mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 17:13:51 +00:00
Merge pull request #141 from c9s/ftx/on-orderbook-snapshot
This commit is contained in:
commit
009dafd176
|
@ -5,13 +5,14 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/cmd/cmdutil"
|
"github.com/c9s/bbgo/pkg/cmd/cmdutil"
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// go run ./cmd/bbgo orderbook --session=ftx --symbol=btc/usdt
|
// go run ./cmd/bbgo orderbook --session=ftx --symbol=BTC/USDT
|
||||||
var orderbookCmd = &cobra.Command{
|
var orderbookCmd = &cobra.Command{
|
||||||
Use: "orderbook",
|
Use: "orderbook",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
@ -29,13 +30,19 @@ var orderbookCmd = &cobra.Command{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't get the symbol from flags: %w", err)
|
return fmt.Errorf("can't get the symbol from flags: %w", err)
|
||||||
}
|
}
|
||||||
|
if symbol == "" {
|
||||||
|
return fmt.Errorf("symbol is not found")
|
||||||
|
}
|
||||||
|
|
||||||
s := ex.NewStream()
|
s := ex.NewStream()
|
||||||
s.Subscribe(types.BookChannel, symbol, types.SubscribeOptions{})
|
s.Subscribe(types.BookChannel, symbol, types.SubscribeOptions{})
|
||||||
|
s.OnBookSnapshot(func(book types.OrderBook) {
|
||||||
|
log.Infof("orderbook snapshot: %+v", book)
|
||||||
|
})
|
||||||
|
|
||||||
if err := s.Connect(ctx); err != nil {
|
if err := s.Connect(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to connect to %s", session)
|
return fmt.Errorf("failed to connect to %s", session)
|
||||||
}
|
}
|
||||||
// TODO: register callbacks to print orderbook and updates
|
|
||||||
|
|
||||||
cmdutil.WaitForSignal(ctx, syscall.SIGINT, syscall.SIGTERM)
|
cmdutil.WaitForSignal(ctx, syscall.SIGINT, syscall.SIGTERM)
|
||||||
return nil
|
return nil
|
||||||
|
|
814
pkg/exchange/ftx/orderbook_snapshot.json
Normal file
814
pkg/exchange/ftx/orderbook_snapshot.json
Normal file
|
@ -0,0 +1,814 @@
|
||||||
|
{
|
||||||
|
"channel": "orderbook",
|
||||||
|
"market": "BTC/USDT",
|
||||||
|
"type": "partial",
|
||||||
|
"data": {
|
||||||
|
"time": 1614520368.9313016,
|
||||||
|
"checksum": 2150525410,
|
||||||
|
"bids": [
|
||||||
|
[
|
||||||
|
44555.0,
|
||||||
|
3.3968
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44554.0,
|
||||||
|
0.0561
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44548.0,
|
||||||
|
0.1683
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44542.0,
|
||||||
|
0.1762
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44540.0,
|
||||||
|
0.0433
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44539.0,
|
||||||
|
4.1616
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44534.0,
|
||||||
|
0.0234
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44533.0,
|
||||||
|
33.1201
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44532.0,
|
||||||
|
8.2272
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44531.0,
|
||||||
|
0.3364
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44530.0,
|
||||||
|
0.0011
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44527.0,
|
||||||
|
0.0074
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44526.0,
|
||||||
|
0.0117
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44525.0,
|
||||||
|
0.4514
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44520.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44518.0,
|
||||||
|
0.1054
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44517.0,
|
||||||
|
0.0077
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44512.0,
|
||||||
|
0.8512
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44511.0,
|
||||||
|
31.8569
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44510.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44507.0,
|
||||||
|
0.0234
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44506.0,
|
||||||
|
0.382
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44505.0,
|
||||||
|
0.0468
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44501.0,
|
||||||
|
0.0082
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44500.0,
|
||||||
|
0.501
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44498.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44496.0,
|
||||||
|
0.0269
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44490.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44480.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44479.0,
|
||||||
|
0.0306
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44478.0,
|
||||||
|
0.01
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44477.0,
|
||||||
|
0.302
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44470.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44469.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44460.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44454.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44450.0,
|
||||||
|
0.0019
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44448.0,
|
||||||
|
0.0005
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44440.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44439.0,
|
||||||
|
28.9321
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44430.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44420.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44416.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44411.0,
|
||||||
|
0.0984
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44410.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44409.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44408.0,
|
||||||
|
0.0004
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44407.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44400.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44397.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44391.0,
|
||||||
|
0.0004
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44390.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44389.0,
|
||||||
|
43.3904
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44380.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44376.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44375.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44372.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44370.0,
|
||||||
|
0.0012
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44365.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44363.0,
|
||||||
|
0.0004
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44360.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44354.0,
|
||||||
|
54.0385
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44350.0,
|
||||||
|
0.0028
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44346.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44340.0,
|
||||||
|
0.0013
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44338.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44336.0,
|
||||||
|
39.6518
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44333.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44330.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44329.0,
|
||||||
|
0.5014
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44326.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44322.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44321.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44320.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44314.0,
|
||||||
|
0.0007
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44310.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44306.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44300.0,
|
||||||
|
33.2836
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44292.0,
|
||||||
|
0.0035
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44291.0,
|
||||||
|
0.0004
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44290.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44287.0,
|
||||||
|
39.717
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44285.0,
|
||||||
|
0.0439
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44281.0,
|
||||||
|
1.0294
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44280.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44277.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44275.0,
|
||||||
|
0.0165
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44270.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44268.0,
|
||||||
|
48.31
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44260.0,
|
||||||
|
0.0011
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44254.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44250.0,
|
||||||
|
0.0031
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44246.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44244.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44241.0,
|
||||||
|
0.0009
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44240.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44233.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44230.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44224.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44222.0,
|
||||||
|
0.0002
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"asks": [
|
||||||
|
[
|
||||||
|
44574.0,
|
||||||
|
0.4591
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44579.0,
|
||||||
|
0.15
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44582.0,
|
||||||
|
2.9122
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44583.0,
|
||||||
|
0.1683
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44584.0,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44588.0,
|
||||||
|
0.0433
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44590.0,
|
||||||
|
8.6379
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44593.0,
|
||||||
|
0.405
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44595.0,
|
||||||
|
0.5988
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44596.0,
|
||||||
|
0.06
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44605.0,
|
||||||
|
0.6927
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44606.0,
|
||||||
|
0.3365
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44616.0,
|
||||||
|
0.1752
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44617.0,
|
||||||
|
0.0215
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44620.0,
|
||||||
|
0.008
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44629.0,
|
||||||
|
0.0078
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44630.0,
|
||||||
|
0.101
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44631.0,
|
||||||
|
0.246
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44632.0,
|
||||||
|
0.01
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44635.0,
|
||||||
|
0.2997
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44636.0,
|
||||||
|
26.777
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44639.0,
|
||||||
|
0.662
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44642.0,
|
||||||
|
0.0078
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44650.0,
|
||||||
|
0.0009
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44651.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44652.0,
|
||||||
|
0.0079
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44653.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44654.0,
|
||||||
|
0.354
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44661.0,
|
||||||
|
0.0306
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44666.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44667.0,
|
||||||
|
0.0009
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44668.0,
|
||||||
|
0.0234
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44672.0,
|
||||||
|
25.923
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44673.0,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44674.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44675.0,
|
||||||
|
0.0467
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44678.0,
|
||||||
|
0.1286
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44680.0,
|
||||||
|
0.0467
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44684.0,
|
||||||
|
0.0117
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44687.0,
|
||||||
|
0.0351
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44689.0,
|
||||||
|
0.1052
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44693.0,
|
||||||
|
0.0132
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44699.0,
|
||||||
|
0.0984
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44700.0,
|
||||||
|
0.671
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44709.0,
|
||||||
|
0.0007
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44713.0,
|
||||||
|
45.9031
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44714.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44719.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44727.0,
|
||||||
|
0.0004
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44728.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44735.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44744.0,
|
||||||
|
64.7511
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44750.0,
|
||||||
|
0.0018
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44763.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44775.0,
|
||||||
|
0.0006
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44781.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44782.0,
|
||||||
|
34.2206
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44784.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44790.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44796.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44799.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44800.0,
|
||||||
|
0.0011
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44806.0,
|
||||||
|
0.0165
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44807.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44813.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44814.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44816.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44820.0,
|
||||||
|
38.3495
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44822.0,
|
||||||
|
0.0026
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44836.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44846.0,
|
||||||
|
50.1127
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44850.0,
|
||||||
|
0.0018
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44851.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44859.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44867.0,
|
||||||
|
66.5987
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44876.0,
|
||||||
|
1.0294
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44885.0,
|
||||||
|
0.0005
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44888.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44889.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44895.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44897.0,
|
||||||
|
0.0443
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44900.0,
|
||||||
|
40.9965
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44909.0,
|
||||||
|
0.0008
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44913.0,
|
||||||
|
0.0001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44926.0,
|
||||||
|
45.4838
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44928.0,
|
||||||
|
70.5138
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44938.0,
|
||||||
|
0.0005
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44939.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44949.0,
|
||||||
|
0.0004
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44950.0,
|
||||||
|
0.0019
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44959.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44962.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44979.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44982.0,
|
||||||
|
68.1033
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44983.0,
|
||||||
|
0.001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
44999.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
45000.0,
|
||||||
|
0.0273
|
||||||
|
],
|
||||||
|
[
|
||||||
|
45002.0,
|
||||||
|
0.0002
|
||||||
|
],
|
||||||
|
[
|
||||||
|
45009.0,
|
||||||
|
0.0003
|
||||||
|
],
|
||||||
|
[
|
||||||
|
45010.0,
|
||||||
|
0.0003
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"action": "partial"
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Stream struct {
|
type Stream struct {
|
||||||
types.StandardStream
|
*types.StandardStream
|
||||||
|
|
||||||
wsService *WebsocketService
|
wsService *WebsocketService
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ type Stream struct {
|
||||||
func NewStream(key, secret string) *Stream {
|
func NewStream(key, secret string) *Stream {
|
||||||
wss := NewWebsocketService(key, secret)
|
wss := NewWebsocketService(key, secret)
|
||||||
s := &Stream{
|
s := &Stream{
|
||||||
StandardStream: types.StandardStream{},
|
StandardStream: &types.StandardStream{},
|
||||||
wsService: wss,
|
wsService: wss,
|
||||||
}
|
}
|
||||||
|
|
||||||
wss.OnMessage(messageHandler{s.StandardStream}.handleMessage)
|
wss.OnMessage(messageHandler{StandardStream: s.StandardStream}.handleMessage)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,13 @@ package ftx
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type messageHandler struct {
|
type messageHandler struct {
|
||||||
types.StandardStream
|
*types.StandardStream
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h messageHandler) handleMessage(message []byte) {
|
func (h messageHandler) handleMessage(message []byte) {
|
||||||
|
@ -20,6 +22,11 @@ func (h messageHandler) handleMessage(message []byte) {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
case subscribedRespType:
|
case subscribedRespType:
|
||||||
h.handleSubscribedMessage(r)
|
h.handleSubscribedMessage(r)
|
||||||
|
case partialRespType:
|
||||||
|
// snapshot of current market data
|
||||||
|
h.handleSnapshot(r)
|
||||||
|
case updateRespType:
|
||||||
|
//log.Infof("update=> %s", string(message))
|
||||||
default:
|
default:
|
||||||
logger.Errorf("unsupported message type: %+v", r.Type)
|
logger.Errorf("unsupported message type: %+v", r.Type)
|
||||||
}
|
}
|
||||||
|
@ -27,5 +34,15 @@ func (h messageHandler) handleMessage(message []byte) {
|
||||||
|
|
||||||
// {"type": "subscribed", "channel": "orderbook", "market": "BTC/USDT"}
|
// {"type": "subscribed", "channel": "orderbook", "market": "BTC/USDT"}
|
||||||
func (h messageHandler) handleSubscribedMessage(response rawResponse) {
|
func (h messageHandler) handleSubscribedMessage(response rawResponse) {
|
||||||
logger.Infof("%s orderbook is subscribed", response.toSubscribedResp().Market)
|
r := response.toSubscribedResp()
|
||||||
|
logger.Infof("%s %s is subscribed", r.Market, r.Channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h messageHandler) handleSnapshot(response rawResponse) {
|
||||||
|
r, err := response.toSnapshotResp()
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Errorf("failed to convert the partial response to snapshot")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.EmitBookSnapshot(r.toGlobalOrderBook())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
package ftx
|
package ftx
|
||||||
|
|
||||||
import "encoding/json"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
type operation string
|
type operation string
|
||||||
|
|
||||||
|
@ -56,7 +65,74 @@ func (r rawResponse) toSubscribedResp() subscribedResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r rawResponse) toSnapshotResp() (snapshotResponse, error) {
|
||||||
|
o := snapshotResponse{
|
||||||
|
mandatoryFields: r.mandatoryFields,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(r.Data["action"], &o.Action); err != nil {
|
||||||
|
return snapshotResponse{}, fmt.Errorf("failed to unmarshal data.action field: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var t float64
|
||||||
|
if err := json.Unmarshal(r.Data["time"], &t); err != nil {
|
||||||
|
return snapshotResponse{}, fmt.Errorf("failed to unmarshal data.time field: %w", err)
|
||||||
|
}
|
||||||
|
sec, dec := math.Modf(t)
|
||||||
|
o.Time = time.Unix(int64(sec), int64(dec*1e9))
|
||||||
|
|
||||||
|
if err := json.Unmarshal(r.Data["checksum"], &o.Checksum); err != nil {
|
||||||
|
return snapshotResponse{}, fmt.Errorf("failed to unmarshal data.checksum field: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(r.Data["bids"], &o.Bids); err != nil {
|
||||||
|
return snapshotResponse{}, fmt.Errorf("failed to unmarshal data.bids field: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(r.Data["asks"], &o.Asks); err != nil {
|
||||||
|
return snapshotResponse{}, fmt.Errorf("failed to unmarshal data.asks field: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return o, nil
|
||||||
|
}
|
||||||
|
|
||||||
// {"type": "subscribed", "channel": "orderbook", "market": "BTC/USDT"}
|
// {"type": "subscribed", "channel": "orderbook", "market": "BTC/USDT"}
|
||||||
type subscribedResponse struct {
|
type subscribedResponse struct {
|
||||||
mandatoryFields
|
mandatoryFields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type snapshotResponse struct {
|
||||||
|
mandatoryFields
|
||||||
|
|
||||||
|
Action string
|
||||||
|
|
||||||
|
Time time.Time
|
||||||
|
|
||||||
|
Checksum int64
|
||||||
|
|
||||||
|
// Best 100 orders
|
||||||
|
Bids [][]float64
|
||||||
|
|
||||||
|
// Best 100 orders
|
||||||
|
Asks [][]float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r snapshotResponse) toGlobalOrderBook() types.OrderBook {
|
||||||
|
return types.OrderBook{
|
||||||
|
// ex. BTC/USDT
|
||||||
|
Symbol: strings.ToUpper(r.Market),
|
||||||
|
Bids: toPriceVolumeSlice(r.Bids),
|
||||||
|
Asks: toPriceVolumeSlice(r.Asks),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toPriceVolumeSlice(orders [][]float64) types.PriceVolumeSlice {
|
||||||
|
var pv types.PriceVolumeSlice
|
||||||
|
for _, o := range orders {
|
||||||
|
pv = append(pv, types.PriceVolume{
|
||||||
|
Price: fixedpoint.NewFromFloat(o[0]),
|
||||||
|
Volume: fixedpoint.NewFromFloat(o[1]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return pv
|
||||||
|
}
|
||||||
|
|
|
@ -2,9 +2,13 @@ package ftx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_rawResponse_toSubscribedResp(t *testing.T) {
|
func Test_rawResponse_toSubscribedResp(t *testing.T) {
|
||||||
|
@ -16,3 +20,59 @@ func Test_rawResponse_toSubscribedResp(t *testing.T) {
|
||||||
assert.Equal(t, orderbook, r.Channel)
|
assert.Equal(t, orderbook, r.Channel)
|
||||||
assert.Equal(t, "BTC/USDT", r.Market)
|
assert.Equal(t, "BTC/USDT", r.Market)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_rawResponse_toSnapshotResp(t *testing.T) {
|
||||||
|
f, err := ioutil.ReadFile("./orderbook_snapshot.json")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
var m rawResponse
|
||||||
|
assert.NoError(t, json.Unmarshal(f, &m))
|
||||||
|
r, err := m.toSnapshotResp()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, partialRespType, r.Type)
|
||||||
|
assert.Equal(t, orderbook, r.Channel)
|
||||||
|
assert.Equal(t, "BTC/USDT", r.Market)
|
||||||
|
assert.Equal(t, int64(1614520368), r.Time.Unix())
|
||||||
|
assert.Equal(t, int64(2150525410), r.Checksum)
|
||||||
|
assert.Len(t, r.Bids, 100)
|
||||||
|
assert.Equal(t, []float64{44555.0, 3.3968}, r.Bids[0])
|
||||||
|
assert.Equal(t, []float64{44554.0, 0.0561}, r.Bids[1])
|
||||||
|
assert.Len(t, r.Asks, 100)
|
||||||
|
assert.Equal(t, []float64{44574.0, 0.4591}, r.Asks[0])
|
||||||
|
assert.Equal(t, []float64{44579.0, 0.15}, r.Asks[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_snapshotResponse_toGlobalOrderBook(t *testing.T) {
|
||||||
|
f, err := ioutil.ReadFile("./orderbook_snapshot.json")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
var m rawResponse
|
||||||
|
assert.NoError(t, json.Unmarshal(f, &m))
|
||||||
|
r, err := m.toSnapshotResp()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
b := r.toGlobalOrderBook()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "BTC/USDT", b.Symbol)
|
||||||
|
isValid, err := b.IsValid()
|
||||||
|
assert.True(t, isValid)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, b.Bids, 100)
|
||||||
|
assert.Equal(t, types.PriceVolume{
|
||||||
|
Price: fixedpoint.MustNewFromString("44555.0"),
|
||||||
|
Volume: fixedpoint.MustNewFromString("3.3968"),
|
||||||
|
}, b.Bids[0])
|
||||||
|
assert.Equal(t, types.PriceVolume{
|
||||||
|
Price: fixedpoint.MustNewFromString("44222.0"),
|
||||||
|
Volume: fixedpoint.MustNewFromString("0.0002"),
|
||||||
|
}, b.Bids[99])
|
||||||
|
|
||||||
|
assert.Len(t, b.Asks, 100)
|
||||||
|
assert.Equal(t, types.PriceVolume{
|
||||||
|
Price: fixedpoint.MustNewFromString("44574.0"),
|
||||||
|
Volume: fixedpoint.MustNewFromString("0.4591"),
|
||||||
|
}, b.Asks[0])
|
||||||
|
assert.Equal(t, types.PriceVolume{
|
||||||
|
Price: fixedpoint.MustNewFromString("45010.0"),
|
||||||
|
Volume: fixedpoint.MustNewFromString("0.0003"),
|
||||||
|
}, b.Asks[99])
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user