5
5
"fmt"
6
6
"os"
7
7
"sync"
8
+ "sync/atomic"
8
9
"time"
9
10
10
11
"github.com/c9s/bbgo/pkg/bbgo"
@@ -14,7 +15,6 @@ import (
14
15
"github.com/c9s/bbgo/pkg/indicator"
15
16
"github.com/c9s/bbgo/pkg/types"
16
17
"github.com/sirupsen/logrus"
17
- "go.uber.org/atomic"
18
18
)
19
19
20
20
const ID = "irr"
@@ -58,26 +58,15 @@ type Strategy struct {
58
58
Nrr * NRR
59
59
Ma * indicator.SMA
60
60
// realtime book ticker to submit order
61
- obBuyPrice * atomic.Float64
62
- obSellPrice * atomic.Float64
63
- // for posting LO
64
- canBuy bool
65
- canSell bool
61
+ obBuyPrice uint64
62
+ obSellPrice uint64
66
63
// for getting close price
67
- currentTradePrice * atomic.Float64
68
- tradePriceSeries * types.Queue
64
+ currentTradePrice uint64
69
65
// for negative return rate
70
66
openPrice float64
71
67
closePrice float64
72
- rtNr * types.Queue
73
- // for moving average reversion
74
- rtMaFast * types.Queue
75
- rtMaSlow * types.Queue
76
- rtMr * types.Queue
77
68
78
- // for final alpha (Nr+Mr)/2
79
- rtWeight * types.Queue
80
- stopC chan struct {}
69
+ stopC chan struct {}
81
70
82
71
// StrategyController
83
72
bbgo.StrategyController
@@ -346,14 +335,6 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
346
335
s .highestPrice = 0
347
336
s .lowestPrice = s .sellPrice
348
337
}
349
-
350
- if trade .Side == types .SideTypeBuy {
351
- s .canSell = true
352
- s .canBuy = false
353
- } else if trade .Side == types .SideTypeSell {
354
- s .canBuy = true
355
- s .canSell = false
356
- }
357
338
})
358
339
359
340
s .InitDrawCommands (& profitSlice , & cumProfitSlice , & cumProfitDollarSlice )
@@ -364,36 +345,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
364
345
s .orderExecutor .Bind ()
365
346
s .activeOrders = bbgo .NewActiveOrderBook (s .Symbol )
366
347
367
- //back-test only, because 1s delayed a lot
368
- //kLineStore, _ := s.session.MarketDataStore(s.Symbol)
369
- //s.Nrr = &NRR{IntervalWindow: types.IntervalWindow{Window: 2, Interval: s.Interval}, RankingWindow: s.Window}
370
- //s.Nrr.BindK(s.session.MarketDataStream, s.Symbol, s.Interval)
371
- //if klines, ok := kLineStore.KLinesOfInterval(s.Nrr.Interval); ok {
372
- // s.Nrr.LoadK((*klines)[0:])
373
- //}
374
- //s.Ma = &indicator.SMA{IntervalWindow: types.IntervalWindow{Window: s.Window, Interval: s.Interval}}
375
- //s.Ma.BindK(s.session.MarketDataStream, s.Symbol, s.Interval)
376
- //if klines, ok := kLineStore.KLinesOfInterval(s.Ma.Interval); ok {
377
- // s.Ma.LoadK((*klines)[0:])
378
- //}
379
-
380
- s .rtNr = types .NewQueue (s .Window )
381
-
382
- s .rtMaFast = types .NewQueue (1 )
383
- s .rtMaSlow = types .NewQueue (5 )
384
- s .rtMr = types .NewQueue (s .Window )
385
-
386
- s .rtWeight = types .NewQueue (s .Window )
387
-
388
- s .currentTradePrice = atomic .NewFloat64 (0. )
389
- s .tradePriceSeries = types .NewQueue (2 )
390
-
391
- // adverse selection based on order flow dynamics
392
- s .canBuy = true
393
- s .canSell = true
394
-
395
- s .closePrice = 0. // atomic.NewFloat64(0)
396
- s .openPrice = 0. //atomic.NewFloat64(0)
348
+ atomic .SwapUint64 (& s .currentTradePrice , 0. )
349
+ s .closePrice = 0.
350
+ s .openPrice = 0.
397
351
klinDirections := types .NewQueue (100 )
398
352
started := false
399
353
boxOpenPrice := 0.
@@ -404,40 +358,43 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
404
358
405
359
s .session .MarketDataStream .OnBookTickerUpdate (func (bt types.BookTicker ) {
406
360
// quote order book price
407
- s .obBuyPrice = atomic .NewFloat64 (bt .Buy .Float64 ())
408
- s .obSellPrice = atomic .NewFloat64 (bt .Sell .Float64 ())
361
+ newBid := uint64 (bt .Buy .Float64 ())
362
+ newAsk := uint64 (bt .Sell .Float64 ())
363
+ atomic .SwapUint64 (& s .obBuyPrice , newBid )
364
+ atomic .SwapUint64 (& s .obSellPrice , newAsk )
409
365
})
410
366
411
367
s .session .MarketDataStream .OnAggTrade (func (trade types.Trade ) {
412
- s .currentTradePrice = atomic .NewFloat64 (trade .Price .Float64 ())
368
+ tradePrice := uint64 (trade .Price .Float64 ())
369
+ atomic .SwapUint64 (& s .currentTradePrice , tradePrice )
413
370
})
414
371
372
+ closeTime := <- time .After (time .Duration (s .Interval - int (time .Now ().UnixMilli ())% s .Interval ) * time .Millisecond )
373
+ log .Infof ("kline close timing synced @ %s" , closeTime .Format ("2006-01-02 15:04:05.000000" ))
415
374
go func () {
416
- time .Sleep (time .Duration (s .Interval - int (time .Now ().UnixMilli ())% s .Interval ) * time .Millisecond )
417
-
418
375
intervalCloseTicker := time .NewTicker (time .Duration (s .Interval ) * time .Millisecond )
419
376
defer intervalCloseTicker .Stop ()
420
-
421
377
for {
422
378
select {
423
379
case <- intervalCloseTicker .C :
380
+ log .Infof ("kline close time @ %s" , time .Now ().Format ("2006-01-02 15:04:05.000000" ))
424
381
425
382
s .orderExecutor .CancelNoWait (context .Background ())
426
383
427
- if s .currentTradePrice . Load () > 0 {
428
- s .closePrice = s .currentTradePrice . Load ( )
429
- log .Infof ("Close Price: %f" , s .closePrice )
384
+ if s .currentTradePrice > 0 {
385
+ s .closePrice = float64 ( s .currentTradePrice )
386
+ log .Infof ("Close Price: %f" , float64 ( s .closePrice ) )
430
387
if s .closePrice > 0 && s .openPrice > 0 {
431
388
direction := s .closePrice - s .openPrice
432
- klinDirections .Update (direction )
389
+ klinDirections .Update (float64 ( direction ) )
433
390
regimeShift := klinDirections .Index (0 )* klinDirections .Index (1 ) < 0
434
391
if regimeShift && ! started {
435
- boxOpenPrice = s .openPrice
392
+ boxOpenPrice = float64 ( s .openPrice )
436
393
started = true
437
394
boxCounter = 0
438
395
log .Infof ("box started at price: %f" , boxOpenPrice )
439
396
} else if regimeShift && started {
440
- boxClosePrice = s .openPrice
397
+ boxClosePrice = float64 ( s .openPrice )
441
398
started = false
442
399
log .Infof ("box ended at price: %f with time length: %d" , boxClosePrice , boxCounter )
443
400
// box ending, should re-balance position
@@ -451,7 +408,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
451
408
Side : types .SideTypeSell ,
452
409
Quantity : s .Quantity ,
453
410
Type : types .OrderTypeLimitMaker ,
454
- Price : fixedpoint .NewFromFloat (s .obSellPrice . Load ( )),
411
+ Price : fixedpoint .NewFromFloat (float64 ( s .obSellPrice )),
455
412
Tag : "irr re-balance: sell" ,
456
413
})
457
414
if err != nil {
@@ -463,7 +420,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
463
420
Side : types .SideTypeBuy ,
464
421
Quantity : s .Quantity ,
465
422
Type : types .OrderTypeLimitMaker ,
466
- Price : fixedpoint .NewFromFloat (s .obBuyPrice . Load ( )),
423
+ Price : fixedpoint .NewFromFloat (float64 ( s .obBuyPrice )),
467
424
Tag : "irr re-balance: buy" ,
468
425
})
469
426
if err != nil {
@@ -484,18 +441,22 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
484
441
return
485
442
}
486
443
}
444
+
487
445
}()
488
446
447
+ openTime := <- time .After (time .Duration (s .Interval - int (time .Now ().UnixMilli ())% s .Interval ) * time .Millisecond )
448
+ log .Infof ("kline open timing synced @ %s" , openTime .Format ("2006-01-02 15:04:05.000000" ))
489
449
go func () {
490
- time .Sleep (time .Duration (s .Interval - int (time .Now ().UnixMilli ())% s .Interval ) * time .Millisecond )
491
450
intervalOpenTicker := time .NewTicker (time .Duration (s .Interval ) * time .Millisecond )
492
451
defer intervalOpenTicker .Stop ()
493
452
for {
494
453
select {
495
454
case <- intervalOpenTicker .C :
496
455
time .Sleep (time .Duration (s .Interval / 10 ) * time .Millisecond )
497
- if s .currentTradePrice .Load () > 0 && s .closePrice > 0 {
498
- s .openPrice = s .currentTradePrice .Load ()
456
+ log .Infof ("kline open time @ %s" , time .Now ().Format ("2006-01-02 15:04:05.000000" ))
457
+
458
+ if s .currentTradePrice > 0 && s .closePrice > 0 {
459
+ s .openPrice = float64 (s .currentTradePrice )
499
460
log .Infof ("Open Price: %f" , s .openPrice )
500
461
}
501
462
case <- s .stopC :
@@ -527,7 +488,6 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
527
488
_ , _ = fmt .Fprintln (os .Stderr , s .TradeStats .String ())
528
489
_ = s .orderExecutor .GracefulCancel (ctx )
529
490
})
530
-
531
491
return nil
532
492
}
533
493
0 commit comments