Skip to content

Commit

Permalink
refactor(series): move to individual module
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-brito committed May 21, 2021
1 parent 23b1be0 commit 2879dc5
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 30 deletions.
5 changes: 4 additions & 1 deletion example/backtesting/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,8 @@ func main() {
// Print bot results
bot.Summary()
wallet.Summary()
chart.Start()
err = chart.Start()
if err != nil {
log.Fatal(err)
}
}
36 changes: 18 additions & 18 deletions example/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,34 @@ type MyStrategy struct{}
func (e MyStrategy) Init(settings model.Settings) {}

func (e MyStrategy) Timeframe() string {
return "1d"
return "1h"
}

func (e MyStrategy) WarmupPeriod() int {
return 9
return 21
}

func (e MyStrategy) Indicators(dataframe *model.Dataframe) {
dataframe.Metadata["ema"] = talib.Ema(dataframe.Close, 9)
func (e MyStrategy) Indicators(df *model.Dataframe) {
df.Metadata["ema9"] = talib.Ema(df.Close, 9)
df.Metadata["ema21"] = talib.Ema(df.Close, 21)
}

func (e *MyStrategy) OnCandle(dataframe *model.Dataframe, broker exchange.Broker) {
closePrice := model.Last(dataframe.Close, 0)
log.Info("New Candle = ", dataframe.Pair, dataframe.LastUpdate, closePrice)
func (e *MyStrategy) OnCandle(df *model.Dataframe, broker exchange.Broker) {
closePrice := df.Close.Last(0)
log.Info("New Candle = ", df.Pair, df.LastUpdate, closePrice)

assetPosition, quotePosition, err := broker.Position(dataframe.Pair)
assetPosition, quotePosition, err := broker.Position(df.Pair)
if err != nil {
log.Error(err)
}

if quotePosition > 1000 && // minimum size
assetPosition*closePrice < 10 && // no position
model.Last(dataframe.Metadata["ema"], 0) > model.Last(dataframe.Metadata["ema"], 1) {
size := 1000 / closePrice
_, err := broker.OrderMarket(model.SideTypeBuy, dataframe.Pair, size)
buyAmount := 4000.0
if quotePosition > buyAmount && df.Metadata["ema9"].Crossover(df.Metadata["ema21"]) {
size := buyAmount / closePrice
_, err := broker.OrderMarket(model.SideTypeBuy, df.Pair, size)
if err != nil {
log.WithFields(map[string]interface{}{
"pair": dataframe.Pair,
"pair": df.Pair,
"side": model.SideTypeBuy,
"close": closePrice,
"asset": assetPosition,
Expand All @@ -50,12 +50,12 @@ func (e *MyStrategy) OnCandle(dataframe *model.Dataframe, broker exchange.Broker
}
}

if assetPosition*closePrice > 10 && // minimum size
model.Last(dataframe.Metadata["ema"], 0) < model.Last(dataframe.Metadata["ema"], 1) {
_, err := broker.OrderMarket(model.SideTypeSell, dataframe.Pair, assetPosition)
if assetPosition*closePrice > 10 && // minimum tradable size
df.Metadata["ema9"].Crossunder(df.Metadata["ema21"]) {
_, err := broker.OrderMarket(model.SideTypeSell, df.Pair, assetPosition)
if err != nil {
log.WithFields(map[string]interface{}{
"pair": dataframe.Pair,
"pair": df.Pair,
"side": model.SideTypeSell,
"close": closePrice,
"asset": assetPosition,
Expand Down
14 changes: 8 additions & 6 deletions pkg/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package model
import (
"fmt"
"time"

"github.com/rodrigo-brito/ninjabot/pkg/series"
)

type SideType string
Expand Down Expand Up @@ -43,17 +45,17 @@ type Balance struct {
type Dataframe struct {
Pair string

Close []float64
Open []float64
High []float64
Low []float64
Volume []float64
Close series.Series
Open series.Series
High series.Series
Low series.Series
Volume series.Series

Time []time.Time
LastUpdate time.Time

// Custom user metadata
Metadata map[string][]float64
Metadata map[string]series.Series
}

type Candle struct {
Expand Down
4 changes: 0 additions & 4 deletions pkg/model/series.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import (
"strings"
)

func Last(series []float64, index int) float64 {
return series[len(series)-index-1]
}

func NumDecPlaces(v float64) int64 {
s := strconv.FormatFloat(v, 'f', -1, 64)
i := strings.IndexByte(s, '.')
Expand Down
26 changes: 26 additions & 0 deletions pkg/series/series.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package series

type Series []float64

func (s Series) Values() []float64 {
return s
}

func (s Series) Last(position int) float64 {
return s[len(s)-1-position]
}

func (s Series) LastValues(size int) []float64 {
if l := len(s); l > size {
return s[l-size:]
}
return s
}

func (s Series) Crossover(ref Series) bool {
return s.Last(0) > ref.Last(0) && s.Last(1) <= ref.Last(1)
}

func (s Series) Crossunder(ref Series) bool {
return s.Last(0) <= ref.Last(0) && s.Last(1) > ref.Last(1)
}
25 changes: 25 additions & 0 deletions pkg/series/series_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package series

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestSeries_Last(t *testing.T) {
series := Series([]float64{1, 2, 3, 4, 5})
require.Equal(t, 5.0, series.Last(0))
require.Equal(t, 3.0, series.Last(2))
}

func TestSeries_LastValues(t *testing.T) {
t.Run("with value", func(t *testing.T) {
series := Series([]float64{1, 2, 3, 4, 5})
require.Equal(t, []float64{4, 5}, series.LastValues(2))
})

t.Run("empty", func(t *testing.T) {
series := Series([]float64{})
require.Empty(t, series.LastValues(2))
})
}
3 changes: 2 additions & 1 deletion pkg/strategy/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package strategy
import (
"github.com/rodrigo-brito/ninjabot/pkg/exchange"
"github.com/rodrigo-brito/ninjabot/pkg/model"
"github.com/rodrigo-brito/ninjabot/pkg/series"
)

type Strategy interface {
Expand All @@ -26,7 +27,7 @@ func NewStrategyController(pair string, settings model.Settings, strategy Strate
strategy.Init(settings)
dataframe := &model.Dataframe{
Pair: pair,
Metadata: make(map[string][]float64),
Metadata: make(map[string]series.Series),
}

return &Controller{
Expand Down

0 comments on commit 2879dc5

Please sign in to comment.