diff --git a/backtesting.go b/backtesting.go index e7798bf..13688f2 100644 --- a/backtesting.go +++ b/backtesting.go @@ -9,6 +9,7 @@ import ( "time" "github.com/go-echarts/go-echarts/v2/charts" + "github.com/go-echarts/go-echarts/v2/components" "github.com/go-echarts/go-echarts/v2/opts" "golang.org/x/exp/rand" ) @@ -23,29 +24,33 @@ func Backtest(trader *Trader) { switch broker := trader.Broker.(type) { case *TestBroker: trader.Init() // Initialize the trader and strategy. + start := time.Now() for !trader.EOF { trader.Tick() // Allow the trader to process the current candlesticks. broker.Advance() // Give the trader access to the next candlestick. } - log.Println("Backtest complete.") - log.Println("Stats:") - log.Println(trader.Stats().String()) + log.Println("Backtest complete. Opening report...") + page := components.NewPage() + + // Create a new line chart based on account equity and add it to the page. chart := charts.NewLine() chart.SetGlobalOptions(charts.WithTitleOpts(opts.Title{ Title: fmt.Sprintf("Backtest (%s)", time.Now().Format(time.DateTime)), - Subtitle: fmt.Sprintf("%s %s %T", trader.Symbol, trader.Frequency, trader.Strategy), + Subtitle: fmt.Sprintf("%s %s %T (took %.2f seconds)", trader.Symbol, trader.Frequency, trader.Strategy, time.Since(start).Seconds()), })) chart.SetXAxis(seriesStringArray(trader.Stats().Dates())). AddSeries("Equity", lineDataFromSeries(trader.Stats().Series("Equity"))). AddSeries("Drawdown", lineDataFromSeries(trader.Stats().Series("Drawdown"))) - // Draw the chart to a file. + page.AddCharts(chart) + + // Draw the page to a file. f, err := os.Create("backtest.html") if err != nil { panic(err) } - chart.Render(f) + page.Render(f) f.Close() // Open the chart in the default browser. diff --git a/cmd/sma_crossover.go b/cmd/sma_crossover.go index 75e4a4b..bf2bf2b 100644 --- a/cmd/sma_crossover.go +++ b/cmd/sma_crossover.go @@ -1,8 +1,6 @@ package main import ( - "log" - auto "github.com/fivemoreminix/autotrader" ) @@ -16,7 +14,6 @@ func (s *SMAStrategy) Init(_ *auto.Trader) { func (s *SMAStrategy) Next(t *auto.Trader) { sma1 := t.Data().Closes().Rolling(s.period1).Mean() sma2 := t.Data().Closes().Rolling(s.period2).Mean() - log.Println(t.Data().Close(-1) - sma1.Float(-1)) // If the shorter SMA crosses above the longer SMA, buy. if crossover(sma1, sma2) { t.Buy(1000) diff --git a/trader.go b/trader.go index 6c4053e..d13aad0 100644 --- a/trader.go +++ b/trader.go @@ -99,7 +99,7 @@ func (t *Trader) Tick() { "Drawdown": func() float64 { var bal float64 if t.stats.Len() > 0 { - bal = t.stats.Value("Equity", 0).(float64) // Take starting balance + bal = t.stats.Float("Equity", 0) // Take starting balance } else { bal = t.Broker.NAV() }