This commit is contained in:
chiahung.lin 2024-01-10 14:37:07 +08:00
parent d3bc37f45e
commit 6e661c805a
5 changed files with 44 additions and 27 deletions

View File

@ -22,9 +22,10 @@ exchangeStrategies:
- on: max - on: max
dca2: dca2:
symbol: ETHUSDT symbol: ETHUSDT
short: false
quoteInvestment: "200" quoteInvestment: "200"
maxOrderCount: 5 maxOrderCount: 5
priceDeviation: "0.01" priceDeviation: "0.01"
takeProfitRatio: "0.002" takeProfitRatio: "0.002"
coolDownInterval: 180 coolDownInterval: 180
recoverWhenStart: true
keepOrdersWhenShutdown: true

View File

@ -1,36 +1,37 @@
package types package common
type CommonCallback struct { //go:generate callbackgen -type StatusCallbacks
type StatusCallbacks struct {
readyCallbacks []func() readyCallbacks []func()
closedCallbacks []func() closedCallbacks []func()
errorCallbacks []func(error) errorCallbacks []func(error)
} }
func (c *CommonCallback) OnReady(cb func()) { func (c *StatusCallbacks) OnReady(cb func()) {
c.readyCallbacks = append(c.readyCallbacks, cb) c.readyCallbacks = append(c.readyCallbacks, cb)
} }
func (c *CommonCallback) EmitReady() { func (c *StatusCallbacks) EmitReady() {
for _, cb := range c.readyCallbacks { for _, cb := range c.readyCallbacks {
cb() cb()
} }
} }
func (c *CommonCallback) OnClosed(cb func()) { func (c *StatusCallbacks) OnClosed(cb func()) {
c.closedCallbacks = append(c.closedCallbacks, cb) c.closedCallbacks = append(c.closedCallbacks, cb)
} }
func (c *CommonCallback) EmitClosed() { func (c *StatusCallbacks) EmitClosed() {
for _, cb := range c.closedCallbacks { for _, cb := range c.closedCallbacks {
cb() cb()
} }
} }
func (c *CommonCallback) OnError(cb func(err error)) { func (c *StatusCallbacks) OnError(cb func(err error)) {
c.errorCallbacks = append(c.errorCallbacks, cb) c.errorCallbacks = append(c.errorCallbacks, cb)
} }
func (c *CommonCallback) EmitError(err error) { func (c *StatusCallbacks) EmitError(err error) {
for _, cb := range c.errorCallbacks { for _, cb := range c.errorCallbacks {
cb(err) cb(err)
} }

View File

@ -3,27 +3,11 @@ package dca2
import ( import (
"fmt" "fmt"
"strings" "strings"
"time"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
type PersistenceTTL struct {
ttl time.Duration
}
func (p *PersistenceTTL) SetTTL(ttl time.Duration) {
if ttl.Nanoseconds() <= 0 {
return
}
p.ttl = ttl
}
func (p *PersistenceTTL) Expiration() time.Duration {
return p.ttl
}
type ProfitStats struct { type ProfitStats struct {
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
Market types.Market `json:"market,omitempty"` Market types.Market `json:"market,omitempty"`
@ -37,7 +21,7 @@ type ProfitStats struct {
TotalProfit fixedpoint.Value `json:"totalProfit,omitempty"` TotalProfit fixedpoint.Value `json:"totalProfit,omitempty"`
TotalFee map[string]fixedpoint.Value `json:"totalFee,omitempty"` TotalFee map[string]fixedpoint.Value `json:"totalFee,omitempty"`
PersistenceTTL types.PersistenceTTL
} }
func newProfitStats(market types.Market, quoteInvestment fixedpoint.Value) *ProfitStats { func newProfitStats(market types.Market, quoteInvestment fixedpoint.Value) *ProfitStats {

View File

@ -10,6 +10,7 @@ import (
"github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/strategy/common"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"github.com/c9s/bbgo/pkg/util" "github.com/c9s/bbgo/pkg/util"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@ -69,7 +70,7 @@ type Strategy struct {
state State state State
// callbacks // callbacks
types.CommonCallback common.StatusCallbacks
positionCallbacks []func(*types.Position) positionCallbacks []func(*types.Position)
profitCallbacks []func(*ProfitStats) profitCallbacks []func(*ProfitStats)
} }
@ -297,11 +298,22 @@ func (s *Strategy) CalculateProfitOfCurrentRound(ctx context.Context) error {
// query the trades of this round // query the trades of this round
for _, order := range orders { for _, order := range orders {
if order.OrderID > s.ProfitStats.FromOrderID {
s.ProfitStats.FromOrderID = order.OrderID
}
// skip not this strategy order
if order.GroupID != s.OrderGroupID {
continue
}
if order.ExecutedQuantity.Sign() == 0 { if order.ExecutedQuantity.Sign() == 0 {
// skip no trade orders // skip no trade orders
continue continue
} }
s.logger.Infof("[DCA] calculate profit stats from order: %s", order.String())
trades, err := queryService.QueryOrderTrades(ctx, types.OrderQuery{ trades, err := queryService.QueryOrderTrades(ctx, types.OrderQuery{
Symbol: order.Symbol, Symbol: order.Symbol,
OrderID: strconv.FormatUint(order.OrderID, 10), OrderID: strconv.FormatUint(order.OrderID, 10),
@ -312,6 +324,7 @@ func (s *Strategy) CalculateProfitOfCurrentRound(ctx context.Context) error {
} }
for _, trade := range trades { for _, trade := range trades {
s.logger.Infof("[DCA] calculate profit stats from trade: %s", trade.String())
s.ProfitStats.AddTrade(trade) s.ProfitStats.AddTrade(trade)
} }
} }

View File

@ -0,0 +1,18 @@
package types
import "time"
type PersistenceTTL struct {
ttl time.Duration
}
func (p *PersistenceTTL) SetTTL(ttl time.Duration) {
if ttl.Nanoseconds() <= 0 {
return
}
p.ttl = ttl
}
func (p *PersistenceTTL) Expiration() time.Duration {
return p.ttl
}