package main import ( "github.com/thrasher-corp/gocryptotrader/backtester/data" "github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/portfolio" "github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/strategies" "github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/strategies/base" "github.com/thrasher-corp/gocryptotrader/backtester/eventtypes/signal" "github.com/thrasher-corp/gocryptotrader/backtester/funding" gctorder "github.com/thrasher-corp/gocryptotrader/exchanges/order" ) func main() { // required for plugin system } // CustomStrategy the type used to define custom strategy functions type CustomStrategy struct { base.Strategy } // GetStrategies is required to load the strategy or strategies into the GoCryptoTrader Backtester func GetStrategies() []strategies.Handler { return []strategies.Handler{&CustomStrategy{}} } // Name returns the name of the strategy func (s *CustomStrategy) Name() string { return "custom-strategy" } // Description describes the strategy func (s *CustomStrategy) Description() string { return "this is a demonstration of loading strategies via custom plugins" } // SupportsSimultaneousProcessing this strategy only supports simultaneous signal processing func (s *CustomStrategy) SupportsSimultaneousProcessing() bool { return true } // OnSignal handles a data event and returns what action the strategy believes should occur func (s *CustomStrategy) OnSignal(d data.Handler, _ funding.IFundingTransferer, _ portfolio.Handler) (signal.Event, error) { return s.createSignal(d) } // OnSimultaneousSignals analyses multiple data points simultaneously, allowing flexibility // in allowing a strategy to only place an order for X currency if Y currency's price is Z func (s *CustomStrategy) OnSimultaneousSignals(d []data.Handler, f funding.IFundingTransferer, p portfolio.Handler) ([]signal.Event, error) { response := make([]signal.Event, len(d)) for i := range d { sig, err := s.createSignal(d[i]) if err != nil { return nil, err } response[i] = sig } return response, nil } func (s *CustomStrategy) createSignal(d data.Handler) (*signal.Signal, error) { es, err := s.GetBaseData(d) if err != nil { return nil, err } sig := &signal.Signal{ Base: es.Base, OpenPrice: es.OpenPrice, HighPrice: es.HighPrice, LowPrice: es.LowPrice, ClosePrice: es.ClosePrice, Volume: es.Volume, BuyLimit: es.BuyLimit, SellLimit: es.SellLimit, Amount: es.Amount, Direction: gctorder.Buy, } sig.AppendReasonf("Signalling purchase of %s", es.Base.Pair()) return sig, nil } // SetCustomSettings can override default settings func (s *CustomStrategy) SetCustomSettings(map[string]interface{}) error { return base.ErrCustomSettingsUnsupported } // SetDefaults sets default values for overridable custom settings func (s *CustomStrategy) SetDefaults() {}