@@ -15,26 +15,30 @@ import (
15
15
type Stream struct {
16
16
types.StandardStream
17
17
config * CsvStreamConfig
18
+ converter ICSVTickConverter
18
19
marketTradeEventCallbacks []func (e []CsvTick )
19
20
kLineEventCallbacks []func (e []types.KLine )
20
21
orderEventCallbacks []func (e []types.Order )
21
22
tradeEventCallbacks []func (e []types.Trade )
22
23
}
23
24
24
25
type CsvStreamConfig struct {
25
- Interval types.Interval
26
- RateLimit time.Duration `json:"csvPath"`
27
- CsvPath string `json:"csvPath"`
28
- Symbol string `json:"symbol"`
29
- BaseCoin string `json:"baseCoin"`
30
- QuoteCoin string `json:"quoteCoin"`
31
- TakerFeeRate fixedpoint.Value `json:"takerFeeRate"`
32
- MakerFeeRate fixedpoint.Value `json:"makerFeeRate"`
26
+ Interval types.Interval `json:"interval"`
27
+ RateLimit time.Duration `json:"rateLimit"`
28
+ StrategyID string `json:"strategyID"`
29
+ CsvPath string `json:"csvPath"`
30
+ Exchange types.ExchangeName `json:"exchange"`
31
+ Symbol string `json:"symbol"`
32
+ BaseCoin string `json:"baseCoin"`
33
+ QuoteCoin string `json:"quoteCoin"`
34
+ TakerFeeRate fixedpoint.Value `json:"takerFeeRate"`
35
+ MakerFeeRate fixedpoint.Value `json:"makerFeeRate"`
33
36
}
34
37
35
38
func NewStream (cfg * CsvStreamConfig ) * Stream {
36
39
stream := & Stream {
37
40
StandardStream : types .NewStandardStream (),
41
+ converter : NewCSVTickConverter (),
38
42
config : cfg ,
39
43
}
40
44
@@ -49,8 +53,6 @@ func NewStream(cfg *CsvStreamConfig) *Stream {
49
53
50
54
func (s * Stream ) Simulate () error {
51
55
var i int
52
- converter := NewCSVTickConverter ()
53
-
54
56
// iterate equity series at csv path and stream
55
57
err := filepath .WalkDir (s .config .CsvPath , func (path string , d fs.DirEntry , err error ) error {
56
58
if err != nil {
@@ -74,23 +76,31 @@ func (s *Stream) Simulate() error {
74
76
return err
75
77
}
76
78
tick .Symbol = s .config .Symbol // not every csv provides symbol information
79
+
77
80
trade , err := tick .toGlobalTrade ()
78
81
if err != nil {
79
82
return err
80
83
}
84
+ trade .Fee = s .config .TakerFeeRate
85
+ trade .FeeCurrency = s .config .QuoteCoin
86
+ if tick .IsBuyerMaker { // if supported by exchange csv format
87
+ trade .Fee = s .config .MakerFeeRate
88
+ }
81
89
s .StandardStream .EmitMarketTrade (* trade )
82
90
83
- kline := converter .LatestKLine ()
84
- closesKline := converter .CsvTickToKLine (tick , s .config .Interval )
91
+ kline := s . converter .LatestKLine ()
92
+ closesKline := s . converter .CsvTickToKLine (tick , s .config .Interval )
85
93
if closesKline {
86
94
s .StandardStream .EmitKLineClosed (* kline )
87
95
} else {
88
- kline = converter .LatestKLine ()
96
+ kline = s . converter .LatestKLine () // overwrite with newer KLine
89
97
s .StandardStream .EmitKLine (* kline )
90
98
}
99
+
91
100
// allow for execution time of indicators and strategy
92
- time .Sleep (s .config .RateLimit ) // Max execution time for tradingview strategy
101
+ time .Sleep (s .config .RateLimit ) // Max execution time for tradingview strategy is 250ms
93
102
// to optimize exec time consider callback channel once a strategy has finished running another tick is emitted
103
+
94
104
return nil
95
105
})
96
106
if err != nil {
0 commit comments