mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
Merge pull request #1820 from c9s/c9s/record-net-profit
FEATURE: add new migration script to record the net profit values
This commit is contained in:
commit
8e326d9cc0
13
doc/topics/profile.md
Normal file
13
doc/topics/profile.md
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Profiling
|
||||||
|
===================
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dotenv -f .env.local -- go run -tags pprof ./cmd/bbgo run \
|
||||||
|
--config ./makemoney-btcusdt.yaml \
|
||||||
|
--cpu-profile makemoney.pprof \
|
||||||
|
--enable-profile-server
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
go tool pprof http://localhost:6060/debug/pprof/heap
|
||||||
|
```
|
17
migrations/mysql/20241115165059_add_net_profit_column.sql
Normal file
17
migrations/mysql/20241115165059_add_net_profit_column.sql
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
-- +up
|
||||||
|
-- +begin
|
||||||
|
ALTER TABLE `positions`
|
||||||
|
ADD COLUMN `net_profit` DECIMAL(16, 8) DEFAULT 0.00000000 NOT NULL
|
||||||
|
;
|
||||||
|
-- +end
|
||||||
|
-- +begin
|
||||||
|
UPDATE positions SET net_profit = profit WHERE net_profit = 0.0;
|
||||||
|
-- +end
|
||||||
|
|
||||||
|
-- +down
|
||||||
|
|
||||||
|
-- +begin
|
||||||
|
ALTER TABLE `positions`
|
||||||
|
DROP COLUMN `net_profit`
|
||||||
|
;
|
||||||
|
-- +end
|
15
migrations/sqlite3/20241115165059_add_net_profit_column.sql
Normal file
15
migrations/sqlite3/20241115165059_add_net_profit_column.sql
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
-- +up
|
||||||
|
-- +begin
|
||||||
|
ALTER TABLE `positions`
|
||||||
|
ADD COLUMN `net_profit` DECIMAL DEFAULT 0.00000000 NOT NULL
|
||||||
|
;
|
||||||
|
-- +end
|
||||||
|
|
||||||
|
|
||||||
|
-- +down
|
||||||
|
|
||||||
|
-- +begin
|
||||||
|
ALTER TABLE `positions`
|
||||||
|
DROP COLUMN `net_profit`
|
||||||
|
;
|
||||||
|
-- +end
|
|
@ -587,7 +587,7 @@ func (environ *Environment) RecordPosition(position *types.Position, trade types
|
||||||
|
|
||||||
log.Infof("recordPosition: position = %s, trade = %+v, profit = %+v", position.Base.String(), trade, profit)
|
log.Infof("recordPosition: position = %s, trade = %+v, profit = %+v", position.Base.String(), trade, profit)
|
||||||
if profit != nil {
|
if profit != nil {
|
||||||
if err := environ.PositionService.Insert(position, trade, profit.Profit); err != nil {
|
if err := environ.PositionService.Insert(position, trade, profit.Profit, profit.NetProfit); err != nil {
|
||||||
log.WithError(err).Errorf("can not insert position record")
|
log.WithError(err).Errorf("can not insert position record")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,7 +595,7 @@ func (environ *Environment) RecordPosition(position *types.Position, trade types
|
||||||
log.WithError(err).Errorf("can not insert profit record: %+v", profit)
|
log.WithError(err).Errorf("can not insert profit record: %+v", profit)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := environ.PositionService.Insert(position, trade, fixedpoint.Zero); err != nil {
|
if err := environ.PositionService.Insert(position, trade, fixedpoint.Zero, fixedpoint.Zero); err != nil {
|
||||||
log.WithError(err).Errorf("can not insert position record")
|
log.WithError(err).Errorf("can not insert position record")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
pkg/cmd/pprof.go
Normal file
6
pkg/cmd/pprof.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//go:build pprof
|
||||||
|
// +build pprof
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import _ "net/http/pprof"
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
_ "time/tzdata"
|
||||||
|
|
||||||
"github.com/heroku/rollrus"
|
"github.com/heroku/rollrus"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
@ -20,8 +21,6 @@ import (
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/bbgo"
|
"github.com/c9s/bbgo/pkg/bbgo"
|
||||||
"github.com/c9s/bbgo/pkg/util"
|
"github.com/c9s/bbgo/pkg/util"
|
||||||
|
|
||||||
_ "time/tzdata"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cpuProfileFile *os.File
|
var cpuProfileFile *os.File
|
||||||
|
@ -81,6 +80,24 @@ var RootCmd = &cobra.Command{
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableProfileServer, err := cmd.Flags().GetBool("enable-profile-server")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if enableProfileServer {
|
||||||
|
profileServerBind, err := cmd.Flags().GetString("profile-server-bind")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := http.ListenAndServe(profileServerBind, nil); err != nil {
|
||||||
|
log.WithError(err).Errorf("profile server error")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
cpuProfile, err := cmd.Flags().GetString("cpu-profile")
|
cpuProfile, err := cmd.Flags().GetString("cpu-profile")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -195,6 +212,8 @@ func init() {
|
||||||
RootCmd.PersistentFlags().String("max-api-secret", "", "max api secret")
|
RootCmd.PersistentFlags().String("max-api-secret", "", "max api secret")
|
||||||
|
|
||||||
RootCmd.PersistentFlags().String("cpu-profile", "", "cpu profile")
|
RootCmd.PersistentFlags().String("cpu-profile", "", "cpu profile")
|
||||||
|
RootCmd.PersistentFlags().Bool("enable-profile-server", false, "enable profile server binding")
|
||||||
|
RootCmd.PersistentFlags().String("profile-server-bind", "localhost:6060", "profile server binding")
|
||||||
|
|
||||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/c9s/rockhopper/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AddMigration("main", up_main_addNetProfitColumn, down_main_addNetProfitColumn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func up_main_addNetProfitColumn(ctx context.Context, tx rockhopper.SQLExecutor) (err error) {
|
||||||
|
// This code is executed when the migration is applied.
|
||||||
|
_, err = tx.ExecContext(ctx, "ALTER TABLE `positions`\n ADD COLUMN `net_profit` DECIMAL(16, 8) DEFAULT 0.00000000 NOT NULL\n;")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = tx.ExecContext(ctx, "UPDATE positions SET net_profit = profit WHERE net_profit = 0.0;")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func down_main_addNetProfitColumn(ctx context.Context, tx rockhopper.SQLExecutor) (err error) {
|
||||||
|
// This code is executed when the migration is rolled back.
|
||||||
|
_, err = tx.ExecContext(ctx, "ALTER TABLE `positions`\nDROP COLUMN `net_profit`\n;")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package sqlite3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/c9s/rockhopper/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AddMigration("main", up_main_addNetProfitColumn, down_main_addNetProfitColumn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func up_main_addNetProfitColumn(ctx context.Context, tx rockhopper.SQLExecutor) (err error) {
|
||||||
|
// This code is executed when the migration is applied.
|
||||||
|
_, err = tx.ExecContext(ctx, "ALTER TABLE `positions`\n ADD COLUMN `net_profit` DECIMAL DEFAULT 0.00000000 NOT NULL\n;")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func down_main_addNetProfitColumn(ctx context.Context, tx rockhopper.SQLExecutor) (err error) {
|
||||||
|
// This code is executed when the migration is rolled back.
|
||||||
|
_, err = tx.ExecContext(ctx, "ALTER TABLE `positions`\nDROP COLUMN `net_profit`\n;")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
|
@ -51,7 +51,11 @@ func (s *PositionService) scanRows(rows *sqlx.Rows) (positions []types.Position,
|
||||||
return positions, rows.Err()
|
return positions, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PositionService) Insert(position *types.Position, trade types.Trade, profit fixedpoint.Value) error {
|
func (s *PositionService) Insert(
|
||||||
|
position *types.Position,
|
||||||
|
trade types.Trade,
|
||||||
|
profit, netProfit fixedpoint.Value,
|
||||||
|
) error {
|
||||||
_, err := s.DB.NamedExec(`
|
_, err := s.DB.NamedExec(`
|
||||||
INSERT INTO positions (
|
INSERT INTO positions (
|
||||||
strategy,
|
strategy,
|
||||||
|
@ -63,6 +67,7 @@ func (s *PositionService) Insert(position *types.Position, trade types.Trade, pr
|
||||||
base,
|
base,
|
||||||
quote,
|
quote,
|
||||||
profit,
|
profit,
|
||||||
|
net_profit,
|
||||||
trade_id,
|
trade_id,
|
||||||
exchange,
|
exchange,
|
||||||
side,
|
side,
|
||||||
|
@ -77,6 +82,7 @@ func (s *PositionService) Insert(position *types.Position, trade types.Trade, pr
|
||||||
:base,
|
:base,
|
||||||
:quote,
|
:quote,
|
||||||
:profit,
|
:profit,
|
||||||
|
:net_profit,
|
||||||
:trade_id,
|
:trade_id,
|
||||||
:exchange,
|
:exchange,
|
||||||
:side,
|
:side,
|
||||||
|
@ -92,6 +98,7 @@ func (s *PositionService) Insert(position *types.Position, trade types.Trade, pr
|
||||||
"base": position.Base,
|
"base": position.Base,
|
||||||
"quote": position.Quote,
|
"quote": position.Quote,
|
||||||
"profit": profit,
|
"profit": profit,
|
||||||
|
"net_profit": netProfit,
|
||||||
"trade_id": trade.ID,
|
"trade_id": trade.ID,
|
||||||
"exchange": trade.Exchange,
|
"exchange": trade.Exchange,
|
||||||
"side": trade.Side,
|
"side": trade.Side,
|
||||||
|
|
|
@ -34,7 +34,7 @@ func TestPositionService(t *testing.T) {
|
||||||
ChangedAt: time.Now(),
|
ChangedAt: time.Now(),
|
||||||
}, types.Trade{
|
}, types.Trade{
|
||||||
Time: types.Time(time.Now()),
|
Time: types.Time(time.Now()),
|
||||||
}, fixedpoint.Zero)
|
}, fixedpoint.Zero, fixedpoint.Zero)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ func TestPositionService(t *testing.T) {
|
||||||
Exchange: types.ExchangeBinance,
|
Exchange: types.ExchangeBinance,
|
||||||
Side: types.SideTypeSell,
|
Side: types.SideTypeSell,
|
||||||
Time: types.Time(time.Now()),
|
Time: types.Time(time.Now()),
|
||||||
}, fixedpoint.NewFromFloat(10.9))
|
}, fixedpoint.NewFromFloat(10.9), fixedpoint.NewFromFloat(8.1))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user