Adjust quantity by max amount

This commit is contained in:
なるみ 2021-12-20 23:27:03 +08:00
parent 97f9285449
commit 531805a449
2 changed files with 33 additions and 16 deletions

View File

@ -10,11 +10,13 @@ exchangeStrategies:
interval: 24h interval: 24h
baseCurrency: TWD baseCurrency: TWD
ignoreLocked: true ignoreLocked: true
weights: targetWeights:
BTC: 40% BTC: 40%
ETH: 20% ETH: 20%
MAX: 20% MAX: 20%
USDT: 10% USDT: 10%
TWD: 10% TWD: 10%
threshold: 2% threshold: 2%
# max amount to buy or sell per order
maxAmount: 10_000
verbose: true verbose: true

View File

@ -52,12 +52,15 @@ func ElementwiseProduct(m1, m2 map[string]fixedpoint.Value) map[string]fixedpoin
type Strategy struct { type Strategy struct {
Notifiability *bbgo.Notifiability Notifiability *bbgo.Notifiability
Interval types.Duration `json:"interval"` Interval types.Duration `json:"interval"`
BaseCurrency string `json:"baseCurrency"` BaseCurrency string `json:"baseCurrency"`
Weights map[string]fixedpoint.Value `json:"weights"` TargetWeights map[string]fixedpoint.Value `json:"targetWeights"`
Threshold fixedpoint.Value `json:"threshold"` Threshold fixedpoint.Value `json:"threshold"`
IgnoreLocked bool `json:"ignoreLocked"` IgnoreLocked bool `json:"ignoreLocked"`
Verbose bool `json:"verbose"` Verbose bool `json:"verbose"`
// max amount to buy or sell per order
MaxAmount fixedpoint.Value `json:"maxAmount"`
} }
func (s *Strategy) ID() string { func (s *Strategy) ID() string {
@ -67,7 +70,7 @@ func (s *Strategy) ID() string {
func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {} func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {}
func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
s.Weights = Normalize(s.Weights) s.TargetWeights = Normalize(s.TargetWeights)
go func() { go func() {
ticker := time.NewTicker(util.MillisecondsJitter(s.Interval.Duration(), 1000)) ticker := time.NewTicker(util.MillisecondsJitter(s.Interval.Duration(), 1000))
@ -107,7 +110,7 @@ func (s *Strategy) rebalance(ctx context.Context, orderExecutor bbgo.OrderExecut
func (s *Strategy) getPrices(ctx context.Context, session *bbgo.ExchangeSession) (map[string]fixedpoint.Value, error) { func (s *Strategy) getPrices(ctx context.Context, session *bbgo.ExchangeSession) (map[string]fixedpoint.Value, error) {
prices := make(map[string]fixedpoint.Value) prices := make(map[string]fixedpoint.Value)
for currency := range s.Weights { for currency := range s.TargetWeights {
if currency == s.BaseCurrency { if currency == s.BaseCurrency {
prices[currency] = fixedpoint.NewFromFloat(1.0) prices[currency] = fixedpoint.NewFromFloat(1.0)
continue continue
@ -128,7 +131,7 @@ func (s *Strategy) getPrices(ctx context.Context, session *bbgo.ExchangeSession)
func (s *Strategy) getQuantities(balances types.BalanceMap) map[string]fixedpoint.Value { func (s *Strategy) getQuantities(balances types.BalanceMap) map[string]fixedpoint.Value {
quantities := make(map[string]fixedpoint.Value) quantities := make(map[string]fixedpoint.Value)
for currency := range s.Weights { for currency := range s.TargetWeights {
if s.IgnoreLocked { if s.IgnoreLocked {
quantities[currency] = balances[currency].Total() quantities[currency] = balances[currency].Total()
} else { } else {
@ -146,20 +149,22 @@ func (s *Strategy) generateSubmitOrders(prices, marketValues map[string]fixedpoi
log.Infof("total value: %f", totalValue.Float64()) log.Infof("total value: %f", totalValue.Float64())
for currency, target := range s.Weights { for currency, targetWeight := range s.TargetWeights {
if currency == s.BaseCurrency { if currency == s.BaseCurrency {
continue continue
} }
symbol := currency + s.BaseCurrency symbol := currency + s.BaseCurrency
weight := currentWeights[currency] currentWeight := currentWeights[currency]
price := prices[currency] currentPrice := prices[currency]
diff := target.Sub(weight) // calculate the difference between current weight and target weight
if diff.Abs() < s.Threshold { // if the difference is less than threshold, then we will not create the order
weightDifference := targetWeight.Sub(currentWeight)
if weightDifference.Abs() < s.Threshold {
continue continue
} }
quantity := diff.Mul(totalValue).Div(price) quantity := weightDifference.Mul(totalValue).Div(currentPrice)
side := types.SideTypeBuy side := types.SideTypeBuy
if quantity < 0.0 { if quantity < 0.0 {
@ -167,6 +172,16 @@ func (s *Strategy) generateSubmitOrders(prices, marketValues map[string]fixedpoi
quantity = quantity.Abs() quantity = quantity.Abs()
} }
if s.MaxAmount > 0 {
quantity = bbgo.AdjustQuantityByMaxAmount(quantity, currentPrice, s.MaxAmount)
log.Infof("adjust the quantity %f (%s %s @ %f) by max amount %f",
quantity.Float64(),
symbol,
side.String(),
currentPrice.Float64(),
s.MaxAmount.Float64())
}
order := types.SubmitOrder{ order := types.SubmitOrder{
Symbol: symbol, Symbol: symbol,
Side: side, Side: side,