Skip to content

Commit

Permalink
refactor(storage): improve filters and docs (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-brito authored Oct 16, 2022
1 parent 9d6ff17 commit 0dcd438
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 53 deletions.
5 changes: 3 additions & 2 deletions examples/backtesting/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package main
import (
"context"

log "github.com/sirupsen/logrus"

"github.com/rodrigo-brito/ninjabot"
"github.com/rodrigo-brito/ninjabot/examples/strategies"
"github.com/rodrigo-brito/ninjabot/exchange"
"github.com/rodrigo-brito/ninjabot/plot"
"github.com/rodrigo-brito/ninjabot/plot/indicator"
"github.com/rodrigo-brito/ninjabot/storage"

log "github.com/sirupsen/logrus"
)

func main() {
Expand Down Expand Up @@ -83,6 +83,7 @@ func main() {
// connect bot feed (candle and orders) to the chart
ninjabot.WithCandleSubscription(chart),
ninjabot.WithOrderSubscription(chart),
ninjabot.WithLogLevel(log.WarnLevel),
)
if err != nil {
log.Fatal(err)
Expand Down
63 changes: 32 additions & 31 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,38 +49,39 @@ go run examples/backtesting/main.go
Output:

```
INFO[2021-10-31 18:13] [SETUP] Using paper wallet
INFO[2021-10-31 18:13] [SETUP] Initial Portfolio = 10000.000000 USDT
+---------+--------+-----+------+--------+--------+----------+-----------+
| PAIR | TRADES | WIN | LOSS | % WIN | PAYOFF | PROFIT | VOLUME |
+---------+--------+-----+------+--------+--------+----------+-----------+
| BTCUSDT | 14 | 6 | 8 | 42.9 % | 5.929 | 13511.66 | 448030.05 |
| ETHUSDT | 9 | 6 | 3 | 66.7 % | 3.407 | 21748.41 | 407769.64 |
+---------+--------+-----+------+--------+--------+----------+-----------+
| TOTAL | 23 | 12 | 11 | 52.2 % | 4.942 | 35260.07 | 855799.68 |
+---------+--------+-----+------+--------+--------+----------+-----------+
--------------
WALLET SUMMARY
--------------
0.000000 BTC = 0.000000 USDT
0.000000 ETH = 0.000000 USDT
TRADING VOLUME
BTCUSDT = 448030.05 USDT
ETHUSDT = 407769.64 USDT
45260.073493 USDT
--------------
START PORTFOLIO = 10000.00 USDT
FINAL PORTFOLIO = 45260.07 USDT
GROSS PROFIT = 35260.073493 USDT (352.60%)
MARKET (B&H) = 407.09%
MAX DRAWDOWN = -11.76 %
VOLUME = 855799.68 USDT
COSTS (0.001*V) = 855.80 USDT (ESTIMATION)
--------------
INFO[2022-10-16 16:34] [SETUP] Using paper wallet
INFO[2022-10-16 16:34] [SETUP] Initial Portfolio = 10000.000000 USDT
+---------+--------+-----+------+--------+--------+-----+----------+-----------+
| PAIR | TRADES | WIN | LOSS | % WIN | PAYOFF | SQN | PROFIT | VOLUME |
+---------+--------+-----+------+--------+--------+-----+----------+-----------+
| BTCUSDT | 14 | 6 | 8 | 42.9 % | 5.929 | 1.5 | 13511.66 | 448030.04 |
| ETHUSDT | 9 | 6 | 3 | 66.7 % | 3.407 | 1.3 | 21748.41 | 407769.64 |
+---------+--------+-----+------+--------+--------+-----+----------+-----------+
| TOTAL | 23 | 12 | 11 | 52.2 % | 4.942 | 1.4 | 35260.07 | 855799.68 |
+---------+--------+-----+------+--------+--------+-----+----------+-----------+
-- FINAL WALLET --
0.0000 BTC = 0.0000 USDT
0.0000 ETH = 0.0000 USDT
45260.0734 USDT
----- RETURNS -----
START PORTFOLIO = 10000.00 USDT
FINAL PORTFOLIO = 45260.07 USDT
GROSS PROFIT = 35260.073380 USDT (352.60%)
MARKET CHANGE (B&H) = 407.09%
------ RISK -------
MAX DRAWDOWN = -11.76 %
------ VOLUME -----
ETHUSDT = 407769.64 USDT
BTCUSDT = 448030.04 USDT
TOTAL = 855799.68 USDT
COSTS (0.001*V) = 855.80 USDT (ESTIMATION)
-------------------
Chart available at http://localhost:8080
```

### Plot result:
Expand Down
2 changes: 1 addition & 1 deletion storage/buntdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestFromFile(t *testing.T) {
file, err := os.CreateTemp(os.TempDir(), "*.db")
require.NoError(t, err)
defer func() {
os.Remove(file.Name())
os.RemoveAll(file.Name())
}()
db, err := FromFile(file.Name())
require.NoError(t, err)
Expand Down
39 changes: 22 additions & 17 deletions storage/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@ package storage
import (
"time"

"github.com/rodrigo-brito/ninjabot/model"
"github.com/samber/lo"
"gorm.io/gorm"

"github.com/rodrigo-brito/ninjabot/model"
)

type SQL struct {
db *gorm.DB
}

func FromSQL(dialector gorm.Dialector, opts ...gorm.Option) (Storage, error) {
db, err := gorm.Open(dialector, opts...)
// FromSQL creates a new SQL connections for orders storage. Example of usage:
//
// import "github.com/glebarez/sqlite"
// storage, err := storage.FromSQL(sqlite.Open("sqlite.db"), &gorm.Config{})
// if err != nil {
// log.Fatal(err)
// }
func FromSQL(dialect gorm.Dialector, opts ...gorm.Option) (Storage, error) {
db, err := gorm.Open(dialect, opts...)
if err != nil {
return nil, err
}
Expand All @@ -21,6 +30,7 @@ func FromSQL(dialector gorm.Dialector, opts ...gorm.Option) (Storage, error) {
if err != nil {
return nil, err
}

sqlDB.SetMaxIdleConns(10)
sqlDB.SetMaxOpenConns(100)
sqlDB.SetConnMaxLifetime(time.Hour)
Expand All @@ -35,11 +45,13 @@ func FromSQL(dialector gorm.Dialector, opts ...gorm.Option) (Storage, error) {
}, nil
}

// CreateOrder creates a new order in a SQL database
func (s *SQL) CreateOrder(order *model.Order) error {
result := s.db.Create(order) // pass pointer of data to Create
return result.Error
}

// UpdateOrder updates a given order
func (s *SQL) UpdateOrder(order *model.Order) error {
o := model.Order{ID: order.ID}
s.db.First(&o)
Expand All @@ -48,28 +60,21 @@ func (s *SQL) UpdateOrder(order *model.Order) error {
return result.Error
}

// Orders filter a list of orders given a filter
func (s *SQL) Orders(filters ...OrderFilter) ([]*model.Order, error) {
orders := make([]*model.Order, 0)
var os []model.Order

result := s.db.Find(&os)
result := s.db.Find(&orders)
if result.Error != nil && result.Error != gorm.ErrRecordNotFound {
return orders, nil
}

for i := range os {
isFiltered := true
return lo.Filter(orders, func(order *model.Order, _ int) bool {
for _, filter := range filters {
if ok := filter(os[i]); !ok {
isFiltered = false
break
} else {
isFiltered = true
if !filter(*order) {
return false
}
}
if isFiltered {
orders = append(orders, &os[i])
}
}
return orders, nil
return true
}), nil
}
5 changes: 3 additions & 2 deletions storage/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import (
"os"
"testing"

"gorm.io/gorm"

"github.com/glebarez/sqlite"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)

func TestFromSQL(t *testing.T) {
file, err := os.CreateTemp(os.TempDir(), "*.db")
require.NoError(t, err)
defer func() {
os.Remove(file.Name())
os.RemoveAll(file.Name())
}()

repo, err := FromSQL(sqlite.Open(file.Name()), &gorm.Config{})
Expand Down
1 change: 1 addition & 0 deletions storage/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

func storageUseCase(repo Storage, t *testing.T) {
t.Helper()
now := time.Now()

firstOrder := &model.Order{
Expand Down

0 comments on commit 0dcd438

Please sign in to comment.