Skip to content

Commit 646d2da

Browse files
committed
strategy:irr: redesign to maker strategy
1 parent dd1d372 commit 646d2da

File tree

3 files changed

+46
-62
lines changed

3 files changed

+46
-62
lines changed

config/irr.yaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ exchangeStrategies:
1717
symbol: BTCBUSD
1818
# in milliseconds(ms)
1919
hftInterval: 5
20-
# maxima position in USD
21-
amount: 500.0
20+
# indicator window
21+
window: 100
22+
# limit maker order quantity
23+
quantity: 0.01
24+
# bonus spread in USD
25+
spread: 0.25
2226
# alpha1: negative return reversion
2327
NR: true
2428
# alpha2: moving average reversion

pkg/strategy/irr/draw.go

+18-24
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,38 @@ func (s *Strategy) InitDrawCommands(profit, cumProfit, cumProfitDollar types.Ser
1616

1717
canvas := DrawPNL(s.InstanceID(), profit)
1818
var buffer bytes.Buffer
19-
go func() {
20-
if err := canvas.Render(chart.PNG, &buffer); err != nil {
21-
log.WithError(err).Errorf("cannot render return in irr")
22-
reply.Message(fmt.Sprintf("[error] cannot render return in irr: %v", err))
23-
return
24-
}
25-
bbgo.SendPhoto(&buffer)
19+
if err := canvas.Render(chart.PNG, &buffer); err != nil {
20+
log.WithError(err).Errorf("cannot render return in irr")
21+
reply.Message(fmt.Sprintf("[error] cannot render return in irr: %v", err))
2622
return
27-
}()
23+
}
24+
bbgo.SendPhoto(&buffer)
25+
return
2826
})
2927
bbgo.RegisterCommand("/nav", "Draw Net Assets Value", func(reply interact.Reply) {
3028

3129
canvas := DrawCumPNL(s.InstanceID(), cumProfit)
3230
var buffer bytes.Buffer
33-
go func() {
34-
if err := canvas.Render(chart.PNG, &buffer); err != nil {
35-
log.WithError(err).Errorf("cannot render nav in irr")
36-
reply.Message(fmt.Sprintf("[error] canot render nav in irr: %v", err))
37-
return
38-
}
39-
bbgo.SendPhoto(&buffer)
31+
if err := canvas.Render(chart.PNG, &buffer); err != nil {
32+
log.WithError(err).Errorf("cannot render nav in irr")
33+
reply.Message(fmt.Sprintf("[error] canot render nav in irr: %v", err))
4034
return
41-
}()
35+
}
36+
bbgo.SendPhoto(&buffer)
37+
return
4238

4339
})
4440
bbgo.RegisterCommand("/pnl", "Draw Cumulative Profit & Loss", func(reply interact.Reply) {
4541

4642
canvas := DrawCumPNL(s.InstanceID(), cumProfitDollar)
4743
var buffer bytes.Buffer
48-
go func() {
49-
if err := canvas.Render(chart.PNG, &buffer); err != nil {
50-
log.WithError(err).Errorf("cannot render pnl in irr")
51-
reply.Message(fmt.Sprintf("[error] canot render pnl in irr: %v", err))
52-
return
53-
}
54-
bbgo.SendPhoto(&buffer)
44+
if err := canvas.Render(chart.PNG, &buffer); err != nil {
45+
log.WithError(err).Errorf("cannot render pnl in irr")
46+
reply.Message(fmt.Sprintf("[error] canot render pnl in irr: %v", err))
5547
return
56-
}()
48+
}
49+
bbgo.SendPhoto(&buffer)
50+
return
5751
})
5852
}
5953

pkg/strategy/irr/strategy.go

