@@ -2,6 +2,10 @@ package csvsource
2
2
3
3
import (
4
4
"encoding/csv"
5
+ "fmt"
6
+ "math/big"
7
+ "strconv"
8
+ "strings"
5
9
6
10
"github.com/c9s/bbgo/pkg/fixedpoint"
7
11
"github.com/c9s/bbgo/pkg/types"
@@ -23,14 +27,34 @@ func BinanceCSVTickDecoder(row []string, _ int) (*CsvTick, error) {
23
27
if len (row ) < 7 {
24
28
return nil , ErrNotEnoughColumns
25
29
}
26
- size := fixedpoint .MustNewFromString (row [2 ])
30
+ // example csv row
31
+ // id, price, qty, base_qty, time, is_buyer_maker,
32
+ // 11782578,6.00000000,1.00000000,14974844,14974844,1698623884463,True
33
+ qty := fixedpoint .MustNewFromString (row [2 ])
34
+ baseQty := fixedpoint .MustNewFromString (row [2 ])
27
35
price := fixedpoint .MustNewFromString (row [1 ])
28
- hn := price .Mul (size )
36
+ // isBuyerMaker=false trade will qualify as BUY.
37
+ id , err := strconv .ParseUint (row [0 ], 10 , 64 )
38
+ if err != nil {
39
+ return nil , err
40
+ }
41
+ isBuyerMaker , err := strconv .ParseBool (row [5 ])
42
+ if err != nil {
43
+ return nil , err
44
+ }
45
+ side := types .SideTypeBuy
46
+ if isBuyerMaker {
47
+ side = types .SideTypeSell
48
+ }
29
49
return & CsvTick {
30
- Timestamp : types .MustParseMillisecondTimestamp (row [5 ]),
31
- Size : size ,
32
- Price : price ,
33
- HomeNotional : hn ,
50
+ TradeID : id ,
51
+ Exchange : types .ExchangeBinance ,
52
+ Side : side ,
53
+ Size : qty ,
54
+ Price : price ,
55
+ HomeNotional : price .Mul (qty ),
56
+ ForeignNotional : price .Mul (baseQty ),
57
+ Timestamp : types .MustParseMillisecondTimestamp (row [5 ]),
34
58
}, nil
35
59
}
36
60
@@ -44,6 +68,9 @@ func NewBybitCSVTickReader(csv *csv.Reader) *CSVTickReader {
44
68
45
69
// BybitCSVTickDecoder decodes a CSV record from Bybit into a CsvTick.
46
70
func BybitCSVTickDecoder (row []string , index int ) (* CsvTick , error ) {
71
+ // example csv row
72
+ // timestamp,symbol,side,size,price,tickDirection,trdMatchID,grossValue,homeNotional,foreignNotional
73
+ // 1649054912,FXSUSDT,Buy,0.01,38.32,PlusTick,9c30abaf-80ae-5ebf-9850-58fe7ed4bac8,3.832e+07,0.01,0.3832
47
74
if len (row ) < 9 {
48
75
return nil , ErrNotEnoughColumns
49
76
}
@@ -54,14 +81,33 @@ func BybitCSVTickDecoder(row []string, index int) (*CsvTick, error) {
54
81
if err != nil {
55
82
return nil , ErrInvalidOrderSideFormat
56
83
}
84
+ id , err := uuidStringToUInt (row [6 ])
85
+ if err != nil {
86
+ return nil , ErrInvalidOrderSideFormat
87
+ }
57
88
return & CsvTick {
58
- Timestamp : types . MustParseMillisecondTimestamp ( row [ 0 ]) ,
89
+ TradeID : id ,
59
90
Symbol : row [1 ],
91
+ Exchange : types .ExchangeBybit ,
60
92
Side : side ,
61
- TickDirection : row [5 ],
62
93
Size : fixedpoint .MustNewFromString (row [3 ]),
63
94
Price : fixedpoint .MustNewFromString (row [4 ]),
64
95
HomeNotional : fixedpoint .MustNewFromString (row [8 ]),
65
96
ForeignNotional : fixedpoint .MustNewFromString (row [9 ]),
97
+ TickDirection : row [5 ], // todo does this seem promising to define for other exchanges too?
98
+ Timestamp : types .MustParseMillisecondTimestamp (row [0 ]),
66
99
}, nil
67
100
}
101
+
102
+ func uuidStringToUInt (uuidStr string ) (uint64 , error ) {
103
+ // Remove hyphens from the UUID string
104
+ uuidStr = strings .Replace (uuidStr , "-" , "" , - 1 )
105
+
106
+ // Parse the hexadecimal string into a big integer
107
+ uuidBigInt , success := new (big.Int ).SetString (uuidStr , 16 )
108
+ if ! success {
109
+ return 0 , fmt .Errorf ("Failed to parse UUID as a big integer" )
110
+ }
111
+
112
+ return uuidBigInt .Uint64 (), nil
113
+ }
0 commit comments