+22-36
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type Strategy struct {
4949
orderExecutor *bbgo.GeneralOrderExecutor
5050

5151
bbgo.QuantityOrAmount
52+
Spread float64 `json:"spread"`
5253

5354
Interval int `json:"hftInterval"`
5455
NR bool `json:"NR"`
@@ -365,13 +366,13 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
365366
// s.Ma.LoadK((*klines)[0:])
366367
//}
367368

368-
s.rtNr = types.NewQueue(100)
369+
s.rtNr = types.NewQueue(s.Window)
369370

370371
s.rtMaFast = types.NewQueue(1)
371372
s.rtMaSlow = types.NewQueue(5)
372-
s.rtMr = types.NewQueue(100)
373+
s.rtMr = types.NewQueue(s.Window)
373374

374-
s.rtWeight = types.NewQueue(100)
375+
s.rtWeight = types.NewQueue(s.Window)
375376

376377
s.currentTradePrice = atomic.NewFloat64(0)
377378

@@ -395,6 +396,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
395396
select {
396397
case <-intervalCloseTicker.C:
397398
if s.currentTradePrice.Load() > 0 {
399+
s.orderExecutor.CancelNoWait(context.Background())
398400
s.closePrice = s.currentTradePrice.Load()
399401
//log.Infof("Close Price: %f", s.closePrice)
400402
// calculate real-time Negative Return
@@ -424,7 +426,6 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
424426
s.rtWeight.Update(alpha)
425427
log.Infof("Alpha: %f/1.0", s.rtWeight.Last())
426428
s.rebalancePosition(s.obBuyPrice.Load(), s.obSellPrice.Load(), s.rtWeight.Last())
427-
s.orderExecutor.CancelNoWait(context.Background())
428429
}
429430
case <-s.stopC:
430431
log.Warnf("%s goroutine stopped, due to the stop signal", s.Symbol)
@@ -443,7 +444,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
443444
for {
444445
select {
445446
case <-intervalOpenTicker.C:
446-
time.Sleep(200 * time.Microsecond)
447+
time.Sleep(50 * time.Microsecond)
447448
if s.currentTradePrice.Load() > 0 {
448449
s.openPrice = s.currentTradePrice.Load()
449450
//log.Infof("Open Price: %f", s.openPrice)
@@ -487,44 +488,29 @@ func (s *Strategy) CalcAssetValue(price fixedpoint.Value) fixedpoint.Value {
487488
}
488489

489490
func (s *Strategy) rebalancePosition(bestBid, bestAsk float64, w float64) {
490-
// alpha-weighted assets (inventory and capital)
491-
position := s.orderExecutor.Position()
492-
p := fixedpoint.NewFromFloat((bestBid + bestAsk) / 2)
493-
494-
targetBase := s.QuantityOrAmount.CalculateQuantity(p).Mul(fixedpoint.NewFromFloat(w))
495-
496-
// to buy/sell quantity
497-
diffQty := targetBase.Sub(position.Base)
498-
log.Infof("Target Position Diff: %f", diffQty.Float64())
499-
500-
// ignore small changes
501-
if diffQty.Abs().Float64() < 0.0005 {
502-
return
503-
}
504-
505-
if diffQty.Sign() > 0 {
506-
_, err := s.orderExecutor.SubmitOrders(context.Background(), types.SubmitOrder{
491+
if w < 0.5 {
492+
_, errB := s.orderExecutor.SubmitOrders(context.Background(), types.SubmitOrder{
507493
Symbol: s.Symbol,
508494
Side: types.SideTypeBuy,
509-
Quantity: diffQty.Abs(),
510-
Type: types.OrderTypeLimit,
511-
Price: fixedpoint.NewFromFloat(bestBid),
512-
Tag: "irr re-balance: buy",
495+
Quantity: s.Quantity,
496+
Type: types.OrderTypeLimitMaker,
497+
Price: fixedpoint.NewFromFloat(bestBid - s.Spread),
498+
Tag: "irr short: buy",
513499
})
514-
if err != nil {
515-
log.WithError(err)
500+
if errB != nil {
501+
log.WithError(errB)
516502
}
517-
} else if diffQty.Sign() < 0 {
518-
_, err := s.orderExecutor.SubmitOrders(context.Background(), types.SubmitOrder{
503+
} else if w > 0.5 {
504+
_, errA := s.orderExecutor.SubmitOrders(context.Background(), types.SubmitOrder{
519505
Symbol: s.Symbol,
520506
Side: types.SideTypeSell,
521-
Quantity: diffQty.Abs(),
522-
Type: types.OrderTypeLimit,
523-
Price: fixedpoint.NewFromFloat(bestAsk),
524-
Tag: "irr re-balance: sell",
507+
Quantity: s.Quantity,
508+
Type: types.OrderTypeLimitMaker,
509+
Price: fixedpoint.NewFromFloat(bestAsk + s.Spread),
510+
Tag: "irr long: buy",
525511
})
526-
if err != nil {
527-
log.WithError(err)
512+
if errA != nil {
513+
log.WithError(errA)
528514
}
529515
}
530516
}

0 commit comments

Comments
 (0)