From 2958e64afecb39203309120383da1ef1d1e5689f Mon Sep 17 00:00:00 2001 From: Ryan O'Hara-Reid Date: Mon, 16 Jun 2025 17:09:25 +1000 Subject: [PATCH] orderbook: change `Base` struct name to `Book` (#1914) * orderbook: change Base struct name to Snapshot * linter: fix * Update exchanges/exchange.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/depth.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_types.go Co-authored-by: Gareth Kirwan * Snapshot -> Book * Tranche(s) -> Level(s) * Tranche(s) -> Level(s) * rm tranche ref * linter: fix * linter: rides again * update tests * Update exchange/websocket/buffer/buffer.go Co-authored-by: Gareth Kirwan * Update backtester/eventhandlers/exchange/slippage/slippage.go Co-authored-by: Gareth Kirwan * Update exchange/websocket/buffer/buffer.go Co-authored-by: Adrian Gallagher * Update exchange/websocket/buffer/buffer.go Co-authored-by: Adrian Gallagher * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Adrian Gallagher * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Adrian Gallagher * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Adrian Gallagher * Update exchanges/orderbook/orderbook_types.go Co-authored-by: Adrian Gallagher * Update exchanges/orderbook/orderbook_types.go Co-authored-by: Adrian Gallagher * fixup tests * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_types.go Co-authored-by: Gareth Kirwan * Update exchanges/orderbook/orderbook_types.go Co-authored-by: Gareth Kirwan * gk: nits and rm stuff that is not needed * Update exchanges/orderbook/orderbook_test.go Co-authored-by: Gareth Kirwan * gk: nits --------- Co-authored-by: shazbert Co-authored-by: Gareth Kirwan Co-authored-by: Adrian Gallagher --- .../exchange/slippage/slippage.go | 5 +- cmd/exchange_template/wrapper_file.tmpl | 12 +- cmd/exchange_wrapper_issues/main.go | 4 +- engine/apiserver.go | 2 +- engine/apiserver_types.go | 2 +- engine/rpcserver_test.go | 12 +- engine/subsystem_types.go | 2 +- engine/sync_manager.go | 2 +- engine/sync_manager_test.go | 10 +- engine/websocketroutine_manager_test.go | 2 +- exchange/websocket/buffer/buffer.go | 10 +- exchange/websocket/buffer/buffer_test.go | 94 ++-- exchange/websocket/buffer/buffer_types.go | 4 +- exchanges/alphapoint/alphapoint_wrapper.go | 12 +- exchanges/binance/binance_websocket.go | 22 +- exchanges/binance/binance_wrapper.go | 12 +- exchanges/binanceus/binanceus_websocket.go | 18 +- exchanges/binanceus/binanceus_wrapper.go | 12 +- exchanges/bitfinex/bitfinex_test.go | 10 +- exchanges/bitfinex/bitfinex_websocket.go | 22 +- exchanges/bitfinex/bitfinex_wrapper.go | 20 +- exchanges/bitflyer/bitflyer_wrapper.go | 12 +- exchanges/bithumb/bithumb_websocket_types.go | 4 +- exchanges/bithumb/bithumb_wrapper.go | 12 +- exchanges/bithumb/bithumb_ws_orderbook.go | 20 +- exchanges/bitmex/bitmex_websocket.go | 14 +- exchanges/bitmex/bitmex_wrapper.go | 12 +- exchanges/bitstamp/bitstamp.go | 2 +- exchanges/bitstamp/bitstamp_test.go | 6 +- exchanges/bitstamp/bitstamp_websocket.go | 16 +- exchanges/bitstamp/bitstamp_wrapper.go | 12 +- exchanges/btcmarkets/btcmarkets_test.go | 6 +- exchanges/btcmarkets/btcmarkets_types.go | 2 +- exchanges/btcmarkets/btcmarkets_websocket.go | 16 +- exchanges/btcmarkets/btcmarkets_wrapper.go | 12 +- exchanges/btse/btse_websocket.go | 10 +- exchanges/btse/btse_wrapper.go | 12 +- exchanges/bybit/bybit.go | 4 +- exchanges/bybit/bybit_types.go | 4 +- exchanges/bybit/bybit_websocket.go | 7 +- exchanges/bybit/bybit_wrapper.go | 12 +- .../coinbasepro/coinbasepro_websocket.go | 14 +- exchanges/coinbasepro/coinbasepro_wrapper.go | 12 +- exchanges/coinut/coinut_websocket.go | 14 +- exchanges/coinut/coinut_wrapper.go | 12 +- exchanges/deribit/deribit_websocket.go | 20 +- exchanges/deribit/deribit_wrapper.go | 12 +- exchanges/exchange.go | 4 +- exchanges/exchange_test.go | 6 +- exchanges/exmo/exmo_wrapper.go | 10 +- exchanges/gateio/gateio_types.go | 12 +- exchanges/gateio/gateio_websocket.go | 16 +- exchanges/gateio/gateio_websocket_futures.go | 20 +- exchanges/gateio/gateio_websocket_option.go | 20 +- exchanges/gateio/gateio_wrapper.go | 14 +- exchanges/gateio/ws_ob_update_manager_test.go | 12 +- exchanges/gemini/gemini_websocket.go | 8 +- exchanges/gemini/gemini_wrapper.go | 12 +- exchanges/hitbtc/hitbtc_websocket.go | 18 +- exchanges/hitbtc/hitbtc_wrapper.go | 12 +- exchanges/huobi/huobi_websocket.go | 10 +- exchanges/huobi/huobi_wrapper.go | 28 +- exchanges/interfaces.go | 4 +- exchanges/kraken/kraken_test.go | 8 +- exchanges/kraken/kraken_websocket.go | 20 +- exchanges/kraken/kraken_wrapper.go | 20 +- exchanges/kucoin/kucoin.go | 6 +- exchanges/kucoin/kucoin_futures.go | 6 +- exchanges/kucoin/kucoin_test.go | 2 +- exchanges/kucoin/kucoin_types.go | 22 +- exchanges/kucoin/kucoin_websocket.go | 28 +- exchanges/kucoin/kucoin_wrapper.go | 4 +- exchanges/lbank/lbank_wrapper.go | 8 +- exchanges/okx/okx_test.go | 2 +- exchanges/okx/okx_types.go | 8 +- exchanges/okx/okx_websocket.go | 18 +- exchanges/okx/okx_wrapper.go | 22 +- exchanges/orderbook/calculator.go | 108 +++-- exchanges/orderbook/calculator_test.go | 46 +- exchanges/orderbook/depth.go | 186 ++++---- exchanges/orderbook/depth_test.go | 124 +++--- .../orderbook/{tranches.go => levels.go} | 346 ++++++++------- .../{tranches_test.go => levels_test.go} | 374 ++++++++-------- exchanges/orderbook/orderbook.go | 44 +- exchanges/orderbook/orderbook_test.go | 402 +++++++----------- exchanges/orderbook/orderbook_types.go | 22 +- exchanges/poloniex/poloniex_websocket.go | 14 +- exchanges/poloniex/poloniex_wrapper.go | 14 +- exchanges/sharedtestvalues/customex.go | 2 +- exchanges/yobit/yobit_wrapper.go | 8 +- gctscript/modules/wrapper_types.go | 2 +- gctscript/wrappers/gct/exchange/exchange.go | 2 +- gctscript/wrappers/validator/validator.go | 8 +- 93 files changed, 1259 insertions(+), 1391 deletions(-) rename exchanges/orderbook/{tranches.go => levels.go} (59%) rename exchanges/orderbook/{tranches_test.go => levels_test.go} (79%) diff --git a/backtester/eventhandlers/exchange/slippage/slippage.go b/backtester/eventhandlers/exchange/slippage/slippage.go index 04d394b5..3bdfdeb8 100644 --- a/backtester/eventhandlers/exchange/slippage/slippage.go +++ b/backtester/eventhandlers/exchange/slippage/slippage.go @@ -29,9 +29,8 @@ func EstimateSlippagePercentage(maximumSlippageRate, minimumSlippageRate decimal return decimal.NewFromInt(1) } -// CalculateSlippageByOrderbook will analyse a provided orderbook and return the result of attempting to -// place the order on there -func CalculateSlippageByOrderbook(ob *orderbook.Base, side gctorder.Side, allocatedFunds, feeRate decimal.Decimal) (price, amount decimal.Decimal, err error) { +// CalculateSlippageByOrderbook returns the price slippage for an order +func CalculateSlippageByOrderbook(ob *orderbook.Book, side gctorder.Side, allocatedFunds, feeRate decimal.Decimal) (price, amount decimal.Decimal, err error) { var result *orderbook.WhaleBombResult result, err = ob.SimulateOrder(allocatedFunds.InexactFloat64(), side == gctorder.Buy) if err != nil { diff --git a/cmd/exchange_template/wrapper_file.tmpl b/cmd/exchange_template/wrapper_file.tmpl index c541257b..9b027f6f 100644 --- a/cmd/exchange_template/wrapper_file.tmpl +++ b/cmd/exchange_template/wrapper_file.tmpl @@ -250,8 +250,8 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateTickers(ctx context.Context, assetT } // UpdateOrderbook updates and returns the orderbook for a currency pair -func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Base, error) { - book := &orderbook.Base{ +func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { + book := &orderbook.Book{ Exchange: {{.Variable}}.Name, Pair: pair, Asset: assetType, @@ -265,17 +265,17 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(ctx context.Context, pair return book, err } - book.Bids = make([]orderbook.Tranche, len(orderbookNew.Bids)) + book.Bids = make([]orderbook.Level, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Quantity, Price: orderbookNew.Bids[x].Price, } } - book.Asks = make([]orderbook.Tranche, len(orderbookNew.Asks)) + book.Asks = make([]orderbook.Level, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderBookNew.Asks[x].Quantity, Price: orderBookNew.Asks[x].Price, } diff --git a/cmd/exchange_wrapper_issues/main.go b/cmd/exchange_wrapper_issues/main.go index 803ab406..3c799c59 100644 --- a/cmd/exchange_wrapper_issues/main.go +++ b/cmd/exchange_wrapper_issues/main.go @@ -372,7 +372,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Response: jsonifyInterface([]any{GetCachedTickerResponse}), }) - var updateOrderbookResponse *orderbook.Base + var updateOrderbookResponse *orderbook.Book updateOrderbookResponse, err = e.UpdateOrderbook(context.TODO(), p, assetTypes[i]) msg = "" if err != nil { @@ -386,7 +386,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Response: jsonifyInterface([]any{updateOrderbookResponse}), }) - var GetCachedOrderbookResponse *orderbook.Base + var GetCachedOrderbookResponse *orderbook.Book GetCachedOrderbookResponse, err = e.GetCachedOrderbook(p, assetTypes[i]) msg = "" if err != nil { diff --git a/engine/apiserver.go b/engine/apiserver.go index fa2f47ff..a43cec04 100644 --- a/engine/apiserver.go +++ b/engine/apiserver.go @@ -317,7 +317,7 @@ func getAllActiveOrderbooks(m iExchangeManager) []EnabledExchangeOrderbooks { orderbookData := make([]EnabledExchangeOrderbooks, 0, len(exchanges)) for _, e := range exchanges { - var orderbooks []orderbook.Base + var orderbooks []orderbook.Book for _, a := range e.GetAssetTypes(true) { pairs, err := e.GetEnabledPairs(a) if err != nil { diff --git a/engine/apiserver_types.go b/engine/apiserver_types.go index c5337b93..fb1d0b17 100644 --- a/engine/apiserver_types.go +++ b/engine/apiserver_types.go @@ -129,7 +129,7 @@ type AllEnabledExchangeOrderbooks struct { // orderbooks type EnabledExchangeOrderbooks struct { ExchangeName string `json:"exchangeName"` - ExchangeValues []orderbook.Base `json:"exchangeValues"` + ExchangeValues []orderbook.Book `json:"exchangeValues"` } // AllEnabledExchangeCurrencies holds the enabled exchange currencies diff --git a/engine/rpcserver_test.go b/engine/rpcserver_test.go index c94c096f..a130a0bd 100644 --- a/engine/rpcserver_test.go +++ b/engine/rpcserver_test.go @@ -3138,13 +3138,13 @@ func TestGetOrderbookMovement(t *testing.T) { t.Fatal(err) } - bid := []orderbook.Tranche{ + bid := []orderbook.Level{ {Price: 10, Amount: 1}, {Price: 9, Amount: 1}, {Price: 8, Amount: 1}, {Price: 7, Amount: 1}, } - ask := []orderbook.Tranche{ + ask := []orderbook.Level{ {Price: 11, Amount: 1}, {Price: 12, Amount: 1}, {Price: 13, Amount: 1}, @@ -3239,13 +3239,13 @@ func TestGetOrderbookAmountByNominal(t *testing.T) { t.Fatal(err) } - bid := []orderbook.Tranche{ + bid := []orderbook.Level{ {Price: 10, Amount: 1}, {Price: 9, Amount: 1}, {Price: 8, Amount: 1}, {Price: 7, Amount: 1}, } - ask := []orderbook.Tranche{ + ask := []orderbook.Level{ {Price: 11, Amount: 1}, {Price: 12, Amount: 1}, {Price: 13, Amount: 1}, @@ -3333,13 +3333,13 @@ func TestGetOrderbookAmountByImpact(t *testing.T) { t.Fatal(err) } - bid := []orderbook.Tranche{ + bid := []orderbook.Level{ {Price: 10, Amount: 1}, {Price: 9, Amount: 1}, {Price: 8, Amount: 1}, {Price: 7, Amount: 1}, } - ask := []orderbook.Tranche{ + ask := []orderbook.Level{ {Price: 11, Amount: 1}, {Price: 12, Amount: 1}, {Price: 13, Amount: 1}, diff --git a/engine/subsystem_types.go b/engine/subsystem_types.go index e6433775..0eaf0c0e 100644 --- a/engine/subsystem_types.go +++ b/engine/subsystem_types.go @@ -77,7 +77,7 @@ type iBot interface { type iCurrencyPairSyncer interface { IsRunning() bool PrintTickerSummary(*ticker.Price, string, error) - PrintOrderbookSummary(*orderbook.Base, string, error) + PrintOrderbookSummary(*orderbook.Book, string, error) WebsocketUpdate(string, currency.Pair, asset.Item, syncItemType, error) error } diff --git a/engine/sync_manager.go b/engine/sync_manager.go index ccbd8dda..6eef71ad 100644 --- a/engine/sync_manager.go +++ b/engine/sync_manager.go @@ -815,7 +815,7 @@ const ( ) // PrintOrderbookSummary outputs orderbook results -func (m *SyncManager) PrintOrderbookSummary(result *orderbook.Base, protocol string, err error) { +func (m *SyncManager) PrintOrderbookSummary(result *orderbook.Book, protocol string, err error) { if m == nil || atomic.LoadInt32(&m.started) == 0 { return } diff --git a/engine/sync_manager_test.go b/engine/sync_manager_test.go index 1335ab3d..086abbb5 100644 --- a/engine/sync_manager_test.go +++ b/engine/sync_manager_test.go @@ -176,25 +176,25 @@ func TestPrintOrderbookSummary(t *testing.T) { assert.NoError(t, err) atomic.StoreInt32(&m.started, 1) - m.PrintOrderbookSummary(&orderbook.Base{ + m.PrintOrderbookSummary(&orderbook.Book{ Pair: currency.NewPair(currency.AUD, currency.USD), }, "REST", nil) m.fiatDisplayCurrency = currency.USD - m.PrintOrderbookSummary(&orderbook.Base{ + m.PrintOrderbookSummary(&orderbook.Book{ Pair: currency.NewPair(currency.AUD, currency.USD), }, "REST", nil) m.fiatDisplayCurrency = currency.JPY - m.PrintOrderbookSummary(&orderbook.Base{ + m.PrintOrderbookSummary(&orderbook.Book{ Pair: currency.NewPair(currency.AUD, currency.USD), }, "REST", nil) - m.PrintOrderbookSummary(&orderbook.Base{ + m.PrintOrderbookSummary(&orderbook.Book{ Pair: currency.NewPair(currency.AUD, currency.USD), }, "REST", common.ErrNotYetImplemented) - m.PrintOrderbookSummary(&orderbook.Base{ + m.PrintOrderbookSummary(&orderbook.Book{ Pair: currency.NewPair(currency.AUD, currency.USD), }, "REST", errors.New("test")) diff --git a/engine/websocketroutine_manager_test.go b/engine/websocketroutine_manager_test.go index 6a8c7fa8..6b000927 100644 --- a/engine/websocketroutine_manager_test.go +++ b/engine/websocketroutine_manager_test.go @@ -214,7 +214,7 @@ func TestWebsocketRoutineManagerHandleData(t *testing.T) { } assert.ErrorIs(t, err, classificationError.Err) - err = m.websocketDataHandler(exchName, &orderbook.Base{ + err = m.websocketDataHandler(exchName, &orderbook.Book{ Exchange: "Bitstamp", Pair: currency.NewBTCUSD(), }) diff --git a/exchange/websocket/buffer/buffer.go b/exchange/websocket/buffer/buffer.go index fa193be8..63f8136b 100644 --- a/exchange/websocket/buffer/buffer.go +++ b/exchange/websocket/buffer/buffer.go @@ -80,8 +80,8 @@ func (w *Orderbook) validate(u *orderbook.Update) error { return nil } -// Update updates a stored pointer to an orderbook.Depth struct containing a -// bid and ask Tranches, this switches between the usage of a buffered update +// Update updates a stored pointer to an orderbook.Depth struct containing +// bid and ask levels, this switches between the usage of a buffered update func (w *Orderbook) Update(u *orderbook.Update) error { if err := w.validate(u); err != nil { return err @@ -275,7 +275,7 @@ func (o *orderbookHolder) updateByIDAndAction(updts *orderbook.Update) error { } // LoadSnapshot loads initial snapshot of orderbook data from websocket -func (w *Orderbook) LoadSnapshot(book *orderbook.Base) error { +func (w *Orderbook) LoadSnapshot(book *orderbook.Book) error { // Checks if book can deploy to depth err := book.Verify() if err != nil { @@ -311,8 +311,8 @@ func (w *Orderbook) LoadSnapshot(book *orderbook.Base) error { return nil } -// GetOrderbook returns an orderbook copy as orderbook.Base -func (w *Orderbook) GetOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) { +// GetOrderbook returns an orderbook copy as orderbook.Book +func (w *Orderbook) GetOrderbook(p currency.Pair, a asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } diff --git a/exchange/websocket/buffer/buffer_test.go b/exchange/websocket/buffer/buffer_test.go index 1ed73966..7ae3136c 100644 --- a/exchange/websocket/buffer/buffer_test.go +++ b/exchange/websocket/buffer/buffer_test.go @@ -19,7 +19,7 @@ import ( ) var ( - itemArray = [][]orderbook.Tranche{ + itemArray = [][]orderbook.Level{ {{Price: 1000, Amount: 1, ID: 1000}}, {{Price: 2000, Amount: 1, ID: 2000}}, {{Price: 3000, Amount: 1, ID: 3000}}, @@ -37,11 +37,11 @@ func getExclusivePair() (currency.Pair, error) { return currency.NewPairFromStrings(currency.BTC.String(), currency.USDT.String()+strconv.FormatInt(offset.IncrementAndGet(), 10)) } -func createSnapshot(pair currency.Pair, bookVerifiy ...bool) (holder *Orderbook, asks, bids orderbook.Tranches, err error) { - asks = orderbook.Tranches{{Price: 4000, Amount: 1, ID: 6}} - bids = orderbook.Tranches{{Price: 4000, Amount: 1, ID: 6}} +func createSnapshot(pair currency.Pair, bookVerifiy ...bool) (holder *Orderbook, asks, bids orderbook.Levels, err error) { + asks = orderbook.Levels{{Price: 4000, Amount: 1, ID: 6}} + bids = orderbook.Levels{{Price: 4000, Amount: 1, ID: 6}} - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: exchangeName, Asks: asks, Bids: bids, @@ -70,14 +70,14 @@ func createSnapshot(pair currency.Pair, bookVerifiy ...bool) (holder *Orderbook, return holder, asks, bids, err } -func bidAskGenerator() []orderbook.Tranche { - response := make([]orderbook.Tranche, 100) +func bidAskGenerator() []orderbook.Level { + response := make([]orderbook.Level, 100) for i := range 100 { price := float64(rand.Intn(1000)) //nolint:gosec // no need to import crypo/rand for testing if price == 0 { price = 1 } - response[i] = orderbook.Tranche{ + response[i] = orderbook.Level{ Amount: float64(rand.Intn(10)), //nolint:gosec // no need to import crypo/rand for testing Price: price, ID: int64(i), @@ -352,7 +352,7 @@ func TestInsertWithIDs(t *testing.T) { err = holder.Update(&orderbook.Update{ UpdateTime: time.Now(), Asset: asset.Spot, - Asks: []orderbook.Tranche{{Price: 999999}}, + Asks: []orderbook.Level{{Price: 999999}}, Pair: cp, }) require.NoError(t, err) @@ -437,11 +437,11 @@ func TestOrderbookLastUpdateID(t *testing.T) { assert.Equal(t, 1000., itemArray[0][0].Price) - holder.checksum = func(*orderbook.Base, uint32) error { return errors.New("testerino") } + holder.checksum = func(*orderbook.Book, uint32) error { return errors.New("testerino") } // this update invalidates the book err = holder.Update(&orderbook.Update{ - Asks: []orderbook.Tranche{{Price: 999999}}, + Asks: []orderbook.Level{{Price: 999999}}, Pair: cp, UpdateID: -1, Asset: asset.Spot, @@ -455,7 +455,7 @@ func TestOrderbookLastUpdateID(t *testing.T) { holder, _, _, err = createSnapshot(cp) require.NoError(t, err) - holder.checksum = func(*orderbook.Base, uint32) error { return nil } + holder.checksum = func(*orderbook.Book, uint32) error { return nil } holder.updateIDProgression = true for i := range itemArray { @@ -472,7 +472,7 @@ func TestOrderbookLastUpdateID(t *testing.T) { // out of order err = holder.Update(&orderbook.Update{ - Asks: []orderbook.Tranche{{Price: 999999}}, + Asks: []orderbook.Level{{Price: 999999}}, Pair: cp, UpdateID: 1, Asset: asset.Spot, @@ -491,8 +491,8 @@ func TestRunUpdateWithoutSnapshot(t *testing.T) { require.NoError(t, err) var holder Orderbook - asks := []orderbook.Tranche{{Price: 4000, Amount: 1, ID: 8}} - bids := []orderbook.Tranche{{Price: 5999, Amount: 1, ID: 8}, {Price: 4000, Amount: 1, ID: 9}} + asks := []orderbook.Level{{Price: 4000, Amount: 1, ID: 8}} + bids := []orderbook.Level{{Price: 5999, Amount: 1, ID: 8}, {Price: 4000, Amount: 1, ID: 9}} holder.exchangeName = exchangeName err = holder.Update(&orderbook.Update{ Bids: bids, @@ -513,8 +513,8 @@ func TestRunUpdateWithoutAnyUpdates(t *testing.T) { var obl Orderbook obl.exchangeName = exchangeName err = obl.Update(&orderbook.Update{ - Bids: []orderbook.Tranche{}, - Asks: []orderbook.Tranche{}, + Bids: []orderbook.Level{}, + Asks: []orderbook.Level{}, Pair: cp, UpdateTime: time.Now(), Asset: asset.Spot, @@ -531,7 +531,7 @@ func TestRunSnapshotWithNoData(t *testing.T) { var obl Orderbook obl.ob = make(map[key.PairAsset]*orderbookHolder) obl.dataHandler = make(chan any, 1) - var snapShot1 orderbook.Base + var snapShot1 orderbook.Book snapShot1.Asset = asset.Spot snapShot1.Pair = cp snapShot1.Exchange = "test" @@ -549,10 +549,10 @@ func TestLoadSnapshot(t *testing.T) { var obl Orderbook obl.dataHandler = make(chan any, 100) obl.ob = make(map[key.PairAsset]*orderbookHolder) - var snapShot1 orderbook.Base + var snapShot1 orderbook.Book snapShot1.Exchange = "SnapshotWithOverride" - asks := []orderbook.Tranche{{Price: 4000, Amount: 1, ID: 8}} - bids := []orderbook.Tranche{{Price: 4000, Amount: 1, ID: 9}} + asks := []orderbook.Level{{Price: 4000, Amount: 1, ID: 8}} + bids := []orderbook.Level{{Price: 4000, Amount: 1, ID: 9}} snapShot1.Asks = asks snapShot1.Bids = bids snapShot1.Asset = asset.Spot @@ -584,9 +584,9 @@ func TestInsertingSnapShots(t *testing.T) { var holder Orderbook holder.dataHandler = make(chan any, 100) holder.ob = make(map[key.PairAsset]*orderbookHolder) - var snapShot1 orderbook.Base + var snapShot1 orderbook.Book snapShot1.Exchange = "WSORDERBOOKTEST1" - asks := []orderbook.Tranche{ + asks := []orderbook.Level{ {Price: 6000, Amount: 1, ID: 1}, {Price: 6001, Amount: 0.5, ID: 2}, {Price: 6002, Amount: 2, ID: 3}, @@ -600,7 +600,7 @@ func TestInsertingSnapShots(t *testing.T) { {Price: 6010, Amount: 7, ID: 11}, } - bids := []orderbook.Tranche{ + bids := []orderbook.Level{ {Price: 5999, Amount: 1, ID: 12}, {Price: 5998, Amount: 0.5, ID: 13}, {Price: 5997, Amount: 2, ID: 14}, @@ -621,9 +621,9 @@ func TestInsertingSnapShots(t *testing.T) { snapShot1.LastUpdated = time.Now() require.NoError(t, holder.LoadSnapshot(&snapShot1)) - var snapShot2 orderbook.Base + var snapShot2 orderbook.Book snapShot2.Exchange = "WSORDERBOOKTEST2" - asks = []orderbook.Tranche{ + asks = []orderbook.Level{ {Price: 51, Amount: 1, ID: 1}, {Price: 52, Amount: 0.5, ID: 2}, {Price: 53, Amount: 2, ID: 3}, @@ -637,7 +637,7 @@ func TestInsertingSnapShots(t *testing.T) { {Price: 60, Amount: 7, ID: 11}, } - bids = []orderbook.Tranche{ + bids = []orderbook.Level{ {Price: 49, Amount: 1, ID: 12}, {Price: 48, Amount: 0.5, ID: 13}, {Price: 47, Amount: 2, ID: 14}, @@ -662,9 +662,9 @@ func TestInsertingSnapShots(t *testing.T) { snapShot2.LastUpdated = time.Now() require.NoError(t, holder.LoadSnapshot(&snapShot2)) - var snapShot3 orderbook.Base + var snapShot3 orderbook.Book snapShot3.Exchange = "WSORDERBOOKTEST3" - asks = []orderbook.Tranche{ + asks = []orderbook.Level{ {Price: 511, Amount: 1, ID: 1}, {Price: 52, Amount: 0.5, ID: 2}, {Price: 53, Amount: 2, ID: 3}, @@ -678,7 +678,7 @@ func TestInsertingSnapShots(t *testing.T) { {Price: 60, Amount: 7, ID: 11}, } - bids = []orderbook.Tranche{ + bids = []orderbook.Level{ {Price: 49, Amount: 1, ID: 12}, {Price: 48, Amount: 0.5, ID: 13}, {Price: 47, Amount: 2, ID: 14}, @@ -844,10 +844,10 @@ func TestEnsureMultipleUpdatesViaPrice(t *testing.T) { assert.LessOrEqual(t, 3, askLen) } -func deploySliceOrdered(size int) orderbook.Tranches { - items := make([]orderbook.Tranche, size) +func deploySliceOrdered(size int) orderbook.Levels { + items := make([]orderbook.Level, size) for i := range size { - items[i] = orderbook.Tranche{Amount: 1, Price: rand.Float64() + float64(i), ID: rand.Int63()} //nolint:gosec // Not needed for tests + items[i] = orderbook.Level{Amount: 1, Price: rand.Float64() + float64(i), ID: rand.Int63()} //nolint:gosec // Not needed for tests } return items } @@ -878,7 +878,7 @@ func TestUpdateByIDAndAction(t *testing.T) { err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.Amend, - Bids: []orderbook.Tranche{{Price: 100, ID: 6969}}, + Bids: []orderbook.Level{{Price: 100, ID: 6969}}, }) require.ErrorIs(t, err, errAmendFailure) @@ -888,8 +888,8 @@ func TestUpdateByIDAndAction(t *testing.T) { // append to slice err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.UpdateInsert, - Bids: []orderbook.Tranche{{Price: 0, ID: 1337, Amount: 1}}, - Asks: []orderbook.Tranche{{Price: 100, ID: 1337, Amount: 1}}, + Bids: []orderbook.Level{{Price: 0, ID: 1337, Amount: 1}}, + Asks: []orderbook.Level{{Price: 100, ID: 1337, Amount: 1}}, UpdateTime: time.Now(), }) require.NoError(t, err) @@ -902,8 +902,8 @@ func TestUpdateByIDAndAction(t *testing.T) { // Change amount err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.UpdateInsert, - Bids: []orderbook.Tranche{{Price: 0, ID: 1337, Amount: 100}}, - Asks: []orderbook.Tranche{{Price: 100, ID: 1337, Amount: 100}}, + Bids: []orderbook.Level{{Price: 0, ID: 1337, Amount: 100}}, + Asks: []orderbook.Level{{Price: 100, ID: 1337, Amount: 100}}, UpdateTime: time.Now(), }) require.NoError(t, err) @@ -916,8 +916,8 @@ func TestUpdateByIDAndAction(t *testing.T) { // Change price level err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.UpdateInsert, - Bids: []orderbook.Tranche{{Price: 100, ID: 1337, Amount: 99}}, - Asks: []orderbook.Tranche{{Price: 0, ID: 1337, Amount: 99}}, + Bids: []orderbook.Level{{Price: 100, ID: 1337, Amount: 99}}, + Asks: []orderbook.Level{{Price: 0, ID: 1337, Amount: 99}}, UpdateTime: time.Now(), }) require.NoError(t, err) @@ -935,7 +935,7 @@ func TestUpdateByIDAndAction(t *testing.T) { // Delete - not found err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.Delete, - Asks: []orderbook.Tranche{{Price: 0, ID: 1337, Amount: 99}}, + Asks: []orderbook.Level{{Price: 0, ID: 1337, Amount: 99}}, }) require.ErrorIs(t, err, errDeleteFailure) @@ -945,7 +945,7 @@ func TestUpdateByIDAndAction(t *testing.T) { // Delete - found err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.Delete, - Asks: []orderbook.Tranche{asks[0]}, + Asks: []orderbook.Level{asks[0]}, UpdateTime: time.Now(), }) require.NoError(t, err) @@ -957,7 +957,7 @@ func TestUpdateByIDAndAction(t *testing.T) { // Apply update err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.Amend, - Asks: []orderbook.Tranche{{ID: 123456}}, + Asks: []orderbook.Level{{ID: 123456}}, }) require.ErrorIs(t, err, errAmendFailure) @@ -974,7 +974,7 @@ func TestUpdateByIDAndAction(t *testing.T) { err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.Amend, - Asks: []orderbook.Tranche{update}, + Asks: []orderbook.Level{update}, UpdateTime: time.Now(), }) require.NoError(t, err) @@ -993,10 +993,10 @@ func TestFlushOrderbook(t *testing.T) { err = w.Setup(&config.Exchange{Name: "test"}, &Config{}, make(chan any, 2)) require.NoError(t, err) - var snapShot1 orderbook.Base + var snapShot1 orderbook.Book snapShot1.Exchange = "Snapshooooot" - asks := []orderbook.Tranche{{Price: 4000, Amount: 1, ID: 8}} - bids := []orderbook.Tranche{{Price: 4000, Amount: 1, ID: 9}} + asks := []orderbook.Level{{Price: 4000, Amount: 1, ID: 8}} + bids := []orderbook.Level{{Price: 4000, Amount: 1, ID: 9}} snapShot1.Asks = asks snapShot1.Bids = bids snapShot1.Asset = asset.Spot diff --git a/exchange/websocket/buffer/buffer_types.go b/exchange/websocket/buffer/buffer_types.go index d59e1fcd..6d4deace 100644 --- a/exchange/websocket/buffer/buffer_types.go +++ b/exchange/websocket/buffer/buffer_types.go @@ -22,7 +22,7 @@ type Config struct { // prior ID. This will skip processing and not error. UpdateIDProgression bool // Checksum is a package defined checksum calculation for updated books. - Checksum func(state *orderbook.Base, checksum uint32) error + Checksum func(state *orderbook.Book, checksum uint32) error } // Orderbook defines a local cache of orderbooks for amending, appending @@ -42,7 +42,7 @@ type Orderbook struct { // prior ID. This will skip processing and not error. updateIDProgression bool // checksum is a package defined checksum calculation for updated books. - checksum func(state *orderbook.Base, checksum uint32) error + checksum func(state *orderbook.Book, checksum uint32) error // TODO: sync.RWMutex. For the moment we process the orderbook in a single // thread. In future when there are workers directly involved this can be // can be improved with RW mechanics which will allow updates to occur at diff --git a/exchanges/alphapoint/alphapoint_wrapper.go b/exchanges/alphapoint/alphapoint_wrapper.go index 11d3b34a..ffff7102 100644 --- a/exchanges/alphapoint/alphapoint_wrapper.go +++ b/exchanges/alphapoint/alphapoint_wrapper.go @@ -175,30 +175,30 @@ func (a *Alphapoint) UpdateTicker(ctx context.Context, p currency.Pair, assetTyp } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (a *Alphapoint) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (a *Alphapoint) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := a.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - orderBook := new(orderbook.Base) + orderBook := new(orderbook.Book) orderbookNew, err := a.GetOrderbook(ctx, p.String()) if err != nil { return orderBook, err } - orderBook.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + orderBook.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - orderBook.Bids[x] = orderbook.Tranche{ + orderBook.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Quantity, Price: orderbookNew.Bids[x].Price, } } - orderBook.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + orderBook.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - orderBook.Asks[x] = orderbook.Tranche{ + orderBook.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Quantity, Price: orderbookNew.Asks[x].Price, } diff --git a/exchanges/binance/binance_websocket.go b/exchanges/binance/binance_websocket.go index 6472fb6f..aff05ea9 100644 --- a/exchanges/binance/binance_websocket.go +++ b/exchanges/binance/binance_websocket.go @@ -461,24 +461,24 @@ func (b *Binance) SeedLocalCache(ctx context.Context, p currency.Pair) error { // SeedLocalCacheWithBook seeds the local orderbook cache func (b *Binance) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *OrderBook) error { - newOrderBook := orderbook.Base{ + newOrderBook := orderbook.Book{ Pair: p, Asset: asset.Spot, Exchange: b.Name, LastUpdateID: orderbookNew.LastUpdateID, VerifyOrderbook: b.CanVerifyOrderbook, - Bids: make(orderbook.Tranches, len(orderbookNew.Bids)), - Asks: make(orderbook.Tranches, len(orderbookNew.Asks)), + Bids: make(orderbook.Levels, len(orderbookNew.Bids)), + Asks: make(orderbook.Levels, len(orderbookNew.Asks)), LastUpdated: time.Now(), // Time not provided in REST book. } for i := range orderbookNew.Bids { - newOrderBook.Bids[i] = orderbook.Tranche{ + newOrderBook.Bids[i] = orderbook.Level{ Amount: orderbookNew.Bids[i].Quantity, Price: orderbookNew.Bids[i].Price, } } for i := range orderbookNew.Asks { - newOrderBook.Asks[i] = orderbook.Tranche{ + newOrderBook.Asks[i] = orderbook.Level{ Amount: orderbookNew.Asks[i].Quantity, Price: orderbookNew.Asks[i].Price, } @@ -615,16 +615,16 @@ func (b *Binance) manageSubs(op string, subs subscription.List) error { // ProcessOrderbookUpdate processes the websocket orderbook update func (b *Binance) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WebsocketDepthStream) error { - updateBid := make([]orderbook.Tranche, len(ws.UpdateBids)) + updateBid := make([]orderbook.Level, len(ws.UpdateBids)) for i := range ws.UpdateBids { - updateBid[i] = orderbook.Tranche{ + updateBid[i] = orderbook.Level{ Price: ws.UpdateBids[i][0].Float64(), Amount: ws.UpdateBids[i][1].Float64(), } } - updateAsk := make([]orderbook.Tranche, len(ws.UpdateAsks)) + updateAsk := make([]orderbook.Level, len(ws.UpdateAsks)) for i := range ws.UpdateAsks { - updateAsk[i] = orderbook.Tranche{ + updateAsk[i] = orderbook.Level{ Price: ws.UpdateAsks[i][0].Float64(), Amount: ws.UpdateAsks[i][1].Float64(), } @@ -919,7 +919,7 @@ func (o *orderbookManager) fetchBookViaREST(pair currency.Pair) error { } } -func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(currency.Pair, asset.Item, *WebsocketDepthStream) error, pair currency.Pair, recent *orderbook.Base) error { +func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(currency.Pair, asset.Item, *WebsocketDepthStream) error, pair currency.Pair, recent *orderbook.Book) error { o.Lock() defer o.Unlock() state, ok := o.state[pair.Base][pair.Quote][asset.Spot] @@ -953,7 +953,7 @@ buffer: } // validate checks for correct update alignment -func (u *update) validate(updt *WebsocketDepthStream, recent *orderbook.Base) (bool, error) { +func (u *update) validate(updt *WebsocketDepthStream, recent *orderbook.Book) (bool, error) { if updt.LastUpdateID <= recent.LastUpdateID { // Drop any event where u is <= lastUpdateId in the snapshot. return false, nil diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index 0ac4040e..3ecf34b4 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -513,14 +513,14 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Binance) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Binance) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -547,16 +547,16 @@ func (b *Binance) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp return book, err } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Quantity, Price: orderbookNew.Bids[x].Price, } } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Quantity, Price: orderbookNew.Asks[x].Price, } diff --git a/exchanges/binanceus/binanceus_websocket.go b/exchanges/binanceus/binanceus_websocket.go index 0b12923b..9ba53dab 100644 --- a/exchanges/binanceus/binanceus_websocket.go +++ b/exchanges/binanceus/binanceus_websocket.go @@ -656,13 +656,13 @@ func (bi *Binanceus) SynchroniseWebsocketOrderbook() { // ProcessOrderbookUpdate processes the websocket orderbook update func (bi *Binanceus) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, wsDSUpdate *WebsocketDepthStream) error { - updateBid := make([]orderbook.Tranche, len(wsDSUpdate.UpdateBids)) + updateBid := make([]orderbook.Level, len(wsDSUpdate.UpdateBids)) for i := range wsDSUpdate.UpdateBids { updateBid[i].Price = wsDSUpdate.UpdateBids[i][0].Float64() updateBid[i].Amount = wsDSUpdate.UpdateBids[i][1].Float64() } - updateAsk := make([]orderbook.Tranche, len(wsDSUpdate.UpdateAsks)) + updateAsk := make([]orderbook.Level, len(wsDSUpdate.UpdateAsks)) for i := range wsDSUpdate.UpdateAsks { updateAsk[i].Price = wsDSUpdate.UpdateAsks[i][0].Float64() updateAsk[i].Amount = wsDSUpdate.UpdateAsks[i][1].Float64() @@ -804,24 +804,24 @@ func (bi *Binanceus) SeedLocalCache(ctx context.Context, p currency.Pair) error // SeedLocalCacheWithBook seeds the local orderbook cache func (bi *Binanceus) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *OrderBook) error { - newOrderBook := orderbook.Base{ + newOrderBook := orderbook.Book{ Pair: p, Asset: asset.Spot, Exchange: bi.Name, LastUpdateID: orderbookNew.LastUpdateID, VerifyOrderbook: bi.CanVerifyOrderbook, - Bids: make(orderbook.Tranches, len(orderbookNew.Bids)), - Asks: make(orderbook.Tranches, len(orderbookNew.Asks)), + Bids: make(orderbook.Levels, len(orderbookNew.Bids)), + Asks: make(orderbook.Levels, len(orderbookNew.Asks)), LastUpdated: time.Now(), // Time not provided in REST book. } for i := range orderbookNew.Bids { - newOrderBook.Bids[i] = orderbook.Tranche{ + newOrderBook.Bids[i] = orderbook.Level{ Amount: orderbookNew.Bids[i].Quantity, Price: orderbookNew.Bids[i].Price, } } for i := range orderbookNew.Asks { - newOrderBook.Asks[i] = orderbook.Tranche{ + newOrderBook.Asks[i] = orderbook.Level{ Amount: orderbookNew.Asks[i].Quantity, Price: orderbookNew.Asks[i].Price, } @@ -985,7 +985,7 @@ func (o *orderbookManager) stopNeedsFetchingBook(pair currency.Pair) error { return nil } -func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(currency.Pair, asset.Item, *WebsocketDepthStream) error, pair currency.Pair, recent *orderbook.Base) error { +func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(currency.Pair, asset.Item, *WebsocketDepthStream) error, pair currency.Pair, recent *orderbook.Book) error { o.Lock() defer o.Unlock() state, ok := o.state[pair.Base][pair.Quote][asset.Spot] @@ -1019,7 +1019,7 @@ buffer: } // validate checks for correct update alignment -func (u *update) validate(updt *WebsocketDepthStream, recent *orderbook.Base) (bool, error) { +func (u *update) validate(updt *WebsocketDepthStream, recent *orderbook.Book) (bool, error) { if updt.LastUpdateID <= recent.LastUpdateID { // Drop any event where u is <= lastUpdateId in the snapshot. return false, nil diff --git a/exchanges/binanceus/binanceus_wrapper.go b/exchanges/binanceus/binanceus_wrapper.go index b9959262..751fd257 100644 --- a/exchanges/binanceus/binanceus_wrapper.go +++ b/exchanges/binanceus/binanceus_wrapper.go @@ -311,14 +311,14 @@ func (bi *Binanceus) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (bi *Binanceus) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (bi *Binanceus) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := bi.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: bi.Name, Pair: pair, Asset: assetType, @@ -332,16 +332,16 @@ func (bi *Binanceus) UpdateOrderbook(ctx context.Context, pair currency.Pair, as if err != nil { return book, err } - book.Bids = make([]orderbook.Tranche, len(orderbookNew.Bids)) + book.Bids = make([]orderbook.Level, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Quantity, Price: orderbookNew.Bids[x].Price, } } - book.Asks = make([]orderbook.Tranche, len(orderbookNew.Asks)) + book.Asks = make([]orderbook.Level, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Quantity, Price: orderbookNew.Asks[x].Price, } diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index a714b01b..023ebed1 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -1767,8 +1767,8 @@ func TestGetHistoricTrades(t *testing.T) { } } -var testOb = orderbook.Base{ - Asks: []orderbook.Tranche{ +var testOb = orderbook.Book{ + Asks: []orderbook.Level{ {Price: 0.05005, Amount: 0.00000500}, {Price: 0.05010, Amount: 0.00000500}, {Price: 0.05015, Amount: 0.00000500}, @@ -1780,7 +1780,7 @@ var testOb = orderbook.Base{ {Price: 0.05045, Amount: 0.00000500}, {Price: 0.05050, Amount: 0.00000500}, }, - Bids: []orderbook.Tranche{ + Bids: []orderbook.Level{ {Price: 0.05000, Amount: 0.00000500}, {Price: 0.04995, Amount: 0.00000500}, {Price: 0.04990, Amount: 0.00000500}, @@ -1802,7 +1802,7 @@ func TestChecksum(t *testing.T) { } func TestReOrderbyID(t *testing.T) { - asks := []orderbook.Tranche{ + asks := []orderbook.Level{ {ID: 4, Price: 100, Amount: 0.00000500}, {ID: 3, Price: 100, Amount: 0.00000500}, {ID: 2, Price: 100, Amount: 0.00000500}, @@ -1822,7 +1822,7 @@ func TestReOrderbyID(t *testing.T) { } } - bids := []orderbook.Tranche{ + bids := []orderbook.Level{ {ID: 4, Price: 100, Amount: 0.00000500}, {ID: 3, Price: 100, Amount: 0.00000500}, {ID: 2, Price: 100, Amount: 0.00000500}, diff --git a/exchanges/bitfinex/bitfinex_websocket.go b/exchanges/bitfinex/bitfinex_websocket.go index b8426700..e046e2d7 100644 --- a/exchanges/bitfinex/bitfinex_websocket.go +++ b/exchanges/bitfinex/bitfinex_websocket.go @@ -1529,11 +1529,11 @@ func (b *Bitfinex) WsInsertSnapshot(p currency.Pair, assetType asset.Item, books if len(books) == 0 { return errors.New("no orderbooks submitted") } - var book orderbook.Base - book.Bids = make(orderbook.Tranches, 0, len(books)) - book.Asks = make(orderbook.Tranches, 0, len(books)) + var book orderbook.Book + book.Bids = make(orderbook.Levels, 0, len(books)) + book.Asks = make(orderbook.Levels, 0, len(books)) for i := range books { - item := orderbook.Tranche{ + item := orderbook.Level{ ID: books[i].ID, Amount: books[i].Amount, Price: books[i].Price, @@ -1578,13 +1578,13 @@ func (b *Bitfinex) WsUpdateOrderbook(c *subscription.Subscription, p currency.Pa orderbookUpdate := orderbook.Update{ Asset: assetType, Pair: p, - Bids: make([]orderbook.Tranche, 0, len(book)), - Asks: make([]orderbook.Tranche, 0, len(book)), + Bids: make([]orderbook.Level, 0, len(book)), + Asks: make([]orderbook.Level, 0, len(book)), UpdateTime: time.Now(), // Not included in update } for i := range book { - item := orderbook.Tranche{ + item := orderbook.Level{ ID: book[i].ID, Amount: book[i].Amount, Price: book[i].Price, @@ -2077,14 +2077,14 @@ func makeRequestInterface(channelName string, data any) []any { return []any{0, channelName, nil, data} } -func validateCRC32(book *orderbook.Base, token uint32) error { +func validateCRC32(book *orderbook.Book, token uint32) error { // Order ID's need to be sub-sorted in ascending order, this needs to be // done on the main book to ensure that we do not cut price levels out below reOrderByID(book.Bids) reOrderByID(book.Asks) // R0 precision calculation is based on order ID's and amount values - var bids, asks []orderbook.Tranche + var bids, asks []orderbook.Level for i := range 25 { if i < len(book.Bids) { bids = append(bids, book.Bids[i]) @@ -2138,10 +2138,10 @@ func validateCRC32(book *orderbook.Base, token uint32) error { // reOrderByID sub sorts orderbook items by its corresponding ID when price // levels are the same. TODO: Deprecate and shift to buffer level insertion // based off ascending ID. -func reOrderByID(depth []orderbook.Tranche) { +func reOrderByID(depth []orderbook.Level) { subSort: for x := 0; x < len(depth); { - var subset []orderbook.Tranche + var subset []orderbook.Level // Traverse forward elements for y := x + 1; y < len(depth); y++ { if depth[x].Price == depth[y].Price && diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index bef7b079..62859d91 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -332,14 +332,14 @@ func (b *Bitfinex) UpdateTicker(ctx context.Context, p currency.Pair, a asset.It } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitfinex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitfinex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - o := &orderbook.Base{ + o := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -366,18 +366,18 @@ func (b *Bitfinex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy } if assetType == asset.MarginFunding { o.IsFundingRate = true - o.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + o.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - o.Asks[x] = orderbook.Tranche{ + o.Asks[x] = orderbook.Level{ ID: orderbookNew.Asks[x].OrderID, Price: orderbookNew.Asks[x].Rate, Amount: orderbookNew.Asks[x].Amount, Period: int64(orderbookNew.Asks[x].Period), } } - o.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + o.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - o.Bids[x] = orderbook.Tranche{ + o.Bids[x] = orderbook.Level{ ID: orderbookNew.Bids[x].OrderID, Price: orderbookNew.Bids[x].Rate, Amount: orderbookNew.Bids[x].Amount, @@ -385,17 +385,17 @@ func (b *Bitfinex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy } } } else { - o.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + o.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - o.Asks[x] = orderbook.Tranche{ + o.Asks[x] = orderbook.Level{ ID: orderbookNew.Asks[x].OrderID, Price: orderbookNew.Asks[x].Price, Amount: orderbookNew.Asks[x].Amount, } } - o.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + o.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - o.Bids[x] = orderbook.Tranche{ + o.Bids[x] = orderbook.Level{ ID: orderbookNew.Bids[x].OrderID, Price: orderbookNew.Bids[x].Price, Amount: orderbookNew.Bids[x].Amount, diff --git a/exchanges/bitflyer/bitflyer_wrapper.go b/exchanges/bitflyer/bitflyer_wrapper.go index e3c431d9..15614131 100644 --- a/exchanges/bitflyer/bitflyer_wrapper.go +++ b/exchanges/bitflyer/bitflyer_wrapper.go @@ -193,14 +193,14 @@ func (b *Bitflyer) CheckFXString(p currency.Pair) currency.Pair { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitflyer) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitflyer) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -217,17 +217,17 @@ func (b *Bitflyer) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy return book, err } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Price: orderbookNew.Asks[x].Price, Amount: orderbookNew.Asks[x].Size, } } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Price: orderbookNew.Bids[x].Price, Amount: orderbookNew.Bids[x].Size, } diff --git a/exchanges/bithumb/bithumb_websocket_types.go b/exchanges/bithumb/bithumb_websocket_types.go index a93cfda7..9c8aecf5 100644 --- a/exchanges/bithumb/bithumb_websocket_types.go +++ b/exchanges/bithumb/bithumb_websocket_types.go @@ -39,13 +39,13 @@ type WsTicker struct { VolumePower float64 `json:"volumePower,string"` } -// WsOrderbooks defines an amalgamated bid ask orderbook tranche list +// WsOrderbooks defines an amalgamated bid ask orderbook level list type WsOrderbooks struct { List []WsOrderbook `json:"list"` DateTime types.Time `json:"datetime"` } -// WsOrderbook defines a singular orderbook tranche +// WsOrderbook defines a singular orderbook level type WsOrderbook struct { Symbol currency.Pair `json:"symbol"` OrderSide string `json:"orderType"` diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index 01a1e1cf..adcdfadd 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -256,14 +256,14 @@ func (b *Bithumb) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -276,17 +276,17 @@ func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp return book, err } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Data.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Data.Bids)) for i := range orderbookNew.Data.Bids { - book.Bids[i] = orderbook.Tranche{ + book.Bids[i] = orderbook.Level{ Amount: orderbookNew.Data.Bids[i].Quantity, Price: orderbookNew.Data.Bids[i].Price, } } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Data.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Data.Asks)) for i := range orderbookNew.Data.Asks { - book.Asks[i] = orderbook.Tranche{ + book.Asks[i] = orderbook.Level{ Amount: orderbookNew.Data.Asks[i].Quantity, Price: orderbookNew.Data.Asks[i].Price, } diff --git a/exchanges/bithumb/bithumb_ws_orderbook.go b/exchanges/bithumb/bithumb_ws_orderbook.go index 4b6b739e..7c49fa32 100644 --- a/exchanges/bithumb/bithumb_ws_orderbook.go +++ b/exchanges/bithumb/bithumb_ws_orderbook.go @@ -25,10 +25,10 @@ const ( ) func (b *Bithumb) processBooks(updates *WsOrderbooks) error { - bids := make([]orderbook.Tranche, 0, len(updates.List)) - asks := make([]orderbook.Tranche, 0, len(updates.List)) + bids := make([]orderbook.Level, 0, len(updates.List)) + asks := make([]orderbook.Level, 0, len(updates.List)) for x := range updates.List { - i := orderbook.Tranche{Price: updates.List[x].Price, Amount: updates.List[x].Quantity} + i := orderbook.Level{Price: updates.List[x].Price, Amount: updates.List[x].Quantity} if updates.List[x].OrderSide == "bid" { bids = append(bids, i) continue @@ -351,7 +351,7 @@ func (o *orderbookManager) fetchBookViaREST(pair currency.Pair) error { } } -func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(*WsOrderbooks) error, pair currency.Pair, recent *orderbook.Base) error { +func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(*WsOrderbooks) error, pair currency.Pair, recent *orderbook.Book) error { o.Lock() defer o.Unlock() state, ok := o.state[pair.Base][pair.Quote][asset.Spot] @@ -382,7 +382,7 @@ buffer: } // validate checks for correct update alignment -func (u *update) validate(updt *WsOrderbooks, recent *orderbook.Base) bool { +func (u *update) validate(updt *WsOrderbooks, recent *orderbook.Book) bool { return updt.DateTime.Time().After(recent.LastUpdated) } @@ -425,17 +425,17 @@ func (b *Bithumb) SeedLocalCache(ctx context.Context, p currency.Pair) error { // SeedLocalCacheWithBook seeds the local orderbook cache func (b *Bithumb) SeedLocalCacheWithBook(p currency.Pair, o *Orderbook) error { - var newOrderBook orderbook.Base - newOrderBook.Bids = make(orderbook.Tranches, len(o.Data.Bids)) + var newOrderBook orderbook.Book + newOrderBook.Bids = make(orderbook.Levels, len(o.Data.Bids)) for i := range o.Data.Bids { - newOrderBook.Bids[i] = orderbook.Tranche{ + newOrderBook.Bids[i] = orderbook.Level{ Amount: o.Data.Bids[i].Quantity, Price: o.Data.Bids[i].Price, } } - newOrderBook.Asks = make(orderbook.Tranches, len(o.Data.Asks)) + newOrderBook.Asks = make(orderbook.Levels, len(o.Data.Asks)) for i := range o.Data.Asks { - newOrderBook.Asks[i] = orderbook.Tranche{ + newOrderBook.Asks[i] = orderbook.Level{ Amount: o.Data.Asks[i].Quantity, Price: o.Data.Asks[i].Price, } diff --git a/exchanges/bitmex/bitmex_websocket.go b/exchanges/bitmex/bitmex_websocket.go index e7c6a3ac..1a7d480b 100644 --- a/exchanges/bitmex/bitmex_websocket.go +++ b/exchanges/bitmex/bitmex_websocket.go @@ -400,13 +400,13 @@ func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, p currency. switch action { case bitmexActionInitialData: - book := orderbook.Base{ - Asks: make(orderbook.Tranches, 0, len(data)), - Bids: make(orderbook.Tranches, 0, len(data)), + book := orderbook.Book{ + Asks: make(orderbook.Levels, 0, len(data)), + Bids: make(orderbook.Levels, 0, len(data)), } for i := range data { - item := orderbook.Tranche{ + item := orderbook.Level{ Price: data[i].Price, Amount: float64(data[i].Size), ID: data[i].ID, @@ -439,10 +439,10 @@ func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, p currency. return err } - asks := make([]orderbook.Tranche, 0, len(data)) - bids := make([]orderbook.Tranche, 0, len(data)) + asks := make([]orderbook.Level, 0, len(data)) + bids := make([]orderbook.Level, 0, len(data)) for i := range data { - nItem := orderbook.Tranche{ + nItem := orderbook.Level{ Price: data[i].Price, Amount: float64(data[i].Size), ID: data[i].ID, diff --git a/exchanges/bitmex/bitmex_wrapper.go b/exchanges/bitmex/bitmex_wrapper.go index d7764455..867d9d4b 100644 --- a/exchanges/bitmex/bitmex_wrapper.go +++ b/exchanges/bitmex/bitmex_wrapper.go @@ -387,14 +387,14 @@ func (b *Bitmex) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitmex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitmex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -419,17 +419,17 @@ func (b *Bitmex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return book, err } - book.Asks = make(orderbook.Tranches, 0, len(orderbookNew)) - book.Bids = make(orderbook.Tranches, 0, len(orderbookNew)) + book.Asks = make(orderbook.Levels, 0, len(orderbookNew)) + book.Bids = make(orderbook.Levels, 0, len(orderbookNew)) for i := range orderbookNew { switch { case strings.EqualFold(orderbookNew[i].Side, order.Sell.String()): - book.Asks = append(book.Asks, orderbook.Tranche{ + book.Asks = append(book.Asks, orderbook.Level{ Amount: float64(orderbookNew[i].Size), Price: orderbookNew[i].Price, }) case strings.EqualFold(orderbookNew[i].Side, order.Buy.String()): - book.Bids = append(book.Bids, orderbook.Tranche{ + book.Bids = append(book.Bids, orderbook.Level{ Amount: float64(orderbookNew[i].Size), Price: orderbookNew[i].Price, }) diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index fe0079c7..9261d5ef 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -639,7 +639,7 @@ func parseTime(dateTime string) (time.Time, error) { return time.Parse(bitstampTimeLayout, dateTime) } -func filterOrderbookZeroBidPrice(ob *orderbook.Base) { +func filterOrderbookZeroBidPrice(ob *orderbook.Book) { if len(ob.Bids) == 0 || ob.Bids[len(ob.Bids)-1].Price != 0 { return } diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index 66e016b4..4353a874 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -941,14 +941,14 @@ func TestGetHistoricTrades(t *testing.T) { func TestOrderbookZeroBidPrice(t *testing.T) { t.Parallel() - ob := &orderbook.Base{ + ob := &orderbook.Book{ Exchange: "Bitstamp", Pair: btcusdPair, Asset: asset.Spot, } filterOrderbookZeroBidPrice(ob) - ob.Bids = orderbook.Tranches{ + ob.Bids = orderbook.Levels{ {Price: 69, Amount: 1337}, {Price: 0, Amount: 69}, } @@ -957,7 +957,7 @@ func TestOrderbookZeroBidPrice(t *testing.T) { t.Error("invalid orderbook bid values") } - ob.Bids = orderbook.Tranches{ + ob.Bids = orderbook.Levels{ {Price: 59, Amount: 1337}, {Price: 42, Amount: 8595}, } diff --git a/exchanges/bitstamp/bitstamp_websocket.go b/exchanges/bitstamp/bitstamp_websocket.go index 2eeec91e..caaea5fd 100644 --- a/exchanges/bitstamp/bitstamp_websocket.go +++ b/exchanges/bitstamp/bitstamp_websocket.go @@ -296,9 +296,9 @@ func (b *Bitstamp) handleWSOrderbook(msg []byte) error { return err } - obUpdate := &orderbook.Base{ - Bids: make(orderbook.Tranches, len(wsOrderBookResp.Data.Bids)), - Asks: make(orderbook.Tranches, len(wsOrderBookResp.Data.Asks)), + obUpdate := &orderbook.Book{ + Bids: make(orderbook.Levels, len(wsOrderBookResp.Data.Bids)), + Asks: make(orderbook.Levels, len(wsOrderBookResp.Data.Asks)), Pair: p, LastUpdated: wsOrderBookResp.Data.Microtimestamp.Time(), Asset: asset.Spot, @@ -334,24 +334,24 @@ func (b *Bitstamp) seedOrderBook(ctx context.Context) error { return err } - newOrderBook := &orderbook.Base{ + newOrderBook := &orderbook.Book{ Pair: p[x], Asset: asset.Spot, Exchange: b.Name, VerifyOrderbook: b.CanVerifyOrderbook, - Bids: make(orderbook.Tranches, len(orderbookSeed.Bids)), - Asks: make(orderbook.Tranches, len(orderbookSeed.Asks)), + Bids: make(orderbook.Levels, len(orderbookSeed.Bids)), + Asks: make(orderbook.Levels, len(orderbookSeed.Asks)), LastUpdated: orderbookSeed.Timestamp, } for i := range orderbookSeed.Asks { - newOrderBook.Asks[i] = orderbook.Tranche{ + newOrderBook.Asks[i] = orderbook.Level{ Price: orderbookSeed.Asks[i].Price, Amount: orderbookSeed.Asks[i].Amount, } } for i := range orderbookSeed.Bids { - newOrderBook.Bids[i] = orderbook.Tranche{ + newOrderBook.Bids[i] = orderbook.Level{ Price: orderbookSeed.Bids[i].Price, Amount: orderbookSeed.Bids[i].Amount, } diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index 0894b4f8..83e9f686 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -288,14 +288,14 @@ func (b *Bitstamp) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBui } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -311,9 +311,9 @@ func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy return book, err } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price, } @@ -321,9 +321,9 @@ func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy filterOrderbookZeroBidPrice(book) - book.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price, } diff --git a/exchanges/btcmarkets/btcmarkets_test.go b/exchanges/btcmarkets/btcmarkets_test.go index dd523d05..cf9ec391 100644 --- a/exchanges/btcmarkets/btcmarkets_test.go +++ b/exchanges/btcmarkets/btcmarkets_test.go @@ -773,12 +773,12 @@ func TestGetHistoricTrades(t *testing.T) { } func TestChecksum(t *testing.T) { - b := &orderbook.Base{ - Asks: []orderbook.Tranche{ + b := &orderbook.Book{ + Asks: []orderbook.Level{ {Price: 0.3965, Amount: 44149.815}, {Price: 0.3967, Amount: 16000.0}, }, - Bids: []orderbook.Tranche{ + Bids: []orderbook.Level{ {Price: 0.396, Amount: 51.0}, {Price: 0.396, Amount: 25.0}, {Price: 0.3958, Amount: 18570.0}, diff --git a/exchanges/btcmarkets/btcmarkets_types.go b/exchanges/btcmarkets/btcmarkets_types.go index 43e29999..fc9c8f34 100644 --- a/exchanges/btcmarkets/btcmarkets_types.go +++ b/exchanges/btcmarkets/btcmarkets_types.go @@ -456,4 +456,4 @@ func (c *CandleResponse) UnmarshalJSON(data []byte) error { // WebsocketOrderbook defines a specific websocket orderbook type to directly // unmarshal json. -type WebsocketOrderbook orderbook.Tranches +type WebsocketOrderbook orderbook.Levels diff --git a/exchanges/btcmarkets/btcmarkets_websocket.go b/exchanges/btcmarkets/btcmarkets_websocket.go index 9255bf7b..4e185a88 100644 --- a/exchanges/btcmarkets/btcmarkets_websocket.go +++ b/exchanges/btcmarkets/btcmarkets_websocket.go @@ -95,7 +95,7 @@ func (w *WebsocketOrderbook) UnmarshalJSON(data []byte) error { return err } - *w = WebsocketOrderbook(make(orderbook.Tranches, len(resp))) + *w = WebsocketOrderbook(make(orderbook.Levels, len(resp))) for x := range resp { (*w)[x].Price = resp[x][0].Float64() (*w)[x].Amount = resp[x][1].Float64() @@ -123,10 +123,10 @@ func (b *BTCMarkets) wsHandleData(respRaw []byte) error { } if ob.Snapshot { - err = b.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err = b.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Pair: ob.Currency, - Bids: orderbook.Tranches(ob.Bids), - Asks: orderbook.Tranches(ob.Asks), + Bids: orderbook.Levels(ob.Bids), + Asks: orderbook.Levels(ob.Asks), LastUpdated: ob.Timestamp, LastUpdateID: ob.SnapshotID, Asset: asset.Spot, @@ -138,8 +138,8 @@ func (b *BTCMarkets) wsHandleData(respRaw []byte) error { UpdateTime: ob.Timestamp, UpdateID: ob.SnapshotID, Asset: asset.Spot, - Bids: orderbook.Tranches(ob.Bids), - Asks: orderbook.Tranches(ob.Asks), + Bids: orderbook.Levels(ob.Bids), + Asks: orderbook.Levels(ob.Asks), Pair: ob.Currency, Checksum: ob.Checksum, }) @@ -418,7 +418,7 @@ func (b *BTCMarkets) ReSubscribeSpecificOrderbook(pair currency.Pair) error { } // checksum provides assurance on current in memory liquidity -func checksum(ob *orderbook.Base, checksum uint32) error { +func checksum(ob *orderbook.Book, checksum uint32) error { check := crc32.ChecksumIEEE([]byte(concatOrderbookLiquidity(ob.Bids) + concatOrderbookLiquidity(ob.Asks))) if check != checksum { return fmt.Errorf("%s %s %s ID: %v expected: %v but received: %v %w", @@ -434,7 +434,7 @@ func checksum(ob *orderbook.Base, checksum uint32) error { } // concatOrderbookLiquidity concatenates price and amounts together for checksum processing -func concatOrderbookLiquidity(liquidity orderbook.Tranches) string { +func concatOrderbookLiquidity(liquidity orderbook.Levels) string { var c string for x := range min(10, len(liquidity)) { c += trim(liquidity[x].Price) + trim(liquidity[x].Amount) diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index f834d36b..cf9a7445 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -250,7 +250,7 @@ func (b *BTCMarkets) UpdateTicker(ctx context.Context, p currency.Pair, a asset. } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *BTCMarkets) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *BTCMarkets) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -258,7 +258,7 @@ func (b *BTCMarkets) UpdateOrderbook(ctx context.Context, p currency.Pair, asset return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -277,17 +277,17 @@ func (b *BTCMarkets) UpdateOrderbook(ctx context.Context, p currency.Pair, asset return book, err } - book.Bids = make(orderbook.Tranches, len(tempResp.Bids)) + book.Bids = make(orderbook.Levels, len(tempResp.Bids)) for x := range tempResp.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: tempResp.Bids[x].Volume, Price: tempResp.Bids[x].Price, } } - book.Asks = make(orderbook.Tranches, len(tempResp.Asks)) + book.Asks = make(orderbook.Levels, len(tempResp.Asks)) for y := range tempResp.Asks { - book.Asks[y] = orderbook.Tranche{ + book.Asks[y] = orderbook.Level{ Amount: tempResp.Asks[y].Volume, Price: tempResp.Asks[y].Price, } diff --git a/exchanges/btse/btse_websocket.go b/exchanges/btse/btse_websocket.go index bfc302dc..96df0ab4 100644 --- a/exchanges/btse/btse_websocket.go +++ b/exchanges/btse/btse_websocket.go @@ -286,9 +286,9 @@ func (b *BTSE) wsHandleData(respRaw []byte) error { if err != nil { return err } - newOB := orderbook.Base{ - Bids: make(orderbook.Tranches, 0, len(t.Data.BuyQuote)), - Asks: make(orderbook.Tranches, 0, len(t.Data.SellQuote)), + newOB := orderbook.Book{ + Bids: make(orderbook.Levels, 0, len(t.Data.BuyQuote)), + Asks: make(orderbook.Levels, 0, len(t.Data.SellQuote)), } var price, amount float64 for i := range t.Data.SellQuote { @@ -305,7 +305,7 @@ func (b *BTSE) wsHandleData(respRaw []byte) error { if b.orderbookFilter(price, amount) { continue } - newOB.Asks = append(newOB.Asks, orderbook.Tranche{ + newOB.Asks = append(newOB.Asks, orderbook.Level{ Price: price, Amount: amount, }) @@ -324,7 +324,7 @@ func (b *BTSE) wsHandleData(respRaw []byte) error { if b.orderbookFilter(price, amount) { continue } - newOB.Bids = append(newOB.Bids, orderbook.Tranche{ + newOB.Bids = append(newOB.Bids, orderbook.Level{ Price: price, Amount: amount, }) diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index 7d5df7db..f2fde559 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -296,14 +296,14 @@ func (b *BTSE) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: b.Name, Pair: p, Asset: assetType, @@ -318,22 +318,22 @@ func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType a return book, err } - book.Bids = make(orderbook.Tranches, 0, len(a.BuyQuote)) + book.Bids = make(orderbook.Levels, 0, len(a.BuyQuote)) for x := range a.BuyQuote { if b.orderbookFilter(a.BuyQuote[x].Price, a.BuyQuote[x].Size) { continue } - book.Bids = append(book.Bids, orderbook.Tranche{ + book.Bids = append(book.Bids, orderbook.Level{ Price: a.BuyQuote[x].Price, Amount: a.BuyQuote[x].Size, }) } - book.Asks = make(orderbook.Tranches, 0, len(a.SellQuote)) + book.Asks = make(orderbook.Levels, 0, len(a.SellQuote)) for x := range a.SellQuote { if b.orderbookFilter(a.SellQuote[x].Price, a.SellQuote[x].Size) { continue } - book.Asks = append(book.Asks, orderbook.Tranche{ + book.Asks = append(book.Asks, orderbook.Level{ Price: a.SellQuote[x].Price, Amount: a.SellQuote[x].Size, }) diff --git a/exchanges/bybit/bybit.go b/exchanges/bybit/bybit.go index cd133bae..4d825a8a 100644 --- a/exchanges/bybit/bybit.go +++ b/exchanges/bybit/bybit.go @@ -2529,8 +2529,8 @@ func (by *Bybit) GetBrokerEarning(ctx context.Context, businessType, cursor stri return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/broker/earning-record", params, nil, &resp, defaultEPL) } -func processOB(ob [][2]types.Number) []orderbook.Tranche { - o := make([]orderbook.Tranche, len(ob)) +func processOB(ob [][2]types.Number) []orderbook.Level { + o := make([]orderbook.Level, len(ob)) for x := range ob { o[x].Price = ob[x][0].Float64() o[x].Amount = ob[x][1].Float64() diff --git a/exchanges/bybit/bybit_types.go b/exchanges/bybit/bybit_types.go index 666d51ca..85c26240 100644 --- a/exchanges/bybit/bybit_types.go +++ b/exchanges/bybit/bybit_types.go @@ -1741,8 +1741,8 @@ type ServerTime struct { // Orderbook stores the orderbook data type Orderbook struct { UpdateID int64 - Bids []orderbook.Tranche - Asks []orderbook.Tranche + Bids []orderbook.Level + Asks []orderbook.Level Symbol string GenerationTime time.Time } diff --git a/exchanges/bybit/bybit_websocket.go b/exchanges/bybit/bybit_websocket.go index c92b27f6..9f78d90d 100644 --- a/exchanges/bybit/bybit_websocket.go +++ b/exchanges/bybit/bybit_websocket.go @@ -707,20 +707,19 @@ func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketRespons if err != nil { return err } - - asks := make([]orderbook.Tranche, len(result.Asks)) + asks := make([]orderbook.Level, len(result.Asks)) for i := range result.Asks { asks[i].Price = result.Asks[i][0].Float64() asks[i].Amount = result.Asks[i][1].Float64() } - bids := make([]orderbook.Tranche, len(result.Bids)) + bids := make([]orderbook.Level, len(result.Bids)) for i := range result.Bids { bids[i].Price = result.Bids[i][0].Float64() bids[i].Amount = result.Bids[i][1].Float64() } if resp.Type == "snapshot" { - return by.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + return by.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Pair: cp, Exchange: by.Name, Asset: assetType, diff --git a/exchanges/bybit/bybit_wrapper.go b/exchanges/bybit/bybit_wrapper.go index 96dce64f..6389a185 100644 --- a/exchanges/bybit/bybit_wrapper.go +++ b/exchanges/bybit/bybit_wrapper.go @@ -477,7 +477,7 @@ func (by *Bybit) UpdateTicker(ctx context.Context, p currency.Pair, assetType as } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (by *Bybit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (by *Bybit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -506,22 +506,22 @@ func (by *Bybit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: by.Name, Pair: p, Asset: assetType, VerifyOrderbook: by.CanVerifyOrderbook, - Bids: make([]orderbook.Tranche, len(orderbookNew.Bids)), - Asks: make([]orderbook.Tranche, len(orderbookNew.Asks)), + Bids: make([]orderbook.Level, len(orderbookNew.Bids)), + Asks: make([]orderbook.Level, len(orderbookNew.Asks)), } for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price, } } for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price, } diff --git a/exchanges/coinbasepro/coinbasepro_websocket.go b/exchanges/coinbasepro/coinbasepro_websocket.go index ca6cc602..867da5ea 100644 --- a/exchanges/coinbasepro/coinbasepro_websocket.go +++ b/exchanges/coinbasepro/coinbasepro_websocket.go @@ -289,10 +289,10 @@ func (c *CoinbasePro) ProcessSnapshot(snapshot *WebsocketOrderbookSnapshot) erro return err } - ob := &orderbook.Base{ + ob := &orderbook.Book{ Pair: pair, - Bids: make(orderbook.Tranches, len(snapshot.Bids)), - Asks: make(orderbook.Tranches, len(snapshot.Asks)), + Bids: make(orderbook.Levels, len(snapshot.Bids)), + Asks: make(orderbook.Levels, len(snapshot.Asks)), Asset: asset.Spot, Exchange: c.Name, VerifyOrderbook: c.CanVerifyOrderbook, @@ -321,8 +321,8 @@ func (c *CoinbasePro) ProcessOrderbookUpdate(update *WebsocketL2Update) error { return err } - asks := make(orderbook.Tranches, 0, len(update.Changes)) - bids := make(orderbook.Tranches, 0, len(update.Changes)) + asks := make(orderbook.Levels, 0, len(update.Changes)) + bids := make(orderbook.Levels, 0, len(update.Changes)) for i := range update.Changes { price, err := strconv.ParseFloat(update.Changes[i][1], 64) @@ -334,9 +334,9 @@ func (c *CoinbasePro) ProcessOrderbookUpdate(update *WebsocketL2Update) error { return err } if update.Changes[i][0] == order.Buy.Lower() { - bids = append(bids, orderbook.Tranche{Price: price, Amount: volume}) + bids = append(bids, orderbook.Level{Price: price, Amount: volume}) } else { - asks = append(asks, orderbook.Tranche{Price: price, Amount: volume}) + asks = append(asks, orderbook.Level{Price: price, Amount: volume}) } } diff --git a/exchanges/coinbasepro/coinbasepro_wrapper.go b/exchanges/coinbasepro/coinbasepro_wrapper.go index 68d37e96..939540dc 100644 --- a/exchanges/coinbasepro/coinbasepro_wrapper.go +++ b/exchanges/coinbasepro/coinbasepro_wrapper.go @@ -300,14 +300,14 @@ func (c *CoinbasePro) UpdateTicker(ctx context.Context, p currency.Pair, a asset } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (c *CoinbasePro) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *CoinbasePro) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := c.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: c.Name, Pair: p, Asset: assetType, @@ -328,17 +328,17 @@ func (c *CoinbasePro) UpdateOrderbook(ctx context.Context, p currency.Pair, asse return book, common.GetTypeAssertError("OrderbookL1L2", orderbookNew) } - book.Bids = make(orderbook.Tranches, len(obNew.Bids)) + book.Bids = make(orderbook.Levels, len(obNew.Bids)) for x := range obNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: obNew.Bids[x].Amount, Price: obNew.Bids[x].Price, } } - book.Asks = make(orderbook.Tranches, len(obNew.Asks)) + book.Asks = make(orderbook.Levels, len(obNew.Asks)) for x := range obNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: obNew.Asks[x].Amount, Price: obNew.Asks[x].Price, } diff --git a/exchanges/coinut/coinut_websocket.go b/exchanges/coinut/coinut_websocket.go index 35498c77..511995f4 100644 --- a/exchanges/coinut/coinut_websocket.go +++ b/exchanges/coinut/coinut_websocket.go @@ -499,23 +499,23 @@ func (c *COINUT) WsGetInstruments() (Instruments, error) { // WsProcessOrderbookSnapshot processes the orderbook snapshot func (c *COINUT) WsProcessOrderbookSnapshot(ob *WsOrderbookSnapshot) error { - bids := make([]orderbook.Tranche, len(ob.Buy)) + bids := make([]orderbook.Level, len(ob.Buy)) for i := range ob.Buy { - bids[i] = orderbook.Tranche{ + bids[i] = orderbook.Level{ Amount: ob.Buy[i].Volume, Price: ob.Buy[i].Price, } } - asks := make([]orderbook.Tranche, len(ob.Sell)) + asks := make([]orderbook.Level, len(ob.Sell)) for i := range ob.Sell { - asks[i] = orderbook.Tranche{ + asks[i] = orderbook.Level{ Amount: ob.Sell[i].Volume, Price: ob.Sell[i].Price, } } - var newOrderBook orderbook.Base + var newOrderBook orderbook.Book newOrderBook.Asks = asks newOrderBook.Bids = bids newOrderBook.VerifyOrderbook = c.CanVerifyOrderbook @@ -572,9 +572,9 @@ func (c *COINUT) WsProcessOrderbookUpdate(update *WsOrderbookUpdate) error { UpdateTime: time.Now(), // No time sent } if strings.EqualFold(update.Side, order.Buy.Lower()) { - bufferUpdate.Bids = []orderbook.Tranche{{Price: update.Price, Amount: update.Volume}} + bufferUpdate.Bids = []orderbook.Level{{Price: update.Price, Amount: update.Volume}} } else { - bufferUpdate.Asks = []orderbook.Tranche{{Price: update.Price, Amount: update.Volume}} + bufferUpdate.Asks = []orderbook.Level{{Price: update.Price, Amount: update.Volume}} } return c.Websocket.Orderbook.Update(bufferUpdate) } diff --git a/exchanges/coinut/coinut_wrapper.go b/exchanges/coinut/coinut_wrapper.go index 257c5fde..c2699ff2 100644 --- a/exchanges/coinut/coinut_wrapper.go +++ b/exchanges/coinut/coinut_wrapper.go @@ -347,14 +347,14 @@ func (c *COINUT) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (c *COINUT) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *COINUT) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := c.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: c.Name, Pair: p, Asset: assetType, @@ -380,17 +380,17 @@ func (c *COINUT) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return book, err } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Buy)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Buy)) for x := range orderbookNew.Buy { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Buy[x].Quantity, Price: orderbookNew.Buy[x].Price, } } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Sell)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Sell)) for x := range orderbookNew.Sell { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Sell[x].Quantity, Price: orderbookNew.Sell[x].Price, } diff --git a/exchanges/deribit/deribit_websocket.go b/exchanges/deribit/deribit_websocket.go index 01b03d97..78e5b7cb 100644 --- a/exchanges/deribit/deribit_websocket.go +++ b/exchanges/deribit/deribit_websocket.go @@ -652,7 +652,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if err != nil { return err } - asks := make(orderbook.Tranches, 0, len(orderbookData.Asks)) + asks := make(orderbook.Levels, 0, len(orderbookData.Asks)) for x := range orderbookData.Asks { if len(orderbookData.Asks[x]) != 3 { return errMalformedData @@ -665,12 +665,12 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if !okay { return fmt.Errorf("%w, invalid amount", errMalformedData) } - asks = append(asks, orderbook.Tranche{ + asks = append(asks, orderbook.Level{ Price: price, Amount: amount, }) } - bids := make(orderbook.Tranches, 0, len(orderbookData.Bids)) + bids := make(orderbook.Levels, 0, len(orderbookData.Bids)) for x := range orderbookData.Bids { if len(orderbookData.Bids[x]) != 3 { return errMalformedData @@ -685,7 +685,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if !okay { return fmt.Errorf("%w, invalid amount", errMalformedData) } - bids = append(bids, orderbook.Tranche{ + bids = append(bids, orderbook.Level{ Price: price, Amount: amount, }) @@ -696,7 +696,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { switch orderbookData.Type { case "snapshot": - return d.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + return d.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Exchange: d.Name, VerifyOrderbook: d.CanVerifyOrderbook, LastUpdated: orderbookData.Timestamp.Time(), @@ -721,7 +721,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if err != nil { return err } - asks := make(orderbook.Tranches, 0, len(orderbookData.Asks)) + asks := make(orderbook.Levels, 0, len(orderbookData.Asks)) for x := range orderbookData.Asks { if len(orderbookData.Asks[x]) != 2 { return errMalformedData @@ -736,12 +736,12 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if !okay { return fmt.Errorf("%w, invalid amount", errMalformedData) } - asks = append(asks, orderbook.Tranche{ + asks = append(asks, orderbook.Level{ Price: price, Amount: amount, }) } - bids := make([]orderbook.Tranche, 0, len(orderbookData.Bids)) + bids := make([]orderbook.Level, 0, len(orderbookData.Bids)) for x := range orderbookData.Bids { if len(orderbookData.Bids[x]) != 2 { return errMalformedData @@ -756,7 +756,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if !okay { return fmt.Errorf("%w, invalid amount", errMalformedData) } - bids = append(bids, orderbook.Tranche{ + bids = append(bids, orderbook.Level{ Price: price, Amount: amount, }) @@ -764,7 +764,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if len(asks) == 0 && len(bids) == 0 { return nil } - return d.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + return d.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asks: asks, Bids: bids, Pair: cp, diff --git a/exchanges/deribit/deribit_wrapper.go b/exchanges/deribit/deribit_wrapper.go index b8d9b3f1..92c49e26 100644 --- a/exchanges/deribit/deribit_wrapper.go +++ b/exchanges/deribit/deribit_wrapper.go @@ -288,7 +288,7 @@ func (d *Deribit) UpdateTicker(ctx context.Context, p currency.Pair, assetType a } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (d *Deribit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (d *Deribit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { p, err := d.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -303,28 +303,28 @@ func (d *Deribit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp if err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: d.Name, Pair: p, Asset: assetType, VerifyOrderbook: d.CanVerifyOrderbook, } - book.Asks = make(orderbook.Tranches, 0, len(obData.Asks)) + book.Asks = make(orderbook.Levels, 0, len(obData.Asks)) for x := range obData.Asks { if obData.Asks[x][0] == 0 || obData.Asks[x][1] == 0 { continue } - book.Asks = append(book.Asks, orderbook.Tranche{ + book.Asks = append(book.Asks, orderbook.Level{ Price: obData.Asks[x][0], Amount: obData.Asks[x][1], }) } - book.Bids = make(orderbook.Tranches, 0, len(obData.Bids)) + book.Bids = make(orderbook.Levels, 0, len(obData.Bids)) for x := range obData.Bids { if obData.Bids[x][0] == 0 || obData.Bids[x][1] == 0 { continue } - book.Bids = append(book.Bids, orderbook.Tranche{ + book.Bids = append(book.Bids, orderbook.Level{ Price: obData.Bids[x][0], Amount: obData.Bids[x][1], }) diff --git a/exchanges/exchange.go b/exchanges/exchange.go index f3900991..728c3fc5 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -1918,9 +1918,9 @@ func (b *Base) GetCachedTicker(p currency.Pair, assetType asset.Item) (*ticker.P return ticker.GetTicker(b.Name, p, assetType) } -// GetCachedOrderbook returns orderbook base on the currency pair and asset type +// GetCachedOrderbook returns an orderbook snapshot for the currency pair and asset type // NOTE: UpdateOrderbook method must be called first to update the orderbook map -func (b *Base) GetCachedOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Base) GetCachedOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { return orderbook.Get(b.Name, p, assetType) } diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index 0f392dcc..2dfc2bc2 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -2678,7 +2678,7 @@ func TestGetCachedOrderbook(t *testing.T) { _, err := b.GetCachedOrderbook(pair, asset.Spot) assert.ErrorIs(t, err, orderbook.ErrOrderbookNotFound) - err = (&orderbook.Base{Exchange: "test", Pair: pair, Asset: asset.Spot}).Process() + err = (&orderbook.Book{Exchange: "test", Pair: pair, Asset: asset.Spot}).Process() assert.NoError(t, err) ob, err := b.GetCachedOrderbook(pair, asset.Spot) @@ -2754,7 +2754,7 @@ func (f *FakeBase) GetCachedAccountInfo(context.Context, asset.Item) (account.Ho return account.Holdings{}, nil } -func (f *FakeBase) GetCachedOrderbook(currency.Pair, asset.Item) (*orderbook.Base, error) { +func (f *FakeBase) GetCachedOrderbook(currency.Pair, asset.Item) (*orderbook.Book, error) { return nil, nil } @@ -2782,7 +2782,7 @@ func (f *FakeBase) UpdateTicker(context.Context, currency.Pair, asset.Item) (*ti return nil, nil } -func (f *FakeBase) UpdateOrderbook(context.Context, currency.Pair, asset.Item) (*orderbook.Base, error) { +func (f *FakeBase) UpdateOrderbook(context.Context, currency.Pair, asset.Item) (*orderbook.Book, error) { return nil, nil } diff --git a/exchanges/exmo/exmo_wrapper.go b/exchanges/exmo/exmo_wrapper.go index 850a688b..cd667fa8 100644 --- a/exchanges/exmo/exmo_wrapper.go +++ b/exchanges/exmo/exmo_wrapper.go @@ -203,14 +203,14 @@ func (e *EXMO) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (e *EXMO) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (e *EXMO) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - callingBook := &orderbook.Base{ + callingBook := &orderbook.Book{ Exchange: e.Name, Pair: p, Asset: assetType, @@ -232,7 +232,7 @@ func (e *EXMO) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType a } for i := range enabledPairs { - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: e.Name, Pair: enabledPairs[i], Asset: assetType, @@ -249,13 +249,13 @@ func (e *EXMO) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType a continue } - book.Asks = make(orderbook.Tranches, len(data.Asks)) + book.Asks = make(orderbook.Levels, len(data.Asks)) for y := range data.Asks { book.Asks[y].Price = data.Asks[y][0].Float64() book.Asks[y].Amount = data.Asks[y][1].Float64() } - book.Bids = make(orderbook.Tranches, len(data.Bids)) + book.Bids = make(orderbook.Levels, len(data.Bids)) for y := range data.Bids { book.Bids[y].Price = data.Bids[y][0].Float64() book.Bids[y].Amount = data.Bids[y][1].Float64() diff --git a/exchanges/gateio/gateio_types.go b/exchanges/gateio/gateio_types.go index e8c157a7..f14f2494 100644 --- a/exchanges/gateio/gateio_types.go +++ b/exchanges/gateio/gateio_types.go @@ -2212,12 +2212,12 @@ type WsFuturesAndOptionsOrderbookUpdate struct { ContractName currency.Pair `json:"s"` FirstUpdatedID int64 `json:"U"` LastUpdatedID int64 `json:"u"` - Bids []Tranche `json:"b"` - Asks []Tranche `json:"a"` + Bids []Level `json:"b"` + Asks []Level `json:"a"` } -// Tranche represents a tranche of orderbook data -type Tranche struct { +// Level represents a level of orderbook data +type Level struct { Price types.Number `json:"p"` Size float64 `json:"s"` } @@ -2227,8 +2227,8 @@ type WsFuturesOrderbookSnapshot struct { Timestamp types.Time `json:"t"` Contract currency.Pair `json:"contract"` OrderbookID int64 `json:"id"` - Asks []Tranche `json:"asks"` - Bids []Tranche `json:"bids"` + Asks []Level `json:"asks"` + Bids []Level `json:"bids"` } // WsFuturesOrderbookUpdateEvent represents futures orderbook push data with the event 'update' diff --git a/exchanges/gateio/gateio_websocket.go b/exchanges/gateio/gateio_websocket.go index 7433769b..e9afb4a4 100644 --- a/exchanges/gateio/gateio_websocket.go +++ b/exchanges/gateio/gateio_websocket.go @@ -358,14 +358,14 @@ func (g *Gateio) processOrderbookTicker(incoming []byte, lastPushed time.Time) e if err := json.Unmarshal(incoming, &data); err != nil { return err } - return g.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + return g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Exchange: g.Name, Pair: data.Pair, Asset: asset.Spot, LastUpdated: data.UpdateTime.Time(), LastPushed: lastPushed, - Bids: []orderbook.Tranche{{Price: data.BestBidPrice.Float64(), Amount: data.BestBidAmount.Float64()}}, - Asks: []orderbook.Tranche{{Price: data.BestAskPrice.Float64(), Amount: data.BestAskAmount.Float64()}}, + Bids: []orderbook.Level{{Price: data.BestBidPrice.Float64(), Amount: data.BestBidAmount.Float64()}}, + Asks: []orderbook.Level{{Price: data.BestAskPrice.Float64(), Amount: data.BestAskAmount.Float64()}}, }) } @@ -374,12 +374,12 @@ func (g *Gateio) processOrderbookUpdate(ctx context.Context, incoming []byte, la if err := json.Unmarshal(incoming, &data); err != nil { return err } - asks := make([]orderbook.Tranche, len(data.Asks)) + asks := make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { asks[x].Price = data.Asks[x][0].Float64() asks[x].Amount = data.Asks[x][1].Float64() } - bids := make([]orderbook.Tranche, len(data.Bids)) + bids := make([]orderbook.Level, len(data.Bids)) for x := range data.Bids { bids[x].Price = data.Bids[x][0].Float64() bids[x].Amount = data.Bids[x][1].Float64() @@ -402,12 +402,12 @@ func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) return err } - asks := make([]orderbook.Tranche, len(data.Asks)) + asks := make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { asks[x].Price = data.Asks[x][0].Float64() asks[x].Amount = data.Asks[x][1].Float64() } - bids := make([]orderbook.Tranche, len(data.Bids)) + bids := make([]orderbook.Level, len(data.Bids)) for x := range data.Bids { bids[x].Price = data.Bids[x][0].Float64() bids[x].Amount = data.Bids[x][1].Float64() @@ -415,7 +415,7 @@ func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) for _, a := range standardMarginAssetTypes { if enabled, _ := g.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled { - if err := g.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + if err := g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Exchange: g.Name, Pair: data.CurrencyPair, Asset: a, diff --git a/exchanges/gateio/gateio_websocket_futures.go b/exchanges/gateio/gateio_websocket_futures.go index 2a9fab79..601b40b6 100644 --- a/exchanges/gateio/gateio_websocket_futures.go +++ b/exchanges/gateio/gateio_websocket_futures.go @@ -411,12 +411,12 @@ func (g *Gateio) processFuturesOrderbookUpdate(ctx context.Context, incoming []b if err := json.Unmarshal(incoming, &data); err != nil { return err } - asks := make([]orderbook.Tranche, len(data.Asks)) + asks := make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { asks[x].Price = data.Asks[x].Price.Float64() asks[x].Amount = data.Asks[x].Size } - bids := make([]orderbook.Tranche, len(data.Bids)) + bids := make([]orderbook.Level, len(data.Bids)) for x := range data.Bids { bids[x].Price = data.Bids[x].Price.Float64() bids[x].Amount = data.Bids[x].Size @@ -441,7 +441,7 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, if err != nil { return err } - base := orderbook.Base{ + base := orderbook.Book{ Asset: assetType, Exchange: g.Name, Pair: data.Contract, @@ -449,12 +449,12 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, LastPushed: lastPushed, VerifyOrderbook: g.CanVerifyOrderbook, } - base.Asks = make([]orderbook.Tranche, len(data.Asks)) + base.Asks = make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { base.Asks[x].Amount = data.Asks[x].Size base.Asks[x].Price = data.Asks[x].Price.Float64() } - base.Bids = make([]orderbook.Tranche, len(data.Bids)) + base.Bids = make([]orderbook.Level, len(data.Bids)) for x := range data.Bids { base.Bids[x].Amount = data.Bids[x].Size base.Bids[x].Price = data.Bids[x].Price.Float64() @@ -466,19 +466,19 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, if err != nil { return err } - dataMap := map[string][2][]orderbook.Tranche{} + dataMap := map[string][2][]orderbook.Level{} for x := range data { ab, ok := dataMap[data[x].CurrencyPair] if !ok { - ab = [2][]orderbook.Tranche{} + ab = [2][]orderbook.Level{} } if data[x].Amount > 0 { - ab[1] = append(ab[1], orderbook.Tranche{ + ab[1] = append(ab[1], orderbook.Level{ Price: data[x].Price.Float64(), Amount: data[x].Amount, }) } else { - ab[0] = append(ab[0], orderbook.Tranche{ + ab[0] = append(ab[0], orderbook.Level{ Price: data[x].Price.Float64(), Amount: -data[x].Amount, }) @@ -495,7 +495,7 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, if err != nil { return err } - err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asks: ab[0], Bids: ab[1], Asset: assetType, diff --git a/exchanges/gateio/gateio_websocket_option.go b/exchanges/gateio/gateio_websocket_option.go index b27a408d..11f1f533 100644 --- a/exchanges/gateio/gateio_websocket_option.go +++ b/exchanges/gateio/gateio_websocket_option.go @@ -503,12 +503,12 @@ func (g *Gateio) processOptionsOrderbookUpdate(ctx context.Context, incoming []b if err := json.Unmarshal(incoming, &data); err != nil { return err } - asks := make([]orderbook.Tranche, len(data.Asks)) + asks := make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { asks[x].Price = data.Asks[x].Price.Float64() asks[x].Amount = data.Asks[x].Size } - bids := make([]orderbook.Tranche, len(data.Bids)) + bids := make([]orderbook.Level, len(data.Bids)) for x := range data.Bids { bids[x].Price = data.Bids[x].Price.Float64() bids[x].Amount = data.Bids[x].Size @@ -532,7 +532,7 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming if err != nil { return err } - base := orderbook.Base{ + base := orderbook.Book{ Asset: asset.Options, Exchange: g.Name, Pair: data.Contract, @@ -540,12 +540,12 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming LastPushed: lastPushed, VerifyOrderbook: g.CanVerifyOrderbook, } - base.Asks = make([]orderbook.Tranche, len(data.Asks)) + base.Asks = make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { base.Asks[x].Amount = data.Asks[x].Size base.Asks[x].Price = data.Asks[x].Price.Float64() } - base.Bids = make([]orderbook.Tranche, len(data.Bids)) + base.Bids = make([]orderbook.Level, len(data.Bids)) for x := range data.Bids { base.Bids[x].Amount = data.Bids[x].Size base.Bids[x].Price = data.Bids[x].Price.Float64() @@ -557,18 +557,18 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming if err != nil { return err } - dataMap := map[string][2][]orderbook.Tranche{} + dataMap := map[string][2][]orderbook.Level{} for x := range data { ab, ok := dataMap[data[x].CurrencyPair] if !ok { - ab = [2][]orderbook.Tranche{} + ab = [2][]orderbook.Level{} } if data[x].Amount > 0 { - ab[1] = append(ab[1], orderbook.Tranche{ + ab[1] = append(ab[1], orderbook.Level{ Price: data[x].Price.Float64(), Amount: data[x].Amount, }) } else { - ab[0] = append(ab[0], orderbook.Tranche{ + ab[0] = append(ab[0], orderbook.Level{ Price: data[x].Price.Float64(), Amount: -data[x].Amount, }) } @@ -584,7 +584,7 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming if err != nil { return err } - err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asks: ab[0], Bids: ab[1], Asset: asset.Options, diff --git a/exchanges/gateio/gateio_wrapper.go b/exchanges/gateio/gateio_wrapper.go index d97203f9..5ad159df 100644 --- a/exchanges/gateio/gateio_wrapper.go +++ b/exchanges/gateio/gateio_wrapper.go @@ -649,12 +649,12 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (g *Gateio) UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) { +func (g *Gateio) UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Book, error) { return g.UpdateOrderbookWithLimit(ctx, p, a, 0) } // UpdateOrderbookWithLimit updates and returns the orderbook for a currency pair with a set orderbook size limit -func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, a asset.Item, limit uint64) (*orderbook.Base, error) { +func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, a asset.Item, limit uint64) (*orderbook.Book, error) { p, err := g.FormatExchangeCurrency(p, a) if err != nil { return nil, err @@ -688,7 +688,7 @@ func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, if err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: g.Name, Asset: a, VerifyOrderbook: g.CanVerifyOrderbook, @@ -697,16 +697,16 @@ func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, LastUpdated: o.Update.Time(), LastPushed: o.Current.Time(), } - book.Bids = make(orderbook.Tranches, len(o.Bids)) + book.Bids = make(orderbook.Levels, len(o.Bids)) for x := range o.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: o.Bids[x].Amount.Float64(), Price: o.Bids[x].Price.Float64(), } } - book.Asks = make(orderbook.Tranches, len(o.Asks)) + book.Asks = make(orderbook.Levels, len(o.Asks)) for x := range o.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: o.Asks[x].Amount.Float64(), Price: o.Asks[x].Price.Float64(), } diff --git a/exchanges/gateio/ws_ob_update_manager_test.go b/exchanges/gateio/ws_ob_update_manager_test.go index 7c85f2de..0464188e 100644 --- a/exchanges/gateio/ws_ob_update_manager_test.go +++ b/exchanges/gateio/ws_ob_update_manager_test.go @@ -23,12 +23,12 @@ func TestProcessOrderbookUpdate(t *testing.T) { assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) pair := currency.NewPair(currency.BABY, currency.BABYDOGE) - err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Exchange: g.Name, Pair: pair, Asset: asset.USDTMarginedFutures, - Bids: []orderbook.Tranche{{Price: 1, Amount: 1}}, - Asks: []orderbook.Tranche{{Price: 1, Amount: 1}}, + Bids: []orderbook.Level{{Price: 1, Amount: 1}}, + Asks: []orderbook.Level{{Price: 1, Amount: 1}}, LastUpdated: time.Now(), LastPushed: time.Now(), LastUpdateID: 1336, @@ -145,12 +145,12 @@ func TestApplyPendingUpdates(t *testing.T) { m := newWsOBUpdateManager(defaultWSSnapshotSyncDelay) pair := currency.NewPair(currency.LTC, currency.USDT) - err := g.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err := g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Exchange: g.Name, Pair: pair, Asset: asset.USDTMarginedFutures, - Bids: []orderbook.Tranche{{Price: 1, Amount: 1}}, - Asks: []orderbook.Tranche{{Price: 1, Amount: 1}}, + Bids: []orderbook.Level{{Price: 1, Amount: 1}}, + Asks: []orderbook.Level{{Price: 1, Amount: 1}}, LastUpdated: time.Now(), LastPushed: time.Now(), LastUpdateID: 1335, diff --git a/exchanges/gemini/gemini_websocket.go b/exchanges/gemini/gemini_websocket.go index a1b59529..d105c7b3 100644 --- a/exchanges/gemini/gemini_websocket.go +++ b/exchanges/gemini/gemini_websocket.go @@ -482,8 +482,8 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { return err } - bids := make([]orderbook.Tranche, 0, len(result.Changes)) - asks := make([]orderbook.Tranche, 0, len(result.Changes)) + bids := make([]orderbook.Level, 0, len(result.Changes)) + asks := make([]orderbook.Level, 0, len(result.Changes)) for x := range result.Changes { price, err := strconv.ParseFloat(result.Changes[x][1], 64) @@ -494,7 +494,7 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { if err != nil { return err } - obItem := orderbook.Tranche{ + obItem := orderbook.Level{ Amount: amount, Price: price, } @@ -506,7 +506,7 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { } if isInitial { - var newOrderBook orderbook.Base + var newOrderBook orderbook.Book newOrderBook.Asks = asks newOrderBook.Bids = bids newOrderBook.Asset = asset.Spot diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index fca95568..5461b106 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -287,14 +287,14 @@ func (g *Gemini) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (g *Gemini) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (g *Gemini) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := g.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: g.Name, Pair: p, Asset: assetType, @@ -310,17 +310,17 @@ func (g *Gemini) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return book, err } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price, } } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price, } diff --git a/exchanges/hitbtc/hitbtc_websocket.go b/exchanges/hitbtc/hitbtc_websocket.go index 68ddd663..d96df533 100644 --- a/exchanges/hitbtc/hitbtc_websocket.go +++ b/exchanges/hitbtc/hitbtc_websocket.go @@ -316,18 +316,18 @@ func (h *HitBTC) WsProcessOrderbookSnapshot(ob *WsOrderbook) error { return errors.New("no orderbooks to process") } - newOrderBook := orderbook.Base{ - Bids: make(orderbook.Tranches, len(ob.Params.Bid)), - Asks: make(orderbook.Tranches, len(ob.Params.Ask)), + newOrderBook := orderbook.Book{ + Bids: make(orderbook.Levels, len(ob.Params.Bid)), + Asks: make(orderbook.Levels, len(ob.Params.Ask)), } for i := range ob.Params.Bid { - newOrderBook.Bids[i] = orderbook.Tranche{ + newOrderBook.Bids[i] = orderbook.Level{ Amount: ob.Params.Bid[i].Size, Price: ob.Params.Bid[i].Price, } } for i := range ob.Params.Ask { - newOrderBook.Asks[i] = orderbook.Tranche{ + newOrderBook.Asks[i] = orderbook.Level{ Amount: ob.Params.Ask[i].Size, Price: ob.Params.Ask[i].Price, } @@ -439,17 +439,17 @@ func (h *HitBTC) WsProcessOrderbookUpdate(update *WsOrderbook) error { return nil } - bids := make(orderbook.Tranches, len(update.Params.Bid)) + bids := make(orderbook.Levels, len(update.Params.Bid)) for i := range update.Params.Bid { - bids[i] = orderbook.Tranche{ + bids[i] = orderbook.Level{ Price: update.Params.Bid[i].Price, Amount: update.Params.Bid[i].Size, } } - asks := make(orderbook.Tranches, len(update.Params.Ask)) + asks := make(orderbook.Levels, len(update.Params.Ask)) for i := range update.Params.Ask { - asks[i] = orderbook.Tranche{ + asks[i] = orderbook.Level{ Price: update.Params.Ask[i].Price, Amount: update.Params.Ask[i].Size, } diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index 52b38be3..f2771b6d 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -261,14 +261,14 @@ func (h *HitBTC) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (h *HitBTC) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (h *HitBTC) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if c.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := h.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: h.Name, Pair: c, Asset: assetType, @@ -284,16 +284,16 @@ func (h *HitBTC) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType return book, err } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price, } } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price, } diff --git a/exchanges/huobi/huobi_websocket.go b/exchanges/huobi/huobi_websocket.go index ff8e9532..376ee27b 100644 --- a/exchanges/huobi/huobi_websocket.go +++ b/exchanges/huobi/huobi_websocket.go @@ -296,7 +296,7 @@ func (h *HUOBI) wsHandleOrderbookMsg(s *subscription.Subscription, respRaw []byt if err := json.Unmarshal(respRaw, &update); err != nil { return err } - bids := make(orderbook.Tranches, len(update.Tick.Bids)) + bids := make(orderbook.Levels, len(update.Tick.Bids)) for i := range update.Tick.Bids { price, ok := update.Tick.Bids[i][0].(float64) if !ok { @@ -306,13 +306,13 @@ func (h *HUOBI) wsHandleOrderbookMsg(s *subscription.Subscription, respRaw []byt if !ok { return errors.New("unable to type assert bid amount") } - bids[i] = orderbook.Tranche{ + bids[i] = orderbook.Level{ Price: price, Amount: amount, } } - asks := make(orderbook.Tranches, len(update.Tick.Asks)) + asks := make(orderbook.Levels, len(update.Tick.Asks)) for i := range update.Tick.Asks { price, ok := update.Tick.Asks[i][0].(float64) if !ok { @@ -322,13 +322,13 @@ func (h *HUOBI) wsHandleOrderbookMsg(s *subscription.Subscription, respRaw []byt if !ok { return errors.New("unable to type assert ask amount") } - asks[i] = orderbook.Tranche{ + asks[i] = orderbook.Level{ Price: price, Amount: amount, } } - var newOrderBook orderbook.Base + var newOrderBook orderbook.Book newOrderBook.Asks = asks newOrderBook.Bids = bids newOrderBook.Pair = s.Pairs[0] diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index c804a954..cf93196a 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -547,14 +547,14 @@ func (h *HUOBI) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if !assetType.IsValid() { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: h.Name, Pair: p, Asset: assetType, @@ -573,16 +573,16 @@ func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return book, err } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x][1], Price: orderbookNew.Bids[x][0], } } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x][1], Price: orderbookNew.Asks[x][0], } @@ -595,16 +595,16 @@ func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return book, err } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Asks[x].Quantity, Price: orderbookNew.Asks[x].Price, } } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Bids)) for y := range orderbookNew.Bids { - book.Bids[y] = orderbook.Tranche{ + book.Bids[y] = orderbook.Level{ Amount: orderbookNew.Bids[y].Quantity, Price: orderbookNew.Bids[y].Price, } @@ -617,17 +617,17 @@ func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return book, err } - book.Asks = make(orderbook.Tranches, len(orderbookNew.Tick.Asks)) + book.Asks = make(orderbook.Levels, len(orderbookNew.Tick.Asks)) for x := range orderbookNew.Tick.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderbookNew.Tick.Asks[x][1], Price: orderbookNew.Tick.Asks[x][0], } } - book.Bids = make(orderbook.Tranches, len(orderbookNew.Tick.Bids)) + book.Bids = make(orderbook.Levels, len(orderbookNew.Tick.Bids)) for y := range orderbookNew.Tick.Bids { - book.Bids[y] = orderbook.Tranche{ + book.Bids[y] = orderbook.Level{ Amount: orderbookNew.Tick.Bids[y][1], Price: orderbookNew.Tick.Bids[y][0], } diff --git a/exchanges/interfaces.go b/exchanges/interfaces.go index 2ecc503d..24614322 100644 --- a/exchanges/interfaces.go +++ b/exchanges/interfaces.go @@ -45,8 +45,8 @@ type IBotExchange interface { GetCachedTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) UpdateTickers(ctx context.Context, a asset.Item) error - GetCachedOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) - UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) + GetCachedOrderbook(p currency.Pair, a asset.Item) (*orderbook.Book, error) + UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Book, error) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error GetEnabledPairs(a asset.Item) (currency.Pairs, error) diff --git a/exchanges/kraken/kraken_test.go b/exchanges/kraken/kraken_test.go index 2d1dea2e..339a4c2b 100644 --- a/exchanges/kraken/kraken_test.go +++ b/exchanges/kraken/kraken_test.go @@ -1370,8 +1370,8 @@ func TestGetHistoricTrades(t *testing.T) { assert.ErrorIs(t, err, common.ErrFunctionNotSupported, "GetHistoricTrades should error") } -var testOb = orderbook.Base{ - Asks: []orderbook.Tranche{ +var testOb = orderbook.Book{ + Asks: []orderbook.Level{ // NOTE: 0.00000500 float64 == 0.000005 {Price: 0.05005, StrPrice: "0.05005", Amount: 0.00000500, StrAmount: "0.00000500"}, {Price: 0.05010, StrPrice: "0.05010", Amount: 0.00000500, StrAmount: "0.00000500"}, @@ -1384,7 +1384,7 @@ var testOb = orderbook.Base{ {Price: 0.05045, StrPrice: "0.05045", Amount: 0.00000500, StrAmount: "0.00000500"}, {Price: 0.05050, StrPrice: "0.05050", Amount: 0.00000500, StrAmount: "0.00000500"}, }, - Bids: []orderbook.Tranche{ + Bids: []orderbook.Level{ {Price: 0.05000, StrPrice: "0.05000", Amount: 0.00000500, StrAmount: "0.00000500"}, {Price: 0.04995, StrPrice: "0.04995", Amount: 0.00000500, StrAmount: "0.00000500"}, {Price: 0.04990, StrPrice: "0.04990", Amount: 0.00000500, StrAmount: "0.00000500"}, @@ -1494,7 +1494,7 @@ func TestWsOrderbookMax10Depth(t *testing.T) { err := k.wsHandleData([]byte(websocketLUNAEUROrderbookUpdates[x])) // TODO: Known issue with LUNA pairs and big number float precision // storage and checksum calc. Might need to store raw strings as fields - // in the orderbook.Tranche struct. + // in the orderbook.Level struct. // Required checksum: 7465000014735432016076747100005084881400000007476000097005027047670474990000293338023886300750000004333333333333375020000152914844934167507000014652990542161752500007370728572000475400000670061645671407546000098022663603417745900007102987806720745800001593557686404000745200003375861179634000743500003156650585902777434000030172726079999999743200006461149653837000743100001042285966000000074300000403660461058200074200000369021657320475740500001674242117790510 if x != len(websocketLUNAEUROrderbookUpdates)-1 { require.NoError(t, err, "wsHandleData must not error") diff --git a/exchanges/kraken/kraken_websocket.go b/exchanges/kraken/kraken_websocket.go index 973cb788..c6cc8b2d 100644 --- a/exchanges/kraken/kraken_websocket.go +++ b/exchanges/kraken/kraken_websocket.go @@ -666,12 +666,12 @@ func (k *Kraken) wsProcessOrderBook(c string, response []any, pair currency.Pair // wsProcessOrderBookPartial creates a new orderbook entry for a given currency pair func (k *Kraken) wsProcessOrderBookPartial(pair currency.Pair, askData, bidData []any, levels int) error { - base := orderbook.Base{ + base := orderbook.Book{ Pair: pair, Asset: asset.Spot, VerifyOrderbook: k.CanVerifyOrderbook, - Bids: make(orderbook.Tranches, len(bidData)), - Asks: make(orderbook.Tranches, len(askData)), + Bids: make(orderbook.Levels, len(bidData)), + Asks: make(orderbook.Levels, len(askData)), MaxDepth: levels, ChecksumStringRequired: true, } @@ -711,7 +711,7 @@ func (k *Kraken) wsProcessOrderBookPartial(pair currency.Pair, askData, bidData if err != nil { return err } - base.Asks[i] = orderbook.Tranche{ + base.Asks[i] = orderbook.Level{ Amount: amount, StrAmount: amountStr, Price: price, @@ -756,7 +756,7 @@ func (k *Kraken) wsProcessOrderBookPartial(pair currency.Pair, askData, bidData return err } - base.Bids[i] = orderbook.Tranche{ + base.Bids[i] = orderbook.Level{ Amount: amount, StrAmount: amountStr, Price: price, @@ -778,8 +778,8 @@ func (k *Kraken) wsProcessOrderBookUpdate(pair currency.Pair, askData, bidData [ update := orderbook.Update{ Asset: asset.Spot, Pair: pair, - Bids: make([]orderbook.Tranche, len(bidData)), - Asks: make([]orderbook.Tranche, len(askData)), + Bids: make([]orderbook.Level, len(bidData)), + Asks: make([]orderbook.Level, len(askData)), } // Calculating checksum requires incoming decimal place checks for both @@ -824,7 +824,7 @@ func (k *Kraken) wsProcessOrderBookUpdate(pair currency.Pair, askData, bidData [ return err } - update.Asks[i] = orderbook.Tranche{ + update.Asks[i] = orderbook.Level{ Amount: amount, StrAmount: amountStr, Price: price, @@ -874,7 +874,7 @@ func (k *Kraken) wsProcessOrderBookUpdate(pair currency.Pair, askData, bidData [ return err } - update.Bids[i] = orderbook.Tranche{ + update.Bids[i] = orderbook.Level{ Amount: amount, StrAmount: amountStr, Price: price, @@ -906,7 +906,7 @@ func (k *Kraken) wsProcessOrderBookUpdate(pair currency.Pair, askData, bidData [ return validateCRC32(book, uint32(token)) } -func validateCRC32(b *orderbook.Base, token uint32) error { +func validateCRC32(b *orderbook.Book, token uint32) error { if b == nil { return common.ErrNilPointer } diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index 2b76e0b5..9ae15a7d 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -451,14 +451,14 @@ func (k *Kraken) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := k.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: k.Name, Pair: p, Asset: assetType, @@ -472,16 +472,16 @@ func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - book.Bids = make([]orderbook.Tranche, len(orderbookNew.Bids)) + book.Bids = make([]orderbook.Level, len(orderbookNew.Bids)) for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderbookNew.Bids[x].Amount.Float64(), Price: orderbookNew.Bids[x].Price.Float64(), } } - book.Asks = make([]orderbook.Tranche, len(orderbookNew.Asks)) + book.Asks = make([]orderbook.Level, len(orderbookNew.Asks)) for y := range orderbookNew.Asks { - book.Asks[y] = orderbook.Tranche{ + book.Asks[y] = orderbook.Level{ Amount: orderbookNew.Asks[y].Amount.Float64(), Price: orderbookNew.Asks[y].Price.Float64(), } @@ -492,16 +492,16 @@ func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - book.Asks = make([]orderbook.Tranche, len(futuresOB.Orderbook.Asks)) + book.Asks = make([]orderbook.Level, len(futuresOB.Orderbook.Asks)) for x := range futuresOB.Orderbook.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Price: futuresOB.Orderbook.Asks[x][0], Amount: futuresOB.Orderbook.Asks[x][1], } } - book.Bids = make([]orderbook.Tranche, len(futuresOB.Orderbook.Bids)) + book.Bids = make([]orderbook.Level, len(futuresOB.Orderbook.Bids)) for y := range futuresOB.Orderbook.Bids { - book.Bids[y] = orderbook.Tranche{ + book.Bids[y] = orderbook.Level{ Price: futuresOB.Orderbook.Bids[y][0], Amount: futuresOB.Orderbook.Bids[y][1], } diff --git a/exchanges/kucoin/kucoin.go b/exchanges/kucoin/kucoin.go index a8b5dd2b..2ac8f027 100644 --- a/exchanges/kucoin/kucoin.go +++ b/exchanges/kucoin/kucoin.go @@ -98,9 +98,9 @@ func (ku *Kucoin) GetMarketList(ctx context.Context) ([]string, error) { return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, marketListEPL, "/v1/markets", &resp) } -// processOB constructs an orderbook.Tranche instances from slice of numbers. -func processOB(ob [][2]types.Number) []orderbook.Tranche { - o := make([]orderbook.Tranche, len(ob)) +// processOB constructs an orderbook.Level instances from slice of numbers. +func processOB(ob [][2]types.Number) []orderbook.Level { + o := make([]orderbook.Level, len(ob)) for x := range ob { o[x].Amount = ob[x][1].Float64() o[x].Price = ob[x][0].Float64() diff --git a/exchanges/kucoin/kucoin_futures.go b/exchanges/kucoin/kucoin_futures.go index 974e45e8..b6f87109 100644 --- a/exchanges/kucoin/kucoin_futures.go +++ b/exchanges/kucoin/kucoin_futures.go @@ -824,10 +824,10 @@ func (ku *Kucoin) GetFuturesTransferOutList(ctx context.Context, ccy currency.Co return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTransferOutListEPL, http.MethodGet, common.EncodeURLValues("/v1/transfer-list", params), nil, &resp) } -func processFuturesOB(ob [][2]float64) []orderbook.Tranche { - o := make([]orderbook.Tranche, len(ob)) +func processFuturesOB(ob [][2]float64) []orderbook.Level { + o := make([]orderbook.Level, len(ob)) for x := range ob { - o[x] = orderbook.Tranche{ + o[x] = orderbook.Level{ Price: ob[x][0], Amount: ob[x][1], } diff --git a/exchanges/kucoin/kucoin_test.go b/exchanges/kucoin/kucoin_test.go index 20ba655c..36075f7b 100644 --- a/exchanges/kucoin/kucoin_test.go +++ b/exchanges/kucoin/kucoin_test.go @@ -2065,7 +2065,7 @@ func TestFetchTradablePairs(t *testing.T) { func TestUpdateOrderbook(t *testing.T) { t.Parallel() - var result *orderbook.Base + var result *orderbook.Book var err error for assetType, tp := range assertToTradablePairMap { result, err = ku.UpdateOrderbook(t.Context(), tp, assetType) diff --git a/exchanges/kucoin/kucoin_types.go b/exchanges/kucoin/kucoin_types.go index 20de283b..9ac2be6e 100644 --- a/exchanges/kucoin/kucoin_types.go +++ b/exchanges/kucoin/kucoin_types.go @@ -156,8 +156,8 @@ type Stats24hrs struct { // Orderbook stores the orderbook data type Orderbook struct { Sequence int64 - Bids []orderbook.Tranche - Asks []orderbook.Tranche + Bids []orderbook.Level + Asks []orderbook.Level Time time.Time } @@ -1565,11 +1565,11 @@ type WsFuturesExecutionData struct { // WsOrderbookLevel5 represents an orderbook push data with depth level 5 type WsOrderbookLevel5 struct { - Sequence int64 `json:"sequence"` - Asks []orderbook.Tranche `json:"asks"` - Bids []orderbook.Tranche `json:"bids"` - PushTimestamp types.Time `json:"ts"` - Timestamp types.Time `json:"timestamp"` + Sequence int64 `json:"sequence"` + Asks []orderbook.Level `json:"asks"` + Bids []orderbook.Level `json:"bids"` + PushTimestamp types.Time `json:"ts"` + Timestamp types.Time `json:"timestamp"` } // WsOrderbookLevel5Response represents a response data for an orderbook push data with depth level 5 @@ -1588,16 +1588,16 @@ func (a *WsOrderbookLevel5Response) ExtractOrderbookItems() *WsOrderbookLevel5 { Sequence: a.Sequence, PushTimestamp: a.PushTimestamp, } - resp.Asks = make([]orderbook.Tranche, len(a.Asks)) + resp.Asks = make([]orderbook.Level, len(a.Asks)) for x := range a.Asks { - resp.Asks[x] = orderbook.Tranche{ + resp.Asks[x] = orderbook.Level{ Price: a.Asks[x][0].Float64(), Amount: a.Asks[x][1].Float64(), } } - resp.Bids = make([]orderbook.Tranche, len(a.Bids)) + resp.Bids = make([]orderbook.Level, len(a.Bids)) for x := range a.Bids { - resp.Bids[x] = orderbook.Tranche{ + resp.Bids[x] = orderbook.Level{ Price: a.Bids[x][0].Float64(), Amount: a.Bids[x][1].Float64(), } diff --git a/exchanges/kucoin/kucoin_websocket.go b/exchanges/kucoin/kucoin_websocket.go index 4e27798b..2cf60241 100644 --- a/exchanges/kucoin/kucoin_websocket.go +++ b/exchanges/kucoin/kucoin_websocket.go @@ -957,13 +957,13 @@ func (ku *Kucoin) processOrderbook(respData []byte, symbol, topic string) error return err } - asks := make([]orderbook.Tranche, len(response.Asks)) + asks := make([]orderbook.Level, len(response.Asks)) for x := range response.Asks { asks[x].Price = response.Asks[x][0].Float64() asks[x].Amount = response.Asks[x][1].Float64() } - bids := make([]orderbook.Tranche, len(response.Bids)) + bids := make([]orderbook.Level, len(response.Bids)) for x := range response.Bids { bids[x].Price = response.Bids[x][0].Float64() bids[x].Amount = response.Bids[x][1].Float64() @@ -979,7 +979,7 @@ func (ku *Kucoin) processOrderbook(respData []byte, symbol, topic string) error lastUpdatedTime = time.Now() } for x := range assets { - err = ku.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err = ku.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Exchange: ku.Name, Asks: asks, Bids: bids, @@ -1161,21 +1161,21 @@ func (ku *Kucoin) setupOrderbookManager() { // processOrderbookUpdate processes the websocket orderbook update func (ku *Kucoin) processOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WsOrderbook) error { - updateBid := make([]orderbook.Tranche, len(ws.Changes.Bids)) + updateBid := make([]orderbook.Level, len(ws.Changes.Bids)) for i := range ws.Changes.Bids { var sequence int64 if len(ws.Changes.Bids[i]) > 2 { sequence = ws.Changes.Bids[i][2].Int64() } - updateBid[i] = orderbook.Tranche{Price: ws.Changes.Bids[i][0].Float64(), Amount: ws.Changes.Bids[i][1].Float64(), ID: sequence} + updateBid[i] = orderbook.Level{Price: ws.Changes.Bids[i][0].Float64(), Amount: ws.Changes.Bids[i][1].Float64(), ID: sequence} } - updateAsk := make([]orderbook.Tranche, len(ws.Changes.Asks)) + updateAsk := make([]orderbook.Level, len(ws.Changes.Asks)) for i := range ws.Changes.Asks { var sequence int64 if len(ws.Changes.Asks[i]) > 2 { sequence = ws.Changes.Asks[i][2].Int64() } - updateAsk[i] = orderbook.Tranche{Price: ws.Changes.Asks[i][0].Float64(), Amount: ws.Changes.Asks[i][1].Float64(), ID: sequence} + updateAsk[i] = orderbook.Level{Price: ws.Changes.Asks[i][0].Float64(), Amount: ws.Changes.Asks[i][1].Float64(), ID: sequence} } return ku.Websocket.Orderbook.Update(&orderbook.Update{ @@ -1290,24 +1290,24 @@ func (ku *Kucoin) SeedLocalCache(ctx context.Context, p currency.Pair, assetType // SeedLocalCacheWithBook seeds the local orderbook cache func (ku *Kucoin) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *Orderbook, assetType asset.Item) error { - newOrderBook := orderbook.Base{ + newOrderBook := orderbook.Book{ Pair: p, Asset: assetType, Exchange: ku.Name, LastUpdated: time.Now(), LastUpdateID: orderbookNew.Sequence, VerifyOrderbook: ku.CanVerifyOrderbook, - Bids: make(orderbook.Tranches, len(orderbookNew.Bids)), - Asks: make(orderbook.Tranches, len(orderbookNew.Asks)), + Bids: make(orderbook.Levels, len(orderbookNew.Bids)), + Asks: make(orderbook.Levels, len(orderbookNew.Asks)), } for i := range orderbookNew.Bids { - newOrderBook.Bids[i] = orderbook.Tranche{ + newOrderBook.Bids[i] = orderbook.Level{ Amount: orderbookNew.Bids[i].Amount, Price: orderbookNew.Bids[i].Price, } } for i := range orderbookNew.Asks { - newOrderBook.Asks[i] = orderbook.Tranche{ + newOrderBook.Asks[i] = orderbook.Level{ Amount: orderbookNew.Asks[i].Amount, Price: orderbookNew.Asks[i].Price, } @@ -1511,7 +1511,7 @@ func (o *orderbookManager) FetchBookViaREST(pair currency.Pair, assetType asset. } } -func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(currency.Pair, asset.Item, *WsOrderbook) error, pair currency.Pair, assetType asset.Item, recent *orderbook.Base) error { +func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(currency.Pair, asset.Item, *WsOrderbook) error, pair currency.Pair, assetType asset.Item, recent *orderbook.Book) error { o.Lock() defer o.Unlock() state, ok := o.state[pair.Base][pair.Quote][assetType] @@ -1545,7 +1545,7 @@ buffer: } // Validate checks for correct update alignment -func (u *update) Validate(updt *WsOrderbook, recent *orderbook.Base) (bool, error) { +func (u *update) Validate(updt *WsOrderbook, recent *orderbook.Book) (bool, error) { if updt.SequenceEnd <= recent.LastUpdateID { // Drop any event where u is <= lastUpdateId in the snapshot. return false, nil diff --git a/exchanges/kucoin/kucoin_wrapper.go b/exchanges/kucoin/kucoin_wrapper.go index 13118c50..ea487f8a 100644 --- a/exchanges/kucoin/kucoin_wrapper.go +++ b/exchanges/kucoin/kucoin_wrapper.go @@ -372,7 +372,7 @@ func (ku *Kucoin) UpdateTickers(ctx context.Context, assetType asset.Item) error } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (ku *Kucoin) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (ku *Kucoin) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { err := ku.CurrencyPairs.IsAssetEnabled(assetType) if err != nil { return nil, err @@ -394,7 +394,7 @@ func (ku *Kucoin) UpdateOrderbook(ctx context.Context, pair currency.Pair, asset return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: ku.Name, Pair: pair, Asset: assetType, diff --git a/exchanges/lbank/lbank_wrapper.go b/exchanges/lbank/lbank_wrapper.go index c79ec78b..7dfdbb95 100644 --- a/exchanges/lbank/lbank_wrapper.go +++ b/exchanges/lbank/lbank_wrapper.go @@ -196,7 +196,7 @@ func (l *Lbank) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (l *Lbank) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (l *Lbank) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if !l.SupportsAsset(assetType) { return nil, fmt.Errorf("%w: %q", asset.ErrNotSupported, assetType) } @@ -211,13 +211,13 @@ func (l *Lbank) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: l.Name, Pair: p, Asset: assetType, VerifyOrderbook: l.CanVerifyOrderbook, - Asks: make(orderbook.Tranches, len(d.Data.Asks)), - Bids: make(orderbook.Tranches, len(d.Data.Bids)), + Asks: make(orderbook.Levels, len(d.Data.Asks)), + Bids: make(orderbook.Levels, len(d.Data.Bids)), } for i := range d.Data.Asks { diff --git a/exchanges/okx/okx_test.go b/exchanges/okx/okx_test.go index 3eb3b139..dfb86f7a 100644 --- a/exchanges/okx/okx_test.go +++ b/exchanges/okx/okx_test.go @@ -3905,7 +3905,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { func TestCalculateUpdateOrderbookChecksum(t *testing.T) { t.Parallel() - var orderbookBase orderbook.Base + var orderbookBase orderbook.Book err := json.Unmarshal([]byte(calculateOrderbookChecksumUpdateOrderbookJSON), &orderbookBase) require.NoError(t, err) diff --git a/exchanges/okx/okx_types.go b/exchanges/okx/okx_types.go index 6d116870..a6fe4ccf 100644 --- a/exchanges/okx/okx_types.go +++ b/exchanges/okx/okx_types.go @@ -4458,8 +4458,8 @@ func (a *WsSpreadOrderbook) ExtractSpreadOrder() (*WsSpreadOrderbookData, error) } for x := range a.Data { resp.Data[x].Timestamp = a.Data[x].Timestamp.Time() - resp.Data[x].Asks = make([]orderbook.Tranche, len(a.Data[x].Asks)) - resp.Data[x].Bids = make([]orderbook.Tranche, len(a.Data[x].Bids)) + resp.Data[x].Asks = make([]orderbook.Level, len(a.Data[x].Asks)) + resp.Data[x].Bids = make([]orderbook.Level, len(a.Data[x].Bids)) for as := range a.Data[x].Asks { resp.Data[x].Asks[as].Price = a.Data[x].Asks[as][0].Float64() @@ -4477,8 +4477,8 @@ func (a *WsSpreadOrderbook) ExtractSpreadOrder() (*WsSpreadOrderbookData, error) // WsSpreadOrderbookItem represents an orderbook asks and bids details type WsSpreadOrderbookItem struct { - Asks []orderbook.Tranche - Bids []orderbook.Tranche + Asks []orderbook.Level + Bids []orderbook.Level Timestamp time.Time } diff --git a/exchanges/okx/okx_websocket.go b/exchanges/okx/okx_websocket.go index 9e4e6174..3d39b19b 100644 --- a/exchanges/okx/okx_websocket.go +++ b/exchanges/okx/okx_websocket.go @@ -834,7 +834,7 @@ func (ok *Okx) wsProcessSpreadOrderbook(respRaw []byte) error { return err } for x := range extractedResponse.Data { - err = ok.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err = ok.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asset: asset.Spread, Asks: extractedResponse.Data[x].Asks, Bids: extractedResponse.Data[x].Bids, @@ -867,20 +867,20 @@ func (ok *Okx) wsProcessOrderbook5(data []byte) error { return err } - asks := make([]orderbook.Tranche, len(resp.Data[0].Asks)) + asks := make([]orderbook.Level, len(resp.Data[0].Asks)) for x := range resp.Data[0].Asks { asks[x].Price = resp.Data[0].Asks[x][0].Float64() asks[x].Amount = resp.Data[0].Asks[x][1].Float64() } - bids := make([]orderbook.Tranche, len(resp.Data[0].Bids)) + bids := make([]orderbook.Level, len(resp.Data[0].Bids)) for x := range resp.Data[0].Bids { bids[x].Price = resp.Data[0].Bids[x][0].Float64() bids[x].Amount = resp.Data[0].Bids[x][1].Float64() } for x := range assets { - err = ok.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ + err = ok.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asset: assets[x], Asks: asks, Bids: bids, @@ -1013,7 +1013,7 @@ func (ok *Okx) WsProcessSnapshotOrderBook(data *WsOrderBookData, pair currency.P return err } for i := range assets { - newOrderBook := orderbook.Base{ + newOrderBook := orderbook.Book{ Asset: assets[i], Asks: asks, Bids: bids, @@ -1060,10 +1060,10 @@ func (ok *Okx) WsProcessUpdateOrderbook(data *WsOrderBookData, pair currency.Pai } // AppendWsOrderbookItems adds websocket orderbook data bid/asks into an orderbook item array -func (ok *Okx) AppendWsOrderbookItems(entries [][4]types.Number) (orderbook.Tranches, error) { - items := make(orderbook.Tranches, len(entries)) +func (ok *Okx) AppendWsOrderbookItems(entries [][4]types.Number) (orderbook.Levels, error) { + items := make(orderbook.Levels, len(entries)) for j := range entries { - items[j] = orderbook.Tranche{Amount: entries[j][1].Float64(), Price: entries[j][0].Float64()} + items[j] = orderbook.Level{Amount: entries[j][1].Float64(), Price: entries[j][0].Float64()} } return items, nil } @@ -1073,7 +1073,7 @@ func (ok *Okx) AppendWsOrderbookItems(entries [][4]types.Number) (orderbook.Tran // quantity with a semicolon (:) deliminating them. This will also work when // there are less than 25 entries (for whatever reason) // eg Bid:Ask:Bid:Ask:Ask:Ask -func (ok *Okx) CalculateUpdateOrderbookChecksum(orderbookData *orderbook.Base, checksumVal uint32) error { +func (ok *Okx) CalculateUpdateOrderbookChecksum(orderbookData *orderbook.Book, checksumVal uint32) error { var checksum strings.Builder for i := range allowableIterations { if len(orderbookData.Bids)-1 >= i { diff --git a/exchanges/okx/okx_wrapper.go b/exchanges/okx/okx_wrapper.go index 219366e6..9e4c2fdd 100644 --- a/exchanges/okx/okx_wrapper.go +++ b/exchanges/okx/okx_wrapper.go @@ -514,7 +514,7 @@ func (ok *Okx) UpdateTickers(ctx context.Context, assetType asset.Item) error { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -534,31 +534,31 @@ func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetTyp return nil, err } for y := range spreadOrderbook { - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: ok.Name, Pair: pair, Asset: assetType, VerifyOrderbook: ok.CanVerifyOrderbook, } - book.Bids = make(orderbook.Tranches, 0, len(spreadOrderbook[y].Bids)) + book.Bids = make(orderbook.Levels, 0, len(spreadOrderbook[y].Bids)) for b := range spreadOrderbook[y].Bids { // Skip order book bid depths where the price value is zero. if spreadOrderbook[y].Bids[b][0].Float64() == 0 { continue } - book.Bids = append(book.Bids, orderbook.Tranche{ + book.Bids = append(book.Bids, orderbook.Level{ Price: spreadOrderbook[y].Bids[b][0].Float64(), Amount: spreadOrderbook[y].Bids[b][1].Float64(), OrderCount: spreadOrderbook[y].Bids[b][2].Int64(), }) } - book.Asks = make(orderbook.Tranches, 0, len(spreadOrderbook[y].Asks)) + book.Asks = make(orderbook.Levels, 0, len(spreadOrderbook[y].Asks)) for a := range spreadOrderbook[y].Asks { // Skip order book ask depths where the price value is zero. if spreadOrderbook[y].Asks[a][0].Float64() == 0 { continue } - book.Asks = append(book.Asks, orderbook.Tranche{ + book.Asks = append(book.Asks, orderbook.Level{ Price: spreadOrderbook[y].Asks[a][0].Float64(), Amount: spreadOrderbook[y].Asks[a][1].Float64(), OrderCount: spreadOrderbook[y].Asks[a][2].Int64(), @@ -583,7 +583,7 @@ func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetTyp return nil, currency.ErrCurrencyPairsEmpty } instrumentID = pairFormat.Format(pair) - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: ok.Name, Pair: pair, Asset: assetType, @@ -595,16 +595,16 @@ func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetTyp return book, err } - book.Bids = make(orderbook.Tranches, len(orderBookD.Bids)) + book.Bids = make(orderbook.Levels, len(orderBookD.Bids)) for x := range orderBookD.Bids { - book.Bids[x] = orderbook.Tranche{ + book.Bids[x] = orderbook.Level{ Amount: orderBookD.Bids[x].Amount.Float64(), Price: orderBookD.Bids[x].DepthPrice.Float64(), } } - book.Asks = make(orderbook.Tranches, len(orderBookD.Asks)) + book.Asks = make(orderbook.Levels, len(orderBookD.Asks)) for x := range orderBookD.Asks { - book.Asks[x] = orderbook.Tranche{ + book.Asks[x] = orderbook.Level{ Amount: orderBookD.Asks[x].Amount.Float64(), Price: orderBookD.Asks[x].DepthPrice.Float64(), } diff --git a/exchanges/orderbook/calculator.go b/exchanges/orderbook/calculator.go index 8fa1123d..42bb77da 100644 --- a/exchanges/orderbook/calculator.go +++ b/exchanges/orderbook/calculator.go @@ -21,12 +21,12 @@ type WhaleBombResult struct { MinimumPrice float64 MaximumPrice float64 PercentageGainOrLoss float64 - Orders Tranches + Orders Levels Status string } // WhaleBomb finds the amount required to target a price -func (b *Base) WhaleBomb(priceTarget float64, buy bool) (*WhaleBombResult, error) { +func (b *Book) WhaleBomb(priceTarget float64, buy bool) (*WhaleBombResult, error) { if priceTarget < 0 { return nil, errPriceTargetInvalid } @@ -44,25 +44,25 @@ func (b *Base) WhaleBomb(priceTarget float64, buy bool) (*WhaleBombResult, error var percent, minPrice, maxPrice, amount float64 if buy { minPrice = action.ReferencePrice - maxPrice = action.TranchePositionPrice + maxPrice = action.LevelPositionPrice amount = action.QuoteAmount - percent = math.PercentageChange(action.ReferencePrice, action.TranchePositionPrice) - status = fmt.Sprintf("Buying using %.2f %s worth of %s will send the price from %v to %v [%.2f%%] and impact %d price tranche(s). %s", + percent = math.PercentageChange(action.ReferencePrice, action.LevelPositionPrice) + status = fmt.Sprintf("Buying using %.2f %s worth of %s will send the price from %v to %v [%.2f%%] and impact %d price level(s). %s", amount, b.Pair.Quote, b.Pair.Base, minPrice, maxPrice, - percent, len(action.Tranches), warning) + percent, len(action.Levels), warning) } else { - minPrice = action.TranchePositionPrice + minPrice = action.LevelPositionPrice maxPrice = action.ReferencePrice amount = action.BaseAmount - percent = math.PercentageChange(action.ReferencePrice, action.TranchePositionPrice) - status = fmt.Sprintf("Selling using %.2f %s worth of %s will send the price from %v to %v [%.2f%%] and impact %d price tranche(s). %s", + percent = math.PercentageChange(action.ReferencePrice, action.LevelPositionPrice) + status = fmt.Sprintf("Selling using %.2f %s worth of %s will send the price from %v to %v [%.2f%%] and impact %d price level(s). %s", amount, b.Pair.Base, b.Pair.Quote, maxPrice, minPrice, - percent, len(action.Tranches), warning) + percent, len(action.Levels), warning) } return &WhaleBombResult{ Amount: amount, - Orders: action.Tranches, + Orders: action.Levels, MinimumPrice: minPrice, MaximumPrice: maxPrice, Status: status, @@ -71,7 +71,7 @@ func (b *Base) WhaleBomb(priceTarget float64, buy bool) (*WhaleBombResult, error } // SimulateOrder simulates an order -func (b *Base) SimulateOrder(amount float64, buy bool) (*WhaleBombResult, error) { +func (b *Book) SimulateOrder(amount float64, buy bool) (*WhaleBombResult, error) { var direction string var action *DeploymentAction var soldAmount, boughtAmount, minimumPrice, maximumPrice float64 @@ -85,7 +85,7 @@ func (b *Base) SimulateOrder(amount float64, buy bool) (*WhaleBombResult, error) } soldAmount = action.QuoteAmount boughtAmount = action.BaseAmount - maximumPrice = action.TranchePositionPrice + maximumPrice = action.LevelPositionPrice minimumPrice = action.ReferencePrice sold = b.Pair.Quote bought = b.Pair.Base @@ -97,7 +97,7 @@ func (b *Base) SimulateOrder(amount float64, buy bool) (*WhaleBombResult, error) } soldAmount = action.BaseAmount boughtAmount = action.QuoteAmount - minimumPrice = action.TranchePositionPrice + minimumPrice = action.LevelPositionPrice maximumPrice = action.ReferencePrice sold = b.Pair.Base bought = b.Pair.Quote @@ -108,12 +108,12 @@ func (b *Base) SimulateOrder(amount float64, buy bool) (*WhaleBombResult, error) warning = fullLiquidityUsageWarning } - pct := math.PercentageChange(action.ReferencePrice, action.TranchePositionPrice) - status := fmt.Sprintf("%s using %f %v worth of %v will send the price from %v to %v [%.2f%%] and impact %v price tranche(s). %s", + pct := math.PercentageChange(action.ReferencePrice, action.LevelPositionPrice) + status := fmt.Sprintf("%s using %f %v worth of %v will send the price from %v to %v [%.2f%%] and impact %v price level(s). %s", direction, soldAmount, sold, bought, action.ReferencePrice, - action.TranchePositionPrice, pct, len(action.Tranches), warning) + action.LevelPositionPrice, pct, len(action.Levels), warning) return &WhaleBombResult{ - Orders: action.Tranches, + Orders: action.Levels, Amount: boughtAmount, MinimumPrice: minimumPrice, MaximumPrice: maximumPrice, @@ -122,7 +122,7 @@ func (b *Base) SimulateOrder(amount float64, buy bool) (*WhaleBombResult, error) }, nil } -func (b *Base) findAmount(priceTarget float64, buy bool) (*DeploymentAction, error) { +func (b *Book) findAmount(priceTarget float64, buy bool) (*DeploymentAction, error) { action := DeploymentAction{} if buy { if len(b.Asks) == 0 { @@ -135,14 +135,14 @@ func (b *Base) findAmount(priceTarget float64, buy bool) (*DeploymentAction, err } for x := range b.Asks { if b.Asks[x].Price >= priceTarget { - action.TranchePositionPrice = b.Asks[x].Price + action.LevelPositionPrice = b.Asks[x].Price return &action, nil } - action.Tranches = append(action.Tranches, b.Asks[x]) + action.Levels = append(action.Levels, b.Asks[x]) action.QuoteAmount += b.Asks[x].Price * b.Asks[x].Amount action.BaseAmount += b.Asks[x].Amount } - action.TranchePositionPrice = b.Asks[len(b.Asks)-1].Price + action.LevelPositionPrice = b.Asks[len(b.Asks)-1].Price action.FullLiquidityUsed = true return &action, nil } @@ -157,29 +157,29 @@ func (b *Base) findAmount(priceTarget float64, buy bool) (*DeploymentAction, err } for x := range b.Bids { if b.Bids[x].Price <= priceTarget { - action.TranchePositionPrice = b.Bids[x].Price + action.LevelPositionPrice = b.Bids[x].Price return &action, nil } - action.Tranches = append(action.Tranches, b.Bids[x]) + action.Levels = append(action.Levels, b.Bids[x]) action.QuoteAmount += b.Bids[x].Price * b.Bids[x].Amount action.BaseAmount += b.Bids[x].Amount } - action.TranchePositionPrice = b.Bids[len(b.Bids)-1].Price + action.LevelPositionPrice = b.Bids[len(b.Bids)-1].Price action.FullLiquidityUsed = true return &action, nil } // DeploymentAction defines deployment information on a liquidity side. type DeploymentAction struct { - ReferencePrice float64 - TranchePositionPrice float64 - BaseAmount float64 - QuoteAmount float64 - Tranches Tranches - FullLiquidityUsed bool + ReferencePrice float64 + LevelPositionPrice float64 + BaseAmount float64 + QuoteAmount float64 + Levels Levels + FullLiquidityUsed bool } -func (b *Base) buy(quote float64) (*DeploymentAction, error) { +func (b *Book) buy(quote float64) (*DeploymentAction, error) { if quote <= 0 { return nil, errQuoteAmountInvalid } @@ -188,23 +188,20 @@ func (b *Base) buy(quote float64) (*DeploymentAction, error) { } action := &DeploymentAction{ReferencePrice: b.Asks[0].Price} for x := range b.Asks { - action.TranchePositionPrice = b.Asks[x].Price - trancheValue := b.Asks[x].Price * b.Asks[x].Amount - action.QuoteAmount += trancheValue - remaining := quote - trancheValue + action.LevelPositionPrice = b.Asks[x].Price + levelValue := b.Asks[x].Price * b.Asks[x].Amount + action.QuoteAmount += levelValue + remaining := quote - levelValue if remaining <= 0 { if remaining == 0 { if len(b.Asks)-1 > x { - action.TranchePositionPrice = b.Asks[x+1].Price + action.LevelPositionPrice = b.Asks[x+1].Price } else { action.FullLiquidityUsed = true } } subAmount := quote / b.Asks[x].Price - action.Tranches = append(action.Tranches, Tranche{ - Price: b.Asks[x].Price, - Amount: subAmount, - }) + action.Levels = append(action.Levels, Level{Price: b.Asks[x].Price, Amount: subAmount}) action.BaseAmount += subAmount return action, nil } @@ -213,13 +210,13 @@ func (b *Base) buy(quote float64) (*DeploymentAction, error) { } quote = remaining action.BaseAmount += b.Asks[x].Amount - action.Tranches = append(action.Tranches, b.Asks[x]) + action.Levels = append(action.Levels, b.Asks[x]) } return action, nil } -func (b *Base) sell(base float64) (*DeploymentAction, error) { +func (b *Book) sell(base float64) (*DeploymentAction, error) { if base <= 0 { return nil, errBaseAmountInvalid } @@ -228,20 +225,17 @@ func (b *Base) sell(base float64) (*DeploymentAction, error) { } action := &DeploymentAction{ReferencePrice: b.Bids[0].Price} for x := range b.Bids { - action.TranchePositionPrice = b.Bids[x].Price + action.LevelPositionPrice = b.Bids[x].Price remaining := base - b.Bids[x].Amount if remaining <= 0 { if remaining == 0 { if len(b.Bids)-1 > x { - action.TranchePositionPrice = b.Bids[x+1].Price + action.LevelPositionPrice = b.Bids[x+1].Price } else { action.FullLiquidityUsed = true } } - action.Tranches = append(action.Tranches, Tranche{ - Price: b.Bids[x].Price, - Amount: base, - }) + action.Levels = append(action.Levels, Level{Price: b.Bids[x].Price, Amount: base}) action.BaseAmount += base action.QuoteAmount += base * b.Bids[x].Price return action, nil @@ -252,7 +246,7 @@ func (b *Base) sell(base float64) (*DeploymentAction, error) { base = remaining action.BaseAmount += b.Bids[x].Amount action.QuoteAmount += b.Bids[x].Amount * b.Bids[x].Price - action.Tranches = append(action.Tranches, b.Bids[x]) + action.Levels = append(action.Levels, b.Bids[x]) } return action, nil } @@ -260,7 +254,7 @@ func (b *Base) sell(base float64) (*DeploymentAction, error) { // GetAveragePrice finds the average buy or sell price of a specified amount. // It finds the nominal amount spent on the total purchase or sell and uses it // to find the average price for an individual unit bought or sold -func (b *Base) GetAveragePrice(buy bool, amount float64) (float64, error) { +func (b *Book) GetAveragePrice(buy bool, amount float64) (float64, error) { if amount <= 0 { return 0, errAmountInvalid } @@ -279,16 +273,16 @@ func (b *Base) GetAveragePrice(buy bool, amount float64) (float64, error) { // FindNominalAmount finds the nominal amount spent in terms of the quote // If the orderbook doesn't have enough liquidity it returns a non zero // remaining amount value -func (ts Tranches) FindNominalAmount(amount float64) (aggNominalAmount, remainingAmount float64) { +func (l Levels) FindNominalAmount(amount float64) (aggNominalAmount, remainingAmount float64) { remainingAmount = amount - for x := range ts { - if remainingAmount <= ts[x].Amount { - aggNominalAmount += ts[x].Price * remainingAmount + for x := range l { + if remainingAmount <= l[x].Amount { + aggNominalAmount += l[x].Price * remainingAmount remainingAmount = 0 break } - aggNominalAmount += ts[x].Price * ts[x].Amount - remainingAmount -= ts[x].Amount + aggNominalAmount += l[x].Price * l[x].Amount + remainingAmount -= l[x].Amount } return aggNominalAmount, remainingAmount } diff --git a/exchanges/orderbook/calculator_test.go b/exchanges/orderbook/calculator_test.go index 67b1cbc0..ec37e53d 100644 --- a/exchanges/orderbook/calculator_test.go +++ b/exchanges/orderbook/calculator_test.go @@ -10,18 +10,12 @@ import ( "github.com/thrasher-corp/gocryptotrader/currency" ) -func testSetup() Base { - return Base{ +func testSetup() Book { + return Book{ Exchange: "a", Pair: currency.NewBTCUSD(), - Asks: []Tranche{ - {Price: 7000, Amount: 1}, - {Price: 7001, Amount: 2}, - }, - Bids: []Tranche{ - {Price: 6999, Amount: 1}, - {Price: 6998, Amount: 2}, - }, + Asks: []Level{{Price: 7000, Amount: 1}, {Price: 7001, Amount: 2}}, + Bids: []Level{{Price: 6999, Amount: 1}, {Price: 6998, Amount: 2}}, } } @@ -51,7 +45,7 @@ func TestWhaleBomb(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", result.PercentageGainOrLoss, 0.014285714285714287) } - result, err = b.WhaleBomb(7000.5, true) // <- Slot between prices will lift to next ask tranche + result, err = b.WhaleBomb(7000.5, true) // <- Slot between prices will lift to next ask level assert.NoError(t, err) if result.Amount != 7000 { @@ -121,7 +115,7 @@ func TestWhaleBomb(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", result.PercentageGainOrLoss, -0.014287755393627661) } - result, err = b.WhaleBomb(6998.5, false) // <- Slot between prices will drop to next bid tranche + result, err = b.WhaleBomb(6998.5, false) // <- Slot between prices will drop to next bid level assert.NoError(t, err) if result.Amount != 1 { @@ -178,7 +172,7 @@ func TestSimulateOrder(t *testing.T) { _, err := b.SimulateOrder(-8000, true) require.ErrorIs(t, err, errQuoteAmountInvalid) - _, err = (&Base{}).SimulateOrder(1337, true) + _, err = (&Book{}).SimulateOrder(1337, true) require.ErrorIs(t, err, errNoLiquidity) // Full liquidity used @@ -229,7 +223,7 @@ func TestSimulateOrder(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", len(result.Orders), 2) } - // First tranche + // First level result, err = b.SimulateOrder(7000, true) require.NoError(t, err) @@ -241,7 +235,7 @@ func TestSimulateOrder(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", result.MinimumPrice, 7000) } - if result.MaximumPrice != 7001 { // A full tranche is wiped out and this one should be preserved. + if result.MaximumPrice != 7001 { // A full level is wiped out and this one should be preserved. t.Fatalf("received: '%v' but expected: '%v'", result.MaximumPrice, 7001) } @@ -281,7 +275,7 @@ func TestSimulateOrder(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", result.Orders[0].Amount, 0.5) } - // Half of second tranche + // Half of second level result, err = b.SimulateOrder(14001, true) require.NoError(t, err) @@ -313,10 +307,10 @@ func TestSimulateOrder(t *testing.T) { // Invalid - _, err = (&Base{}).SimulateOrder(-1, false) + _, err = (&Book{}).SimulateOrder(-1, false) require.ErrorIs(t, err, errBaseAmountInvalid) - _, err = (&Base{}).SimulateOrder(2, false) + _, err = (&Book{}).SimulateOrder(2, false) require.ErrorIs(t, err, errNoLiquidity) // Full liquidity used @@ -367,7 +361,7 @@ func TestSimulateOrder(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", len(result.Orders), 2) } - // First tranche + // First level result, err = b.SimulateOrder(1, false) require.NoError(t, err) @@ -379,7 +373,7 @@ func TestSimulateOrder(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", result.MaximumPrice, 6999) } - if result.MinimumPrice != 6998 { // A full tranche is wiped out and this one should be preserved. + if result.MinimumPrice != 6998 { // A full level is wiped out and this one should be preserved. t.Fatalf("received: '%v' but expected: '%v'", result.MinimumPrice, 6998) } @@ -419,7 +413,7 @@ func TestSimulateOrder(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", result.Orders[0].Amount, 0.5) } - // Half of second tranche + // Half of second level result, err = b.SimulateOrder(2, false) require.NoError(t, err) @@ -449,15 +443,15 @@ func TestSimulateOrder(t *testing.T) { } func TestGetAveragePrice(t *testing.T) { - b := Base{ + b := Book{ Exchange: "Binance", Pair: currency.NewBTCUSD(), } _, err := b.GetAveragePrice(false, 5) assert.ErrorIs(t, err, errNotEnoughLiquidity) - b = Base{ - Asks: []Tranche{ + b = Book{ + Asks: []Level{ {Amount: 5, Price: 1}, {Amount: 5, Price: 2}, {Amount: 5, Price: 3}, @@ -480,7 +474,7 @@ func TestGetAveragePrice(t *testing.T) { } func TestFindNominalAmount(t *testing.T) { - b := Tranches{ + b := Levels{ {Amount: 5, Price: 1}, {Amount: 5, Price: 2}, {Amount: 5, Price: 3}, @@ -490,7 +484,7 @@ func TestFindNominalAmount(t *testing.T) { if nomAmt != 30 && remainingAmt != 0 { t.Errorf("invalid return") } - b = Tranches{} + b = Levels{} nomAmt, remainingAmt = b.FindNominalAmount(15) if nomAmt != 0 && remainingAmt != 30 { t.Errorf("invalid return") diff --git a/exchanges/orderbook/depth.go b/exchanges/orderbook/depth.go index f2620eb5..c2bc09e1 100644 --- a/exchanges/orderbook/depth.go +++ b/exchanges/orderbook/depth.go @@ -30,13 +30,13 @@ var ( // Outbound restricts outbound usage of depth. NOTE: Type assert to // *orderbook.Depth. type Outbound interface { - Retrieve() (*Base, error) + Retrieve() (*Book, error) } -// Depth defines a store of orderbook tranches +// Depth defines a store of orderbook Levels type Depth struct { - askTranches - bidTranches + askLevels + bidLevels alert.Notice @@ -63,17 +63,17 @@ func (d *Depth) Publish() { } } -// Retrieve returns the orderbook base a copy of the underlying linked list +// Retrieve returns a snapshot of the orderbook // spread -func (d *Depth) Retrieve() (*Base, error) { +func (d *Depth) Retrieve() (*Book, error) { d.m.RLock() defer d.m.RUnlock() if d.validationError != nil { return nil, d.validationError } - return &Base{ - Bids: d.bidTranches.retrieve(0), - Asks: d.askTranches.retrieve(0), + return &Book{ + Bids: d.bidLevels.retrieve(0), + Asks: d.askLevels.retrieve(0), Exchange: d.exchange, Asset: d.asset, Pair: d.pair, @@ -92,23 +92,19 @@ func (d *Depth) Retrieve() (*Base, error) { } // LoadSnapshot flushes the bids and asks with a snapshot -func (d *Depth) LoadSnapshot(bids, asks []Tranche, lastUpdateID int64, lastUpdated, lastPushed time.Time, updateByREST bool) error { +func (d *Depth) LoadSnapshot(bids, asks []Level, lastUpdateID int64, lastUpdated, lastPushed time.Time, updateByREST bool) error { d.m.Lock() defer d.m.Unlock() if lastUpdated.IsZero() { - return fmt.Errorf("%s %s %s %w", - d.exchange, - d.pair, - d.asset, - errLastUpdatedNotSet) + return fmt.Errorf("%s %s %s %w", d.exchange, d.pair, d.asset, errLastUpdatedNotSet) } d.lastUpdateID = lastUpdateID d.lastUpdated = lastUpdated d.lastPushed = lastPushed d.insertedAt = time.Now() d.restSnapshot = updateByREST - d.bidTranches.load(bids) - d.askTranches.load(asks) + d.bidLevels.load(bids) + d.askLevels.load(asks) d.validationError = nil d.Alert() return nil @@ -119,13 +115,9 @@ func (d *Depth) LoadSnapshot(bids, asks []Tranche, lastUpdateID int64, lastUpdat func (d *Depth) invalidate(withReason error) error { d.lastUpdateID = 0 d.lastUpdated = time.Time{} - d.bidTranches.load(nil) - d.askTranches.load(nil) - d.validationError = fmt.Errorf("%s %s %s Reason: [%w]", - d.exchange, - d.pair, - d.asset, - common.AppendError(ErrOrderbookInvalid, withReason)) + d.bidLevels.load(nil) + d.askLevels.load(nil) + d.validationError = fmt.Errorf("%s %s %s Reason: [%w]", d.exchange, d.pair, d.asset, common.AppendError(ErrOrderbookInvalid, withReason)) d.Alert() return d.validationError } @@ -151,17 +143,13 @@ func (d *Depth) UpdateBidAskByPrice(update *Update) error { d.m.Lock() defer d.m.Unlock() if update.UpdateTime.IsZero() { - return fmt.Errorf("%s %s %s %w", - d.exchange, - d.pair, - d.asset, - errLastUpdatedNotSet) + return fmt.Errorf("%s %s %s %w", d.exchange, d.pair, d.asset, errLastUpdatedNotSet) } if len(update.Bids) != 0 { - d.bidTranches.updateInsertByPrice(update.Bids, d.options.maxDepth) + d.bidLevels.updateInsertByPrice(update.Bids, d.options.maxDepth) } if len(update.Asks) != 0 { - d.askTranches.updateInsertByPrice(update.Asks, d.options.maxDepth) + d.askLevels.updateInsertByPrice(update.Asks, d.options.maxDepth) } d.updateAndAlert(update) return nil @@ -173,21 +161,17 @@ func (d *Depth) UpdateBidAskByID(update *Update) error { defer d.m.Unlock() if update.UpdateTime.IsZero() { - return fmt.Errorf("%s %s %s %w", - d.exchange, - d.pair, - d.asset, - errLastUpdatedNotSet) + return fmt.Errorf("%s %s %s %w", d.exchange, d.pair, d.asset, errLastUpdatedNotSet) } if len(update.Bids) != 0 { - err := d.bidTranches.updateByID(update.Bids) + err := d.bidLevels.updateByID(update.Bids) if err != nil { return d.invalidate(err) } } if len(update.Asks) != 0 { - err := d.askTranches.updateByID(update.Asks) + err := d.askLevels.updateByID(update.Asks) if err != nil { return d.invalidate(err) } @@ -201,20 +185,16 @@ func (d *Depth) DeleteBidAskByID(update *Update, bypassErr bool) error { d.m.Lock() defer d.m.Unlock() if update.UpdateTime.IsZero() { - return fmt.Errorf("%s %s %s %w", - d.exchange, - d.pair, - d.asset, - errLastUpdatedNotSet) + return fmt.Errorf("%s %s %s %w", d.exchange, d.pair, d.asset, errLastUpdatedNotSet) } if len(update.Bids) != 0 { - err := d.bidTranches.deleteByID(update.Bids, bypassErr) + err := d.bidLevels.deleteByID(update.Bids, bypassErr) if err != nil { return d.invalidate(err) } } if len(update.Asks) != 0 { - err := d.askTranches.deleteByID(update.Asks, bypassErr) + err := d.askLevels.deleteByID(update.Asks, bypassErr) if err != nil { return d.invalidate(err) } @@ -228,20 +208,16 @@ func (d *Depth) InsertBidAskByID(update *Update) error { d.m.Lock() defer d.m.Unlock() if update.UpdateTime.IsZero() { - return fmt.Errorf("%s %s %s %w", - d.exchange, - d.pair, - d.asset, - errLastUpdatedNotSet) + return fmt.Errorf("%s %s %s %w", d.exchange, d.pair, d.asset, errLastUpdatedNotSet) } if len(update.Bids) != 0 { - err := d.bidTranches.insertUpdates(update.Bids) + err := d.bidLevels.insertUpdates(update.Bids) if err != nil { return d.invalidate(err) } } if len(update.Asks) != 0 { - err := d.askTranches.insertUpdates(update.Asks) + err := d.askLevels.insertUpdates(update.Asks) if err != nil { return d.invalidate(err) } @@ -255,20 +231,16 @@ func (d *Depth) UpdateInsertByID(update *Update) error { d.m.Lock() defer d.m.Unlock() if update.UpdateTime.IsZero() { - return fmt.Errorf("%s %s %s %w", - d.exchange, - d.pair, - d.asset, - errLastUpdatedNotSet) + return fmt.Errorf("%s %s %s %w", d.exchange, d.pair, d.asset, errLastUpdatedNotSet) } if len(update.Bids) != 0 { - err := d.bidTranches.updateInsertByID(update.Bids) + err := d.bidLevels.updateInsertByID(update.Bids) if err != nil { return d.invalidate(err) } } if len(update.Asks) != 0 { - err := d.askTranches.updateInsertByID(update.Asks) + err := d.askLevels.updateInsertByID(update.Asks) if err != nil { return d.invalidate(err) } @@ -278,7 +250,7 @@ func (d *Depth) UpdateInsertByID(update *Update) error { } // AssignOptions assigns the initial options for the depth instance -func (d *Depth) AssignOptions(b *Base) { +func (d *Depth) AssignOptions(b *Book) { d.m.Lock() d.options = options{ exchange: b.Exchange, @@ -345,7 +317,7 @@ func (d *Depth) GetAskLength() (int, error) { if d.validationError != nil { return 0, d.validationError } - return len(d.askTranches.Tranches), nil + return len(d.askLevels.Levels), nil } // GetBidLength returns length of bids @@ -355,7 +327,7 @@ func (d *Depth) GetBidLength() (int, error) { if d.validationError != nil { return 0, d.validationError } - return len(d.bidTranches.Tranches), nil + return len(d.bidLevels.Levels), nil } // TotalBidAmounts returns the total amount of bids and the total orderbook @@ -366,7 +338,7 @@ func (d *Depth) TotalBidAmounts() (liquidity, value float64, err error) { if d.validationError != nil { return 0, 0, d.validationError } - liquidity, value = d.bidTranches.amount() + liquidity, value = d.bidLevels.amount() return liquidity, value, nil } @@ -378,7 +350,7 @@ func (d *Depth) TotalAskAmounts() (liquidity, value float64, err error) { if d.validationError != nil { return 0, 0, d.validationError } - liquidity, value = d.askTranches.amount() + liquidity, value = d.askLevels.amount() return liquidity, value, nil } @@ -401,7 +373,7 @@ func (d *Depth) HitTheBidsByNominalSlippage(maxSlippage, refPrice float64) (*Mov if d.validationError != nil { return nil, d.validationError } - return d.bidTranches.hitBidsByNominalSlippage(maxSlippage, refPrice) + return d.bidLevels.hitBidsByNominalSlippage(maxSlippage, refPrice) } // HitTheBidsByNominalSlippageFromMid hits the bids by the required nominal @@ -417,7 +389,7 @@ func (d *Depth) HitTheBidsByNominalSlippageFromMid(maxSlippage float64) (*Moveme if err != nil { return nil, err } - return d.bidTranches.hitBidsByNominalSlippage(maxSlippage, mid) + return d.bidLevels.hitBidsByNominalSlippage(maxSlippage, mid) } // HitTheBidsByNominalSlippageFromBest hits the bids by the required nominal @@ -429,11 +401,11 @@ func (d *Depth) HitTheBidsByNominalSlippageFromBest(maxSlippage float64) (*Movem if d.validationError != nil { return nil, d.validationError } - head, err := d.bidTranches.getHeadPriceNoLock() + head, err := d.bidLevels.getHeadPriceNoLock() if err != nil { return nil, err } - return d.bidTranches.hitBidsByNominalSlippage(maxSlippage, head) + return d.bidLevels.hitBidsByNominalSlippage(maxSlippage, head) } // LiftTheAsksByNominalSlippage lifts the asks by the required nominal slippage @@ -445,7 +417,7 @@ func (d *Depth) LiftTheAsksByNominalSlippage(maxSlippage, refPrice float64) (*Mo if d.validationError != nil { return nil, d.validationError } - return d.askTranches.liftAsksByNominalSlippage(maxSlippage, refPrice) + return d.askLevels.liftAsksByNominalSlippage(maxSlippage, refPrice) } // LiftTheAsksByNominalSlippageFromMid lifts the asks by the required nominal @@ -461,7 +433,7 @@ func (d *Depth) LiftTheAsksByNominalSlippageFromMid(maxSlippage float64) (*Movem if err != nil { return nil, err } - return d.askTranches.liftAsksByNominalSlippage(maxSlippage, mid) + return d.askLevels.liftAsksByNominalSlippage(maxSlippage, mid) } // LiftTheAsksByNominalSlippageFromBest lifts the asks by the required nominal @@ -473,11 +445,11 @@ func (d *Depth) LiftTheAsksByNominalSlippageFromBest(maxSlippage float64) (*Move if d.validationError != nil { return nil, d.validationError } - head, err := d.askTranches.getHeadPriceNoLock() + head, err := d.askLevels.getHeadPriceNoLock() if err != nil { return nil, err } - return d.askTranches.liftAsksByNominalSlippage(maxSlippage, head) + return d.askLevels.liftAsksByNominalSlippage(maxSlippage, head) } // HitTheBidsByImpactSlippage hits the bids by the required impact slippage @@ -489,7 +461,7 @@ func (d *Depth) HitTheBidsByImpactSlippage(maxSlippage, refPrice float64) (*Move if d.validationError != nil { return nil, d.validationError } - return d.bidTranches.hitBidsByImpactSlippage(maxSlippage, refPrice) + return d.bidLevels.hitBidsByImpactSlippage(maxSlippage, refPrice) } // HitTheBidsByImpactSlippageFromMid hits the bids by the required impact @@ -505,7 +477,7 @@ func (d *Depth) HitTheBidsByImpactSlippageFromMid(maxSlippage float64) (*Movemen if err != nil { return nil, err } - return d.bidTranches.hitBidsByImpactSlippage(maxSlippage, mid) + return d.bidLevels.hitBidsByImpactSlippage(maxSlippage, mid) } // HitTheBidsByImpactSlippageFromBest hits the bids by the required impact @@ -517,11 +489,11 @@ func (d *Depth) HitTheBidsByImpactSlippageFromBest(maxSlippage float64) (*Moveme if d.validationError != nil { return nil, d.validationError } - head, err := d.bidTranches.getHeadPriceNoLock() + head, err := d.bidLevels.getHeadPriceNoLock() if err != nil { return nil, err } - return d.bidTranches.hitBidsByImpactSlippage(maxSlippage, head) + return d.bidLevels.hitBidsByImpactSlippage(maxSlippage, head) } // LiftTheAsksByImpactSlippage lifts the asks by the required impact slippage @@ -533,7 +505,7 @@ func (d *Depth) LiftTheAsksByImpactSlippage(maxSlippage, refPrice float64) (*Mov if d.validationError != nil { return nil, d.validationError } - return d.askTranches.liftAsksByImpactSlippage(maxSlippage, refPrice) + return d.askLevels.liftAsksByImpactSlippage(maxSlippage, refPrice) } // LiftTheAsksByImpactSlippageFromMid lifts the asks by the required impact @@ -549,7 +521,7 @@ func (d *Depth) LiftTheAsksByImpactSlippageFromMid(maxSlippage float64) (*Moveme if err != nil { return nil, err } - return d.askTranches.liftAsksByImpactSlippage(maxSlippage, mid) + return d.askLevels.liftAsksByImpactSlippage(maxSlippage, mid) } // LiftTheAsksByImpactSlippageFromBest lifts the asks by the required impact @@ -561,11 +533,11 @@ func (d *Depth) LiftTheAsksByImpactSlippageFromBest(maxSlippage float64) (*Movem if d.validationError != nil { return nil, d.validationError } - head, err := d.askTranches.getHeadPriceNoLock() + head, err := d.askLevels.getHeadPriceNoLock() if err != nil { return nil, err } - return d.askTranches.liftAsksByImpactSlippage(maxSlippage, head) + return d.askLevels.liftAsksByImpactSlippage(maxSlippage, head) } // HitTheBids derives full orderbook slippage information from reference price @@ -578,9 +550,9 @@ func (d *Depth) HitTheBids(amount, refPrice float64, purchase bool) (*Movement, return nil, d.validationError } if purchase { - return d.bidTranches.getMovementByQuotation(amount, refPrice, false) + return d.bidLevels.getMovementByQuotation(amount, refPrice, false) } - return d.bidTranches.getMovementByBase(amount, refPrice, false) + return d.bidLevels.getMovementByBase(amount, refPrice, false) } // HitTheBidsFromMid derives full orderbook slippage information from mid price @@ -597,9 +569,9 @@ func (d *Depth) HitTheBidsFromMid(amount float64, purchase bool) (*Movement, err return nil, err } if purchase { - return d.bidTranches.getMovementByQuotation(amount, mid, false) + return d.bidLevels.getMovementByQuotation(amount, mid, false) } - return d.bidTranches.getMovementByBase(amount, mid, false) + return d.bidLevels.getMovementByBase(amount, mid, false) } // HitTheBidsFromBest derives full orderbook slippage information from best bid @@ -611,14 +583,14 @@ func (d *Depth) HitTheBidsFromBest(amount float64, purchase bool) (*Movement, er if d.validationError != nil { return nil, d.validationError } - head, err := d.bidTranches.getHeadPriceNoLock() + head, err := d.bidLevels.getHeadPriceNoLock() if err != nil { return nil, err } if purchase { - return d.bidTranches.getMovementByQuotation(amount, head, false) + return d.bidLevels.getMovementByQuotation(amount, head, false) } - return d.bidTranches.getMovementByBase(amount, head, false) + return d.bidLevels.getMovementByBase(amount, head, false) } // LiftTheAsks derives full orderbook slippage information from reference price @@ -631,9 +603,9 @@ func (d *Depth) LiftTheAsks(amount, refPrice float64, purchase bool) (*Movement, return nil, d.validationError } if purchase { - return d.askTranches.getMovementByBase(amount, refPrice, true) + return d.askLevels.getMovementByBase(amount, refPrice, true) } - return d.askTranches.getMovementByQuotation(amount, refPrice, true) + return d.askLevels.getMovementByQuotation(amount, refPrice, true) } // LiftTheAsksFromMid derives full orderbook slippage information from mid price @@ -650,9 +622,9 @@ func (d *Depth) LiftTheAsksFromMid(amount float64, purchase bool) (*Movement, er return nil, err } if purchase { - return d.askTranches.getMovementByBase(amount, mid, true) + return d.askLevels.getMovementByBase(amount, mid, true) } - return d.askTranches.getMovementByQuotation(amount, mid, true) + return d.askLevels.getMovementByQuotation(amount, mid, true) } // LiftTheAsksFromBest derives full orderbook slippage information from best ask @@ -664,14 +636,14 @@ func (d *Depth) LiftTheAsksFromBest(amount float64, purchase bool) (*Movement, e if d.validationError != nil { return nil, d.validationError } - head, err := d.askTranches.getHeadPriceNoLock() + head, err := d.askLevels.getHeadPriceNoLock() if err != nil { return nil, err } if purchase { - return d.askTranches.getMovementByBase(amount, head, true) + return d.askLevels.getMovementByBase(amount, head, true) } - return d.askTranches.getMovementByQuotation(amount, head, true) + return d.askLevels.getMovementByQuotation(amount, head, true) } // GetMidPrice returns the mid price between the ask and bid spread @@ -686,11 +658,11 @@ func (d *Depth) GetMidPrice() (float64, error) { // getMidPriceNoLock is an unprotected helper that gets mid price func (d *Depth) getMidPriceNoLock() (float64, error) { - bidHead, err := d.bidTranches.getHeadPriceNoLock() + bidHead, err := d.bidLevels.getHeadPriceNoLock() if err != nil { return 0, err } - askHead, err := d.askTranches.getHeadPriceNoLock() + askHead, err := d.askLevels.getHeadPriceNoLock() if err != nil { return 0, err } @@ -704,7 +676,7 @@ func (d *Depth) GetBestBid() (float64, error) { if d.validationError != nil { return 0, d.validationError } - return d.bidTranches.getHeadPriceNoLock() + return d.bidLevels.getHeadPriceNoLock() } // GetBestAsk returns the best ask price @@ -714,7 +686,7 @@ func (d *Depth) GetBestAsk() (float64, error) { if d.validationError != nil { return 0, d.validationError } - return d.askTranches.getHeadPriceNoLock() + return d.askLevels.getHeadPriceNoLock() } // GetSpreadAmount returns the spread as a quotation amount @@ -724,11 +696,11 @@ func (d *Depth) GetSpreadAmount() (float64, error) { if d.validationError != nil { return 0, d.validationError } - askHead, err := d.askTranches.getHeadPriceNoLock() + askHead, err := d.askLevels.getHeadPriceNoLock() if err != nil { return 0, err } - bidHead, err := d.bidTranches.getHeadPriceNoLock() + bidHead, err := d.bidLevels.getHeadPriceNoLock() if err != nil { return 0, err } @@ -742,11 +714,11 @@ func (d *Depth) GetSpreadPercentage() (float64, error) { if d.validationError != nil { return 0, d.validationError } - askHead, err := d.askTranches.getHeadPriceNoLock() + askHead, err := d.askLevels.getHeadPriceNoLock() if err != nil { return 0, err } - bidHead, err := d.bidTranches.getHeadPriceNoLock() + bidHead, err := d.bidLevels.getHeadPriceNoLock() if err != nil { return 0, err } @@ -760,22 +732,22 @@ func (d *Depth) GetImbalance() (float64, error) { if d.validationError != nil { return 0, d.validationError } - askVolume, err := d.askTranches.getHeadVolumeNoLock() + askVolume, err := d.askLevels.getHeadVolumeNoLock() if err != nil { return 0, err } - bidVolume, err := d.bidTranches.getHeadVolumeNoLock() + bidVolume, err := d.bidLevels.getHeadVolumeNoLock() if err != nil { return 0, err } return (bidVolume - askVolume) / (bidVolume + askVolume), nil } -// GetTranches returns the desired tranche for the required depth count. If +// GetLevels returns the desired level for the required depth count. If // count is 0, it will return the entire orderbook. Count == 1 will retrieve the // best bid and ask. If the required count exceeds the orderbook depth, it will // return the entire orderbook. -func (d *Depth) GetTranches(count int) (ask, bid []Tranche, err error) { +func (d *Depth) GetLevels(count int) (ask, bid []Level, err error) { if count < 0 { return nil, nil, errInvalidBookDepth } @@ -784,7 +756,7 @@ func (d *Depth) GetTranches(count int) (ask, bid []Tranche, err error) { if d.validationError != nil { return nil, nil, d.validationError } - return d.askTranches.retrieve(count), d.bidTranches.retrieve(count), nil + return d.askLevels.retrieve(count), d.bidLevels.retrieve(count), nil } // Pair returns the pair associated with the depth diff --git a/exchanges/orderbook/depth_test.go b/exchanges/orderbook/depth_test.go index 3cd02810..22d1336a 100644 --- a/exchanges/orderbook/depth_test.go +++ b/exchanges/orderbook/depth_test.go @@ -30,14 +30,14 @@ func TestGetLength(t *testing.T) { _, err = d.GetAskLength() assert.ErrorIs(t, err, ErrOrderbookInvalid, "GetAskLength should error with invalid depth") - err = d.LoadSnapshot([]Tranche{{Price: 1337}}, nil, 0, time.Now(), time.Now(), true) + err = d.LoadSnapshot([]Level{{Price: 1337}}, nil, 0, time.Now(), time.Now(), true) assert.NoError(t, err, "LoadSnapshot should not error") askLen, err := d.GetAskLength() assert.NoError(t, err, "GetAskLength should not error") assert.Zero(t, askLen, "ask length should be zero") - d.askTranches.load([]Tranche{{Price: 1337}}) + d.askLevels.load([]Level{{Price: 1337}}) askLen, err = d.GetAskLength() assert.NoError(t, err, "GetAskLength should not error") @@ -50,14 +50,14 @@ func TestGetLength(t *testing.T) { _, err = d.GetBidLength() assert.ErrorIs(t, err, ErrOrderbookInvalid, "GetBidLength should error with invalid depth") - err = d.LoadSnapshot(nil, []Tranche{{Price: 1337}}, 0, time.Now(), time.Now(), true) + err = d.LoadSnapshot(nil, []Level{{Price: 1337}}, 0, time.Now(), time.Now(), true) assert.NoError(t, err, "LoadSnapshot should not error") bidLen, err := d.GetBidLength() assert.NoError(t, err, "GetBidLength should not error") assert.Zero(t, bidLen, "bid length should be zero") - d.bidTranches.load([]Tranche{{Price: 1337}}) + d.bidLevels.load([]Level{{Price: 1337}}) bidLen, err = d.GetBidLength() assert.NoError(t, err, "GetBidLength should not error") @@ -67,8 +67,8 @@ func TestGetLength(t *testing.T) { func TestRetrieve(t *testing.T) { t.Parallel() d := NewDepth(id) - d.askTranches.load([]Tranche{{Price: 1337}}) - d.bidTranches.load([]Tranche{{Price: 1337}}) + d.askLevels.load([]Level{{Price: 1337}}) + d.bidLevels.load([]Level{{Price: 1337}}) d.options = options{ exchange: "THE BIG ONE!!!!!!", pair: currency.NewPair(currency.THETA, currency.USD), @@ -142,8 +142,8 @@ func TestTotalAmounts(t *testing.T) { assert.Zero(t, liquidity, "total ask liquidity should be zero") assert.Zero(t, value, "total ask value should be zero") - d.askTranches.load([]Tranche{{Price: 1337, Amount: 1}}) - d.bidTranches.load([]Tranche{{Price: 1337, Amount: 10}}) + d.askLevels.load([]Level{{Price: 1337, Amount: 1}}) + d.bidLevels.load([]Level{{Price: 1337, Amount: 10}}) liquidity, value, err = d.TotalBidAmounts() assert.NoError(t, err, "TotalBidAmounts should not error") @@ -159,10 +159,10 @@ func TestTotalAmounts(t *testing.T) { func TestLoadSnapshot(t *testing.T) { t.Parallel() d := NewDepth(id) - err := d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1}}, Tranches{{Price: 1337, Amount: 10}}, 0, time.Time{}, time.Now(), false) + err := d.LoadSnapshot(Levels{{Price: 1337, Amount: 1}}, Levels{{Price: 1337, Amount: 10}}, 0, time.Time{}, time.Now(), false) assert.ErrorIs(t, err, errLastUpdatedNotSet, "LoadSnapshot should error correctly") - err = d.LoadSnapshot(Tranches{{Price: 1337, Amount: 2}}, Tranches{{Price: 1338, Amount: 10}}, 0, time.Now(), time.Now(), false) + err = d.LoadSnapshot(Levels{{Price: 1337, Amount: 2}}, Levels{{Price: 1338, Amount: 10}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") ob, err := d.Retrieve() @@ -181,7 +181,7 @@ func TestInvalidate(t *testing.T) { d.pair = currency.NewPair(currency.BTC, currency.WABI) d.asset = asset.Spot - err := d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1}}, Tranches{{Price: 1337, Amount: 10}}, 0, time.Now(), time.Now(), false) + err := d.LoadSnapshot(Levels{{Price: 1337, Amount: 1}}, Levels{{Price: 1337, Amount: 10}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") ob, err := d.Retrieve() @@ -209,7 +209,7 @@ func TestInvalidate(t *testing.T) { func TestUpdateBidAskByPrice(t *testing.T) { t.Parallel() d := NewDepth(id) - err := d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1338, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err := d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1338, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") err = d.UpdateBidAskByPrice(&Update{}) @@ -219,8 +219,8 @@ func TestUpdateBidAskByPrice(t *testing.T) { assert.NoError(t, err, "UpdateBidAskByPrice should not error") updates := &Update{ - Bids: Tranches{{Price: 1337, Amount: 2, ID: 1}}, - Asks: Tranches{{Price: 1338, Amount: 3, ID: 2}}, + Bids: Levels{{Price: 1337, Amount: 2, ID: 1}}, + Asks: Levels{{Price: 1338, Amount: 3, ID: 2}}, UpdateID: 1, UpdateTime: time.Now(), } @@ -233,8 +233,8 @@ func TestUpdateBidAskByPrice(t *testing.T) { assert.Equal(t, 2.0, ob.Bids[0].Amount, "Bids amount should be correct") updates = &Update{ - Bids: Tranches{{Price: 1337, Amount: 0, ID: 1}}, - Asks: Tranches{{Price: 1338, Amount: 0, ID: 2}}, + Bids: Levels{{Price: 1337, Amount: 0, ID: 1}}, + Asks: Levels{{Price: 1338, Amount: 0, ID: 2}}, UpdateID: 2, UpdateTime: time.Now(), } @@ -253,12 +253,12 @@ func TestUpdateBidAskByPrice(t *testing.T) { func TestDeleteBidAskByID(t *testing.T) { t.Parallel() d := NewDepth(id) - err := d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err := d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates := &Update{ - Bids: Tranches{{Price: 1337, Amount: 2, ID: 1}}, - Asks: Tranches{{Price: 1337, Amount: 2, ID: 2}}, + Bids: Levels{{Price: 1337, Amount: 2, ID: 1}}, + Asks: Levels{{Price: 1337, Amount: 2, ID: 2}}, } err = d.DeleteBidAskByID(updates, false) @@ -274,21 +274,21 @@ func TestDeleteBidAskByID(t *testing.T) { assert.Empty(t, ob.Bids, "Bids should be empty") updates = &Update{ - Bids: Tranches{{Price: 1337, Amount: 2, ID: 1}}, + Bids: Levels{{Price: 1337, Amount: 2, ID: 1}}, UpdateTime: time.Now(), } err = d.DeleteBidAskByID(updates, false) assert.ErrorIs(t, err, errIDCannotBeMatched, "DeleteBidAskByID should error correctly") updates = &Update{ - Asks: Tranches{{Price: 1337, Amount: 2, ID: 2}}, + Asks: Levels{{Price: 1337, Amount: 2, ID: 2}}, UpdateTime: time.Now(), } err = d.DeleteBidAskByID(updates, false) assert.ErrorIs(t, err, errIDCannotBeMatched, "DeleteBidAskByID should error correctly") updates = &Update{ - Asks: Tranches{{Price: 1337, Amount: 2, ID: 2}}, + Asks: Levels{{Price: 1337, Amount: 2, ID: 2}}, UpdateTime: time.Now(), } err = d.DeleteBidAskByID(updates, true) @@ -298,12 +298,12 @@ func TestDeleteBidAskByID(t *testing.T) { func TestUpdateBidAskByID(t *testing.T) { t.Parallel() d := NewDepth(id) - err := d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err := d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates := &Update{ - Bids: Tranches{{Price: 1337, Amount: 2, ID: 1}}, - Asks: Tranches{{Price: 1337, Amount: 2, ID: 2}}, + Bids: Levels{{Price: 1337, Amount: 2, ID: 1}}, + Asks: Levels{{Price: 1337, Amount: 2, ID: 2}}, } err = d.UpdateBidAskByID(updates) @@ -319,7 +319,7 @@ func TestUpdateBidAskByID(t *testing.T) { assert.Equal(t, 2.0, ob.Bids[0].Amount, "First bid amount should be correct") updates = &Update{ - Bids: Tranches{{Price: 1337, Amount: 2, ID: 666}}, + Bids: Levels{{Price: 1337, Amount: 2, ID: 666}}, UpdateTime: time.Now(), } // random unmatching IDs @@ -327,7 +327,7 @@ func TestUpdateBidAskByID(t *testing.T) { assert.ErrorIs(t, err, errIDCannotBeMatched, "UpdateBidAskByID should error correctly") updates = &Update{ - Asks: Tranches{{Price: 1337, Amount: 2, ID: 69}}, + Asks: Levels{{Price: 1337, Amount: 2, ID: 69}}, UpdateTime: time.Now(), } err = d.UpdateBidAskByID(updates) @@ -337,11 +337,11 @@ func TestUpdateBidAskByID(t *testing.T) { func TestInsertBidAskByID(t *testing.T) { t.Parallel() d := NewDepth(id) - err := d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err := d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates := &Update{ - Asks: Tranches{{Price: 1337, Amount: 2, ID: 3}}, + Asks: Levels{{Price: 1337, Amount: 2, ID: 3}}, } err = d.InsertBidAskByID(updates) assert.ErrorIs(t, err, errLastUpdatedNotSet, "InsertBidAskByID should error correctly") @@ -351,23 +351,23 @@ func TestInsertBidAskByID(t *testing.T) { err = d.InsertBidAskByID(updates) assert.ErrorIs(t, err, errCollisionDetected, "InsertBidAskByID should error correctly on collision") - err = d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err = d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates = &Update{ - Bids: Tranches{{Price: 1337, Amount: 2, ID: 3}}, + Bids: Levels{{Price: 1337, Amount: 2, ID: 3}}, UpdateTime: time.Now(), } err = d.InsertBidAskByID(updates) assert.ErrorIs(t, err, errCollisionDetected, "InsertBidAskByID should error correctly on collision") - err = d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err = d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates = &Update{ - Bids: Tranches{{Price: 1338, Amount: 2, ID: 3}}, - Asks: Tranches{{Price: 1336, Amount: 2, ID: 4}}, + Bids: Levels{{Price: 1338, Amount: 2, ID: 3}}, + Asks: Levels{{Price: 1336, Amount: 2, ID: 4}}, UpdateTime: time.Now(), } err = d.InsertBidAskByID(updates) @@ -382,12 +382,12 @@ func TestInsertBidAskByID(t *testing.T) { func TestUpdateInsertByID(t *testing.T) { t.Parallel() d := NewDepth(id) - err := d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err := d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates := &Update{ - Bids: Tranches{{Price: 1338, Amount: 0, ID: 3}}, - Asks: Tranches{{Price: 1336, Amount: 2, ID: 4}}, + Bids: Levels{{Price: 1338, Amount: 0, ID: 3}}, + Asks: Levels{{Price: 1336, Amount: 2, ID: 4}}, } err = d.UpdateInsertByID(updates) assert.ErrorIs(t, err, errLastUpdatedNotSet, "UpdateInsertByID should error correctly") @@ -400,12 +400,12 @@ func TestUpdateInsertByID(t *testing.T) { _, err = d.Retrieve() assert.ErrorIs(t, err, ErrOrderbookInvalid, "Retrieve should error correctly") - err = d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err = d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates = &Update{ - Bids: Tranches{{Price: 1338, Amount: 2, ID: 3}}, - Asks: Tranches{{Price: 1336, Amount: 0, ID: 4}}, + Bids: Levels{{Price: 1338, Amount: 2, ID: 3}}, + Asks: Levels{{Price: 1336, Amount: 0, ID: 4}}, UpdateTime: time.Now(), } err = d.UpdateInsertByID(updates) @@ -415,12 +415,12 @@ func TestUpdateInsertByID(t *testing.T) { _, err = d.Retrieve() assert.ErrorIs(t, err, ErrOrderbookInvalid, "Retrieve should error correctly") - err = d.LoadSnapshot(Tranches{{Price: 1337, Amount: 1, ID: 1}}, Tranches{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) + err = d.LoadSnapshot(Levels{{Price: 1337, Amount: 1, ID: 1}}, Levels{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Now(), time.Now(), false) assert.NoError(t, err, "LoadSnapshot should not error") updates = &Update{ - Bids: Tranches{{Price: 1338, Amount: 2, ID: 3}}, - Asks: Tranches{{Price: 1336, Amount: 2, ID: 4}}, + Bids: Levels{{Price: 1338, Amount: 2, ID: 3}}, + Asks: Levels{{Price: 1336, Amount: 2, ID: 4}}, UpdateTime: time.Now(), } err = d.UpdateInsertByID(updates) @@ -437,7 +437,7 @@ func TestAssignOptions(t *testing.T) { d := Depth{} cp := currency.NewPair(currency.LINK, currency.BTC) tn := time.Now() - d.AssignOptions(&Base{ + d.AssignOptions(&Book{ Exchange: "test", Pair: cp, Asset: asset.Spot, @@ -663,33 +663,33 @@ func TestGetImbalance_Depth(t *testing.T) { assert.Zero(t, imbalance, "imbalance should be correct") } -func TestGetTranches(t *testing.T) { +func TestGetLevels(t *testing.T) { t.Parallel() - _, _, err := getInvalidDepth().GetTranches(0) - assert.ErrorIs(t, err, ErrOrderbookInvalid, "GetTranches should error correctly") + _, _, err := getInvalidDepth().GetLevels(0) + assert.ErrorIs(t, err, ErrOrderbookInvalid, "GetLevels should error correctly") depth := NewDepth(id) - _, _, err = depth.GetTranches(-1) - assert.ErrorIs(t, err, errInvalidBookDepth, "GetTranches should error correctly") + _, _, err = depth.GetLevels(-1) + assert.ErrorIs(t, err, errInvalidBookDepth, "GetLevels should error correctly") - askT, bidT, err := depth.GetTranches(0) - assert.NoError(t, err, "GetTranches should not error") - assert.Empty(t, askT, "Ask tranche should be empty") - assert.Empty(t, bidT, "Bid tranche should be empty") + askL, bidL, err := depth.GetLevels(0) + assert.NoError(t, err, "GetLevels should not error") + assert.Empty(t, askL, "Ask level should be empty") + assert.Empty(t, bidL, "Bid level should be empty") err = depth.LoadSnapshot(bid, ask, 0, time.Now(), time.Now(), true) assert.NoError(t, err, "LoadSnapshot should not error") - askT, bidT, err = depth.GetTranches(0) - assert.NoError(t, err, "GetTranches should not error") - assert.Len(t, askT, 20, "asks should have correct number of tranches") - assert.Len(t, bidT, 20, "bids should have correct number of tranches") + askL, bidL, err = depth.GetLevels(0) + assert.NoError(t, err, "GetLevels should not error") + assert.Len(t, askL, 20, "asks should have correct number of Levels") + assert.Len(t, bidL, 20, "bids should have correct number of Levels") - askT, bidT, err = depth.GetTranches(5) - assert.NoError(t, err, "GetTranches should not error") - assert.Len(t, askT, 5, "asks should have correct number of tranches") - assert.Len(t, bidT, 5, "bids should have correct number of tranches") + askL, bidL, err = depth.GetLevels(5) + assert.NoError(t, err, "GetLevels should not error") + assert.Len(t, askL, 5, "asks should have correct number of Levels") + assert.Len(t, bidL, 5, "bids should have correct number of Levels") } func getInvalidDepth() *Depth { @@ -835,7 +835,7 @@ var movementTests = []struct { []movementTest{ {[]any{0.7479431563201197}, Movement{Sold: 13415.0}}, // First and second price from mid - price level target 1326 (which should be kept) // All the way up to the last price from best bid price - // This goes to price 1356, it will not count that tranches' volume as it is needed to sustain the slippage. + // This goes to price 1356, it will not count that Levels' volume as it is needed to sustain the slippage. {[]any{1.4210919970082274}, Movement{Sold: 25574.0}}, }, }, diff --git a/exchanges/orderbook/tranches.go b/exchanges/orderbook/levels.go similarity index 59% rename from exchanges/orderbook/tranches.go rename to exchanges/orderbook/levels.go index 09ce05ae..87105c0f 100644 --- a/exchanges/orderbook/tranches.go +++ b/exchanges/orderbook/levels.go @@ -27,65 +27,63 @@ var ( errNoLiquidity = errors.New("no liquidity") ) -// Tranches defines a slice of orderbook Tranche -type Tranches []Tranche +// Levels defines a slice of orderbook levels +type Levels []Level // comparison defines expected functionality to compare between two reference // price levels type comparison func(float64, float64) bool -// load iterates across new tranches and refreshes stored slice with this +// load iterates across new Levels and refreshes stored slice with this // incoming snapshot. -func (ts *Tranches) load(incoming Tranches) { +func (l *Levels) load(incoming Levels) { if len(incoming) == 0 { - *ts = (*ts)[:0] // Flush + *l = (*l)[:0] // Flush return } - if len(incoming) <= len(*ts) { - copy(*ts, incoming) // Reuse - *ts = (*ts)[:len(incoming)] // Flush excess + if len(incoming) <= len(*l) { + copy(*l, incoming) // Reuse + *l = (*l)[:len(incoming)] // Flush excess return } - *ts = make([]Tranche, len(incoming)) // Extend - copy(*ts, incoming) // Copy + *l = make([]Level, len(incoming)) // Extend + copy(*l, incoming) // Copy } // updateByID amends price by corresponding ID and returns an error if not found -func (ts Tranches) updateByID(updts []Tranche) error { +func (l Levels) updateByID(updts []Level) error { updates: for x := range updts { - for y := range ts { - if updts[x].ID != ts[y].ID { // Filter IDs that don't match + for y := range l { + if updts[x].ID != l[y].ID { // Filter IDs that don't match continue } if updts[x].Price > 0 { // Only apply changes when zero values are not present, Bitmex // for example sends 0 price values. - ts[y].Price = updts[x].Price - ts[y].StrPrice = updts[x].StrPrice + l[y].Price = updts[x].Price + l[y].StrPrice = updts[x].StrPrice } - ts[y].Amount = updts[x].Amount - ts[y].StrAmount = updts[x].StrAmount + l[y].Amount = updts[x].Amount + l[y].StrAmount = updts[x].StrAmount continue updates } - return fmt.Errorf("update error: %w ID: %d not found", - errIDCannotBeMatched, - updts[x].ID) + return fmt.Errorf("update error: %w ID: %d not found", errIDCannotBeMatched, updts[x].ID) } return nil } // deleteByID deletes reference by ID -func (ts *Tranches) deleteByID(updts Tranches, bypassErr bool) error { +func (l *Levels) deleteByID(updts Levels, bypassErr bool) error { updates: for x := range updts { - for y := range *ts { - if updts[x].ID != (*ts)[y].ID { + for y := range *l { + if updts[x].ID != (*l)[y].ID { continue } - copy((*ts)[y:], (*ts)[y+1:]) - *ts = (*ts)[:len(*ts)-1] + copy((*l)[y:], (*l)[y+1:]) + *l = (*l)[:len(*l)-1] continue updates } @@ -97,164 +95,164 @@ updates: } // amount returns total depth liquidity and value -func (ts Tranches) amount() (liquidity, value float64) { - for x := range ts { - liquidity += ts[x].Amount - value += ts[x].Amount * ts[x].Price +func (l Levels) amount() (liquidity, value float64) { + for x := range l { + liquidity += l[x].Amount + value += l[x].Amount * l[x].Price } return } -// retrieve returns a slice of contents from the stored Tranches up to the +// retrieve returns a slice of contents from the stored Levels up to the // count length. If count is zero or greater than the length of the stored -// Tranches, the entire slice is returned. -func (ts Tranches) retrieve(count int) Tranches { - if count == 0 || count >= len(ts) { - count = len(ts) +// Levels, the entire slice is returned. +func (l Levels) retrieve(count int) Levels { + if count == 0 || count >= len(l) { + count = len(l) } - result := make(Tranches, count) - copy(result, ts) + result := make(Levels, count) + copy(result, l) return result } // updateInsertByPrice amends, inserts, moves and cleaves length of depth by // updates -func (ts *Tranches) updateInsertByPrice(updts Tranches, maxChainLength int, compare func(float64, float64) bool) { +func (l *Levels) updateInsertByPrice(updts Levels, maxChainLength int, compare func(float64, float64) bool) { updates: for x := range updts { - for y := range *ts { + for y := range *l { switch { - case (*ts)[y].Price == updts[x].Price: + case (*l)[y].Price == updts[x].Price: if updts[x].Amount <= 0 { // Delete - if y+1 == len(*ts) { - *ts = (*ts)[:y] + if y+1 == len(*l) { + *l = (*l)[:y] } else { - copy((*ts)[y:], (*ts)[y+1:]) - *ts = (*ts)[:len(*ts)-1] + copy((*l)[y:], (*l)[y+1:]) + *l = (*l)[:len(*l)-1] } } else { // Update - (*ts)[y].Amount = updts[x].Amount - (*ts)[y].StrAmount = updts[x].StrAmount + (*l)[y].Amount = updts[x].Amount + (*l)[y].StrAmount = updts[x].StrAmount } continue updates - case compare((*ts)[y].Price, updts[x].Price): + case compare((*l)[y].Price, updts[x].Price): if updts[x].Amount > 0 { - *ts = append(*ts, Tranche{}) // Extend - copy((*ts)[y+1:], (*ts)[y:]) // Copy elements from index y onwards one position to the right - (*ts)[y] = updts[x] // Insert updts[x] at index y + *l = append(*l, Level{}) // Extend + copy((*l)[y+1:], (*l)[y:]) // Copy elements from index y onwards one position to the right + (*l)[y] = updts[x] // Insert updts[x] at index y } continue updates } } if updts[x].Amount > 0 { - *ts = append(*ts, updts[x]) + *l = append(*l, updts[x]) } } // Reduces length of total stored slice length to a maxChainLength value - if maxChainLength != 0 && len(*ts) > maxChainLength { - *ts = (*ts)[:maxChainLength] + if maxChainLength != 0 && len(*l) > maxChainLength { + *l = (*l)[:maxChainLength] } } // updateInsertByID updates or inserts if not found for a bid or ask depth -func (ts *Tranches) updateInsertByID(updts Tranches, compare comparison) error { +func (l *Levels) updateInsertByID(updts Levels, compare comparison) error { updates: for x := range updts { if updts[x].Amount <= 0 { return errAmountCannotBeLessOrEqualToZero } var popped bool - for y := 0; y < len(*ts); y++ { - if (*ts)[y].ID == updts[x].ID { - if (*ts)[y].Price != updts[x].Price { // Price level change - if y+1 == len(*ts) { // end of depth + for y := 0; y < len(*l); y++ { + if (*l)[y].ID == updts[x].ID { + if (*l)[y].Price != updts[x].Price { // Price level change + if y+1 == len(*l) { // end of depth // no movement needed just a re-adjustment - (*ts)[y] = updts[x] + (*l)[y] = updts[x] continue updates } - copy((*ts)[y:], (*ts)[y+1:]) // RM tranche and shift left - *ts = (*ts)[:len(*ts)-1] // Unlink residual element from end of slice - y-- // adjust index + copy((*l)[y:], (*l)[y+1:]) // RM level and shift left + *l = (*l)[:len(*l)-1] // Unlink residual element from end of slice + y-- // adjust index popped = true continue // continue through node depth } // no price change, amend amount and continue update - (*ts)[y].Amount = updts[x].Amount - (*ts)[y].StrAmount = updts[x].StrAmount + (*l)[y].Amount = updts[x].Amount + (*l)[y].StrAmount = updts[x].StrAmount continue updates // continue to next update } - if compare((*ts)[y].Price, updts[x].Price) { - *ts = append(*ts, Tranche{}) // Extend - copy((*ts)[y+1:], (*ts)[y:]) // Copy elements from index y onwards one position to the right - (*ts)[y] = updts[x] // Insert updts[x] at index y + if compare((*l)[y].Price, updts[x].Price) { + *l = append(*l, Level{}) // Extend + copy((*l)[y+1:], (*l)[y:]) // Copy elements from index y onwards one position to the right + (*l)[y] = updts[x] // Insert updts[x] at index y if popped { // already found ID and popped continue updates } // search for ID - for z := y + 1; z < len(*ts); z++ { - if (*ts)[z].ID == updts[x].ID { - copy((*ts)[z:], (*ts)[z+1:]) // RM tranche and shift left - *ts = (*ts)[:len(*ts)-1] // Unlink residual element from end of slice + for z := y + 1; z < len(*l); z++ { + if (*l)[z].ID == updts[x].ID { + copy((*l)[z:], (*l)[z+1:]) // RM level and shift left + *l = (*l)[:len(*l)-1] // Unlink residual element from end of slice break } } continue updates } } - *ts = append(*ts, updts[x]) + *l = append(*l, updts[x]) } return nil } // insertUpdates inserts new updates for bids or asks based on price level -func (ts *Tranches) insertUpdates(updts Tranches, comp comparison) error { +func (l *Levels) insertUpdates(updts Levels, comp comparison) error { updates: for x := range updts { - if len(*ts) == 0 { - *ts = append(*ts, updts[x]) + if len(*l) == 0 { + *l = append(*l, updts[x]) continue } - for y := range *ts { + for y := range *l { switch { - case (*ts)[y].Price == updts[x].Price: // Price already found + case (*l)[y].Price == updts[x].Price: // Price already found return fmt.Errorf("%w for price %f", errCollisionDetected, updts[x].Price) - case comp((*ts)[y].Price, updts[x].Price): // price at correct spot - *ts = append((*ts)[:y], append([]Tranche{updts[x]}, (*ts)[y:]...)...) + case comp((*l)[y].Price, updts[x].Price): // price at correct spot + *l = append((*l)[:y], append([]Level{updts[x]}, (*l)[y:]...)...) continue updates } } - *ts = append(*ts, updts[x]) + *l = append(*l, updts[x]) } return nil } // getHeadPriceNoLock gets best/head price -func (ts Tranches) getHeadPriceNoLock() (float64, error) { - if len(ts) == 0 { +func (l Levels) getHeadPriceNoLock() (float64, error) { + if len(l) == 0 { return 0, errNoLiquidity } - return ts[0].Price, nil + return l[0].Price, nil } // getHeadVolumeNoLock gets best/head volume -func (ts Tranches) getHeadVolumeNoLock() (float64, error) { - if len(ts) == 0 { +func (l Levels) getHeadVolumeNoLock() (float64, error) { + if len(l) == 0 { return 0, errNoLiquidity } - return ts[0].Amount, nil + return l[0].Amount, nil } // getMovementByQuotation traverses through orderbook liquidity using quotation // currency as a limiter and returns orderbook movement details. Swap boolean // allows the swap of sold and purchased to reduce code so it doesn't need to be // specific to bid or ask. -func (ts Tranches) getMovementByQuotation(quote, refPrice float64, swap bool) (*Movement, error) { +func (l Levels) getMovementByQuotation(quote, refPrice float64, swap bool) (*Movement, error) { if quote <= 0 { return nil, errQuoteAmountInvalid } @@ -263,32 +261,32 @@ func (ts Tranches) getMovementByQuotation(quote, refPrice float64, swap bool) (* return nil, errInvalidReferencePrice } - head, err := ts.getHeadPriceNoLock() + head, err := l.getHeadPriceNoLock() if err != nil { return nil, err } m := Movement{StartPrice: refPrice} - for x := range ts { - trancheValue := ts[x].Amount * ts[x].Price - leftover := quote - trancheValue + for x := range l { + levelValue := l[x].Amount * l[x].Price + leftover := quote - levelValue if leftover < 0 { m.Purchased += quote - m.Sold += quote / trancheValue * ts[x].Amount - // This tranche is not consumed so the book shifts to this price. - m.EndPrice = ts[x].Price + m.Sold += quote / levelValue * l[x].Amount + // This level is not consumed so the book shifts to this price. + m.EndPrice = l[x].Price quote = 0 break } - // Full tranche consumed - m.Purchased += ts[x].Price * ts[x].Amount - m.Sold += ts[x].Amount + // Full level consumed + m.Purchased += l[x].Price * l[x].Amount + m.Sold += l[x].Amount quote = leftover if leftover == 0 { - // Price no longer exists on the book so use next full price tranche + // Price no longer exists on the book so use next full price level // to calculate book impact. If available. - if x+1 < len(ts) { - m.EndPrice = ts[x+1].Price + if x+1 < len(l) { + m.EndPrice = l[x+1].Price } else { m.FullBookSideConsumed = true } @@ -302,7 +300,7 @@ func (ts Tranches) getMovementByQuotation(quote, refPrice float64, swap bool) (* // as a limiter and returns orderbook movement details. Swap boolean allows the // swap of sold and purchased to reduce code so it doesn't need to be specific // to bid or ask. -func (ts Tranches) getMovementByBase(base, refPrice float64, swap bool) (*Movement, error) { +func (l Levels) getMovementByBase(base, refPrice float64, swap bool) (*Movement, error) { if base <= 0 { return nil, errBaseAmountInvalid } @@ -311,31 +309,31 @@ func (ts Tranches) getMovementByBase(base, refPrice float64, swap bool) (*Moveme return nil, errInvalidReferencePrice } - head, err := ts.getHeadPriceNoLock() + head, err := l.getHeadPriceNoLock() if err != nil { return nil, err } m := Movement{StartPrice: refPrice} - for x := range ts { - leftover := base - ts[x].Amount + for x := range l { + leftover := base - l[x].Amount if leftover < 0 { - m.Purchased += ts[x].Price * base + m.Purchased += l[x].Price * base m.Sold += base - // This tranche is not consumed so the book shifts to this price. - m.EndPrice = ts[x].Price + // This level is not consumed so the book shifts to this price. + m.EndPrice = l[x].Price base = 0 break } - // Full tranche consumed - m.Purchased += ts[x].Price * ts[x].Amount - m.Sold += ts[x].Amount + // Full level consumed + m.Purchased += l[x].Price * l[x].Amount + m.Sold += l[x].Amount base = leftover if leftover == 0 { - // Price no longer exists on the book so use next full price tranche + // Price no longer exists on the book so use next full price level // to calculate book impact. - if x+1 < len(ts) { - m.EndPrice = ts[x+1].Price + if x+1 < len(l) { + m.EndPrice = l[x+1].Price } else { m.FullBookSideConsumed = true } @@ -345,8 +343,8 @@ func (ts Tranches) getMovementByBase(base, refPrice float64, swap bool) (*Moveme return m.finalizeFields(m.Purchased, m.Sold, head, base, swap) } -// bidTranches bid depth specific functionality -type bidTranches struct{ Tranches } +// bidLevels bid depth specific functionality +type bidLevels struct{ Levels } // bidCompare ensures price is in correct descending alignment (can inline) func bidCompare(left, right float64) bool { @@ -355,24 +353,24 @@ func bidCompare(left, right float64) bool { // updateInsertByPrice amends, inserts, moves and cleaves length of depth by // updates -func (bids *bidTranches) updateInsertByPrice(updts Tranches, maxChainLength int) { - bids.Tranches.updateInsertByPrice(updts, maxChainLength, bidCompare) +func (bids *bidLevels) updateInsertByPrice(updts Levels, maxChainLength int) { + bids.Levels.updateInsertByPrice(updts, maxChainLength, bidCompare) } // updateInsertByID updates or inserts if not found -func (bids *bidTranches) updateInsertByID(updts Tranches) error { - return bids.Tranches.updateInsertByID(updts, bidCompare) +func (bids *bidLevels) updateInsertByID(updts Levels) error { + return bids.Levels.updateInsertByID(updts, bidCompare) } // insertUpdates inserts new updates for bids based on price level -func (bids *bidTranches) insertUpdates(updts Tranches) error { - return bids.Tranches.insertUpdates(updts, bidCompare) +func (bids *bidLevels) insertUpdates(updts Levels) error { + return bids.Levels.insertUpdates(updts, bidCompare) } // hitBidsByNominalSlippage hits the bids by the required nominal slippage // percentage, calculated from the reference price and returns orderbook // movement details. -func (bids *bidTranches) hitBidsByNominalSlippage(slippage, refPrice float64) (*Movement, error) { +func (bids *bidLevels) hitBidsByNominalSlippage(slippage, refPrice float64) (*Movement, error) { if slippage < 0 { return nil, errInvalidNominalSlippage } @@ -385,16 +383,16 @@ func (bids *bidTranches) hitBidsByNominalSlippage(slippage, refPrice float64) (* return nil, errInvalidReferencePrice } - if len(bids.Tranches) == 0 { + if len(bids.Levels) == 0 { return nil, errNoLiquidity } nominal := &Movement{StartPrice: refPrice, EndPrice: refPrice} var cumulativeValue, cumulativeAmounts float64 - for x := range bids.Tranches { - totalTrancheValue := bids.Tranches[x].Price * bids.Tranches[x].Amount - currentFullValue := totalTrancheValue + cumulativeValue - currentTotalAmounts := cumulativeAmounts + bids.Tranches[x].Amount + for x := range bids.Levels { + totallevelValue := bids.Levels[x].Price * bids.Levels[x].Amount + currentFullValue := totallevelValue + cumulativeValue + currentTotalAmounts := cumulativeAmounts + bids.Levels[x].Amount nominal.AverageOrderCost = currentFullValue / currentTotalAmounts percent := math.PercentageChange(refPrice, nominal.AverageOrderCost) @@ -411,24 +409,24 @@ func (bids *bidTranches) hitBidsByNominalSlippage(slippage, refPrice float64) (* } comparative := targetCost * cumulativeAmounts comparativeDiff := comparative - cumulativeValue - trancheTargetPriceDiff := bids.Tranches[x].Price - targetCost - trancheAmountExpectation := comparativeDiff / trancheTargetPriceDiff + levelTargetPriceDiff := bids.Levels[x].Price - targetCost + levelAmountExpectation := comparativeDiff / levelTargetPriceDiff nominal.NominalPercentage = slippage - nominal.Sold = cumulativeAmounts + trancheAmountExpectation - nominal.Purchased += trancheAmountExpectation * bids.Tranches[x].Price + nominal.Sold = cumulativeAmounts + levelAmountExpectation + nominal.Purchased += levelAmountExpectation * bids.Levels[x].Price nominal.AverageOrderCost = nominal.Purchased / nominal.Sold - nominal.EndPrice = bids.Tranches[x].Price + nominal.EndPrice = bids.Levels[x].Price return nominal, nil } - nominal.EndPrice = bids.Tranches[x].Price + nominal.EndPrice = bids.Levels[x].Price cumulativeValue = currentFullValue nominal.NominalPercentage = percent - nominal.Sold += bids.Tranches[x].Amount - nominal.Purchased += totalTrancheValue + nominal.Sold += bids.Levels[x].Amount + nominal.Purchased += totallevelValue cumulativeAmounts = currentTotalAmounts if slippage == percent { - nominal.FullBookSideConsumed = x+1 >= len(bids.Tranches) + nominal.FullBookSideConsumed = x+1 >= len(bids.Levels) return nominal, nil } } @@ -439,7 +437,7 @@ func (bids *bidTranches) hitBidsByNominalSlippage(slippage, refPrice float64) (* // hitBidsByImpactSlippage hits the bids by the required impact slippage // percentage, calculated from the reference price and returns orderbook // movement details. -func (bids *bidTranches) hitBidsByImpactSlippage(slippage, refPrice float64) (*Movement, error) { +func (bids *bidLevels) hitBidsByImpactSlippage(slippage, refPrice float64) (*Movement, error) { if slippage <= 0 { return nil, errInvalidImpactSlippage } @@ -452,25 +450,25 @@ func (bids *bidTranches) hitBidsByImpactSlippage(slippage, refPrice float64) (*M return nil, errInvalidReferencePrice } - if len(bids.Tranches) == 0 { + if len(bids.Levels) == 0 { return nil, errNoLiquidity } impact := &Movement{StartPrice: refPrice, EndPrice: refPrice} - for x := range bids.Tranches { - percent := math.PercentageChange(refPrice, bids.Tranches[x].Price) + for x := range bids.Levels { + percent := math.PercentageChange(refPrice, bids.Levels[x].Price) if percent != 0 { percent *= -1 } - impact.EndPrice = bids.Tranches[x].Price + impact.EndPrice = bids.Levels[x].Price impact.ImpactPercentage = percent if slippage <= percent { - // Don't include this tranche amount as this consumes the tranche + // Don't include this level amount as this consumes the level // book price, thus obtaining a higher percentage impact. return impact, nil } - impact.Sold += bids.Tranches[x].Amount - impact.Purchased += bids.Tranches[x].Amount * bids.Tranches[x].Price + impact.Sold += bids.Levels[x].Amount + impact.Purchased += bids.Levels[x].Amount * bids.Levels[x].Price impact.AverageOrderCost = impact.Purchased / impact.Sold } impact.FullBookSideConsumed = true @@ -478,8 +476,8 @@ func (bids *bidTranches) hitBidsByImpactSlippage(slippage, refPrice float64) (*M return impact, nil } -// askTranches ask depth specific functionality -type askTranches struct{ Tranches } +// askLevels ask depth specific functionality +type askLevels struct{ Levels } // askCompare ensures price is in correct ascending alignment (can inline) func askCompare(left, right float64) bool { @@ -488,24 +486,24 @@ func askCompare(left, right float64) bool { // updateInsertByPrice amends, inserts, moves and cleaves length of depth by // updates -func (ask *askTranches) updateInsertByPrice(updts Tranches, maxChainLength int) { - ask.Tranches.updateInsertByPrice(updts, maxChainLength, askCompare) +func (ask *askLevels) updateInsertByPrice(updts Levels, maxChainLength int) { + ask.Levels.updateInsertByPrice(updts, maxChainLength, askCompare) } // updateInsertByID updates or inserts if not found -func (ask *askTranches) updateInsertByID(updts Tranches) error { - return ask.Tranches.updateInsertByID(updts, askCompare) +func (ask *askLevels) updateInsertByID(updts Levels) error { + return ask.Levels.updateInsertByID(updts, askCompare) } // insertUpdates inserts new updates for asks based on price level -func (ask *askTranches) insertUpdates(updts Tranches) error { - return ask.Tranches.insertUpdates(updts, askCompare) +func (ask *askLevels) insertUpdates(updts Levels) error { + return ask.Levels.insertUpdates(updts, askCompare) } // liftAsksByNominalSlippage lifts the asks by the required nominal slippage // percentage, calculated from the reference price and returns orderbook // movement details. -func (ask *askTranches) liftAsksByNominalSlippage(slippage, refPrice float64) (*Movement, error) { +func (ask *askLevels) liftAsksByNominalSlippage(slippage, refPrice float64) (*Movement, error) { if slippage < 0 { return nil, errInvalidNominalSlippage } @@ -514,16 +512,16 @@ func (ask *askTranches) liftAsksByNominalSlippage(slippage, refPrice float64) (* return nil, errInvalidReferencePrice } - if len(ask.Tranches) == 0 { + if len(ask.Levels) == 0 { return nil, errNoLiquidity } nominal := &Movement{StartPrice: refPrice, EndPrice: refPrice} var cumulativeAmounts float64 - for x := range ask.Tranches { - totalTrancheValue := ask.Tranches[x].Price * ask.Tranches[x].Amount - currentValue := totalTrancheValue + nominal.Sold - currentAmounts := cumulativeAmounts + ask.Tranches[x].Amount + for x := range ask.Levels { + totallevelValue := ask.Levels[x].Price * ask.Levels[x].Amount + currentValue := totallevelValue + nominal.Sold + currentAmounts := cumulativeAmounts + ask.Levels[x].Amount nominal.AverageOrderCost = currentValue / currentAmounts percent := math.PercentageChange(refPrice, nominal.AverageOrderCost) @@ -538,19 +536,19 @@ func (ask *askTranches) liftAsksByNominalSlippage(slippage, refPrice float64) (* comparative := targetCost * cumulativeAmounts comparativeDiff := comparative - nominal.Sold - trancheTargetPriceDiff := ask.Tranches[x].Price - targetCost - trancheAmountExpectation := comparativeDiff / trancheTargetPriceDiff + levelTargetPriceDiff := ask.Levels[x].Price - targetCost + levelAmountExpectation := comparativeDiff / levelTargetPriceDiff nominal.NominalPercentage = slippage - nominal.Sold += trancheAmountExpectation * ask.Tranches[x].Price - nominal.Purchased += trancheAmountExpectation + nominal.Sold += levelAmountExpectation * ask.Levels[x].Price + nominal.Purchased += levelAmountExpectation nominal.AverageOrderCost = nominal.Sold / nominal.Purchased - nominal.EndPrice = ask.Tranches[x].Price + nominal.EndPrice = ask.Levels[x].Price return nominal, nil } - nominal.EndPrice = ask.Tranches[x].Price + nominal.EndPrice = ask.Levels[x].Price nominal.Sold = currentValue - nominal.Purchased += ask.Tranches[x].Amount + nominal.Purchased += ask.Levels[x].Amount nominal.NominalPercentage = percent if slippage == percent { return nominal, nil @@ -564,7 +562,7 @@ func (ask *askTranches) liftAsksByNominalSlippage(slippage, refPrice float64) (* // liftAsksByImpactSlippage lifts the asks by the required impact slippage // percentage, calculated from the reference price and returns orderbook // movement details. -func (ask *askTranches) liftAsksByImpactSlippage(slippage, refPrice float64) (*Movement, error) { +func (ask *askLevels) liftAsksByImpactSlippage(slippage, refPrice float64) (*Movement, error) { if slippage <= 0 { return nil, errInvalidImpactSlippage } @@ -573,22 +571,22 @@ func (ask *askTranches) liftAsksByImpactSlippage(slippage, refPrice float64) (*M return nil, errInvalidReferencePrice } - if len(ask.Tranches) == 0 { + if len(ask.Levels) == 0 { return nil, errNoLiquidity } impact := &Movement{StartPrice: refPrice, EndPrice: refPrice} - for x := range ask.Tranches { - percent := math.PercentageChange(refPrice, ask.Tranches[x].Price) + for x := range ask.Levels { + percent := math.PercentageChange(refPrice, ask.Levels[x].Price) impact.ImpactPercentage = percent - impact.EndPrice = ask.Tranches[x].Price + impact.EndPrice = ask.Levels[x].Price if slippage <= percent { - // Don't include this tranche amount as this consumes the tranche + // Don't include this level amount as this consumes the level // book price, thus obtaining a higher percentage impact. return impact, nil } - impact.Sold += ask.Tranches[x].Amount * ask.Tranches[x].Price - impact.Purchased += ask.Tranches[x].Amount + impact.Sold += ask.Levels[x].Amount * ask.Levels[x].Price + impact.Purchased += ask.Levels[x].Amount impact.AverageOrderCost = impact.Sold / impact.Purchased } impact.FullBookSideConsumed = true @@ -629,7 +627,7 @@ func (m *Movement) finalizeFields(cost, amount, headPrice, leftover float64, swa if !m.FullBookSideConsumed && leftover == 0 { // Impact percentage is how much the orderbook slips from the reference - // price to the remaining tranche price. + // price to the remaining level price. m.ImpactPercentage = math.PercentageChange(m.StartPrice, m.EndPrice) if m.ImpactPercentage < 0 { diff --git a/exchanges/orderbook/tranches_test.go b/exchanges/orderbook/levels_test.go similarity index 79% rename from exchanges/orderbook/tranches_test.go rename to exchanges/orderbook/levels_test.go index b89a6d83..b06859f0 100644 --- a/exchanges/orderbook/tranches_test.go +++ b/exchanges/orderbook/levels_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" ) -var ask = Tranches{ +var ask = Levels{ {Price: 1337, Amount: 1}, {Price: 1338, Amount: 1}, {Price: 1339, Amount: 1}, @@ -32,7 +32,7 @@ var ask = Tranches{ {Price: 1356, Amount: 1}, } -var bid = Tranches{ +var bid = Levels{ {Price: 1336, Amount: 1}, {Price: 1335, Amount: 1}, {Price: 1334, Amount: 1}, @@ -56,18 +56,18 @@ var bid = Tranches{ } // Display displays depth content for tests -func (ts Tranches) display() { - for x := range ts { - fmt.Printf("Tranche: %+v %p \n", ts[x], &ts[x]) +func (l Levels) display() { + for x := range l { + fmt.Printf("Level: %+v %p \n", l[x], &l[x]) } fmt.Println() } func TestLoad(t *testing.T) { - list := askTranches{} + list := askLevels{} Check(t, list, 0, 0, 0) - list.load(Tranches{ + list.load(Levels{ {Price: 1, Amount: 1}, {Price: 3, Amount: 1}, {Price: 5, Amount: 1}, @@ -78,7 +78,7 @@ func TestLoad(t *testing.T) { Check(t, list, 6, 36, 6) - list.load(Tranches{ + list.load(Levels{ {Price: 1, Amount: 1}, {Price: 3, Amount: 1}, {Price: 5, Amount: 1}, @@ -86,7 +86,7 @@ func TestLoad(t *testing.T) { Check(t, list, 3, 9, 3) - list.load(Tranches{ + list.load(Levels{ {Price: 1, Amount: 1}, {Price: 3, Amount: 1}, {Price: 5, Amount: 1}, @@ -103,15 +103,15 @@ func TestLoad(t *testing.T) { // 27906781 42.4 ns/op 0 B/op 0 allocs/op (old) // 84119028 13.87 ns/op 0 B/op 0 allocs/op (new) func BenchmarkLoad(b *testing.B) { - ts := Tranches{} + ts := Levels{} for b.Loop() { ts.load(ask) } } func TestUpdateInsertByPrice(t *testing.T) { - a := askTranches{} - asksSnapshot := Tranches{ + a := askLevels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1}, {Price: 3, Amount: 1}, {Price: 5, Amount: 1}, @@ -122,26 +122,26 @@ func TestUpdateInsertByPrice(t *testing.T) { a.load(asksSnapshot) // Update one instance with matching price - a.updateInsertByPrice(Tranches{{Price: 1, Amount: 2}}, 0) + a.updateInsertByPrice(Levels{{Price: 1, Amount: 2}}, 0) Check(t, a, 7, 37, 6) // Insert at head - a.updateInsertByPrice(Tranches{ + a.updateInsertByPrice(Levels{ {Price: 0.5, Amount: 2}, }, 0) Check(t, a, 9, 38, 7) // Insert at tail - a.updateInsertByPrice(Tranches{ + a.updateInsertByPrice(Levels{ {Price: 12, Amount: 2}, }, 0) Check(t, a, 11, 62, 8) // Insert between price and up to and beyond max allowable depth level - a.updateInsertByPrice(Tranches{ + a.updateInsertByPrice(Levels{ {Price: 11.5, Amount: 2}, {Price: 10.5, Amount: 2}, {Price: 13, Amount: 2}, @@ -150,17 +150,17 @@ func TestUpdateInsertByPrice(t *testing.T) { Check(t, a, 15, 106, 10) // delete at tail - a.updateInsertByPrice(Tranches{{Price: 12, Amount: 0}}, 0) + a.updateInsertByPrice(Levels{{Price: 12, Amount: 0}}, 0) Check(t, a, 13, 82, 9) // delete at mid - a.updateInsertByPrice(Tranches{{Price: 7, Amount: 0}}, 0) + a.updateInsertByPrice(Levels{{Price: 7, Amount: 0}}, 0) Check(t, a, 12, 75, 8) // delete at head - a.updateInsertByPrice(Tranches{{Price: 0.5, Amount: 0}}, 0) + a.updateInsertByPrice(Levels{{Price: 0.5, Amount: 0}}, 0) Check(t, a, 10, 74, 7) @@ -168,7 +168,7 @@ func TestUpdateInsertByPrice(t *testing.T) { a.load(nil) // rebuild everything again - a.updateInsertByPrice(Tranches{ + a.updateInsertByPrice(Levels{ {Price: 1, Amount: 1}, {Price: 3, Amount: 1}, {Price: 5, Amount: 1}, @@ -179,8 +179,8 @@ func TestUpdateInsertByPrice(t *testing.T) { Check(t, a, 6, 36, 6) - b := bidTranches{} - bidsSnapshot := Tranches{ + b := bidLevels{} + bidsSnapshot := Levels{ {Price: 11, Amount: 1}, {Price: 9, Amount: 1}, {Price: 7, Amount: 1}, @@ -191,22 +191,22 @@ func TestUpdateInsertByPrice(t *testing.T) { b.load(bidsSnapshot) // Update one instance with matching price - b.updateInsertByPrice(Tranches{{Price: 11, Amount: 2}}, 0) + b.updateInsertByPrice(Levels{{Price: 11, Amount: 2}}, 0) Check(t, b, 7, 47, 6) // Insert at head - b.updateInsertByPrice(Tranches{{Price: 12, Amount: 2}}, 0) + b.updateInsertByPrice(Levels{{Price: 12, Amount: 2}}, 0) Check(t, b, 9, 71, 7) // Insert at tail - b.updateInsertByPrice(Tranches{{Price: 0.5, Amount: 2}}, 0) + b.updateInsertByPrice(Levels{{Price: 0.5, Amount: 2}}, 0) Check(t, b, 11, 72, 8) // Insert between price and up to and beyond max allowable depth level - b.updateInsertByPrice(Tranches{ + b.updateInsertByPrice(Levels{ {Price: 11.5, Amount: 2}, {Price: 10.5, Amount: 2}, {Price: 13, Amount: 2}, @@ -215,17 +215,17 @@ func TestUpdateInsertByPrice(t *testing.T) { Check(t, b, 15, 141, 10) // Insert between price and up to and beyond max allowable depth level - b.updateInsertByPrice(Tranches{{Price: 1, Amount: 0}}, 0) + b.updateInsertByPrice(Levels{{Price: 1, Amount: 0}}, 0) Check(t, b, 14, 140, 9) // delete at mid - b.updateInsertByPrice(Tranches{{Price: 10.5, Amount: 0}}, 0) + b.updateInsertByPrice(Levels{{Price: 10.5, Amount: 0}}, 0) Check(t, b, 12, 119, 8) // delete at head - b.updateInsertByPrice(Tranches{{Price: 13, Amount: 0}}, 0) + b.updateInsertByPrice(Levels{{Price: 13, Amount: 0}}, 0) Check(t, b, 10, 93, 7) @@ -233,7 +233,7 @@ func TestUpdateInsertByPrice(t *testing.T) { b.load(nil) // rebuild everything again - b.updateInsertByPrice(Tranches{ + b.updateInsertByPrice(Levels{ {Price: 1, Amount: 1}, {Price: 3, Amount: 1}, {Price: 5, Amount: 1}, @@ -248,10 +248,10 @@ func TestUpdateInsertByPrice(t *testing.T) { // 134830672 9.83 ns/op 0 B/op 0 allocs/op (old) // 206689897 5.761 ns/op 0 B/op 0 allocs/op (new) func BenchmarkUpdateInsertByPrice_Amend(b *testing.B) { - a := askTranches{} + a := askLevels{} a.load(ask) - updates := Tranches{ + updates := Levels{ { Price: 1337, // Amend Amount: 2, @@ -270,11 +270,11 @@ func BenchmarkUpdateInsertByPrice_Amend(b *testing.B) { // 49763002 24.9 ns/op 0 B/op 0 allocs/op (old) // 25662849 45.32 ns/op 0 B/op 0 allocs/op (new) func BenchmarkUpdateInsertByPrice_Insert_Delete(b *testing.B) { - a := askTranches{} + a := askLevels{} a.load(ask) - updates := Tranches{ + updates := Levels{ { Price: 1337.5, // Insert Amount: 2, @@ -291,8 +291,8 @@ func BenchmarkUpdateInsertByPrice_Insert_Delete(b *testing.B) { } func TestUpdateByID(t *testing.T) { - a := askTranches{} - asksSnapshot := Tranches{ + a := askLevels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -302,7 +302,7 @@ func TestUpdateByID(t *testing.T) { } a.load(asksSnapshot) - err := a.updateByID(Tranches{ + err := a.updateByID(Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -316,12 +316,12 @@ func TestUpdateByID(t *testing.T) { Check(t, a, 6, 36, 6) - err = a.updateByID(Tranches{ + err = a.updateByID(Levels{ {Price: 11, Amount: 1, ID: 1337}, }) require.ErrorIs(t, err, errIDCannotBeMatched) - err = a.updateByID(Tranches{ // Simulate Bitmex updating + err = a.updateByID(Levels{ // Simulate Bitmex updating {Price: 0, Amount: 1337, ID: 3}, }) require.NoError(t, err) @@ -342,8 +342,8 @@ func TestUpdateByID(t *testing.T) { // 46043871 25.9 ns/op 0 B/op 0 allocs/op (old) // 63445401 18.51 ns/op 0 B/op 0 allocs/op (new) func BenchmarkUpdateByID(b *testing.B) { - asks := Tranches{} - asksSnapshot := Tranches{ + asks := Levels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -362,8 +362,8 @@ func BenchmarkUpdateByID(b *testing.B) { } func TestDeleteByID(t *testing.T) { - a := askTranches{} - asksSnapshot := Tranches{ + a := askLevels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -374,7 +374,7 @@ func TestDeleteByID(t *testing.T) { a.load(asksSnapshot) // Delete at head - err := a.deleteByID(Tranches{{Price: 1, Amount: 1, ID: 1}}, false) + err := a.deleteByID(Levels{{Price: 1, Amount: 1, ID: 1}}, false) if err != nil { t.Fatal(err) } @@ -382,7 +382,7 @@ func TestDeleteByID(t *testing.T) { Check(t, a, 5, 35, 5) // Delete at tail - err = a.deleteByID(Tranches{{Price: 1, Amount: 1, ID: 11}}, false) + err = a.deleteByID(Levels{{Price: 1, Amount: 1, ID: 11}}, false) if err != nil { t.Fatal(err) } @@ -390,7 +390,7 @@ func TestDeleteByID(t *testing.T) { Check(t, a, 4, 24, 4) // Delete in middle - err = a.deleteByID(Tranches{{Price: 1, Amount: 1, ID: 5}}, false) + err = a.deleteByID(Levels{{Price: 1, Amount: 1, ID: 5}}, false) if err != nil { t.Fatal(err) } @@ -398,11 +398,11 @@ func TestDeleteByID(t *testing.T) { Check(t, a, 3, 19, 3) // Intentional error - err = a.deleteByID(Tranches{{Price: 11, Amount: 1, ID: 1337}}, false) + err = a.deleteByID(Levels{{Price: 11, Amount: 1, ID: 1337}}, false) require.ErrorIs(t, err, errIDCannotBeMatched) // Error bypass - err = a.deleteByID(Tranches{{Price: 11, Amount: 1, ID: 1337}}, true) + err = a.deleteByID(Levels{{Price: 11, Amount: 1, ID: 1337}}, true) if err != nil { t.Fatal(err) } @@ -410,8 +410,8 @@ func TestDeleteByID(t *testing.T) { // 26724331 44.69 ns/op 0 B/op 0 allocs/op func BenchmarkDeleteByID(b *testing.B) { - asks := Tranches{} - asksSnapshot := Tranches{ + asks := Levels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -431,8 +431,8 @@ func BenchmarkDeleteByID(b *testing.B) { } func TestUpdateInsertByIDAsk(t *testing.T) { - a := askTranches{} - asksSnapshot := Tranches{ + a := askLevels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -443,7 +443,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { a.load(asksSnapshot) // Update one instance with matching ID - err := a.updateInsertByID(Tranches{{Price: 1, Amount: 2, ID: 1}}) + err := a.updateInsertByID(Levels{{Price: 1, Amount: 2, ID: 1}}) if err != nil { t.Fatal(err) } @@ -454,7 +454,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { a.load(asksSnapshot) // Update all instances with matching ID in order - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 5, Amount: 2, ID: 5}, @@ -469,7 +469,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 12, 72, 6) // Update all instances with matching ID in backwards - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 11, Amount: 2, ID: 11}, {Price: 9, Amount: 2, ID: 9}, {Price: 7, Amount: 2, ID: 7}, @@ -484,7 +484,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 12, 72, 6) // Update all instances with matching ID all over the ship - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 11, Amount: 2, ID: 11}, {Price: 3, Amount: 2, ID: 3}, {Price: 7, Amount: 2, ID: 7}, @@ -499,7 +499,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 12, 72, 6) // Update all instances move one before ID in middle - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 2, Amount: 2, ID: 5}, @@ -514,7 +514,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 12, 66, 6) // Update all instances move one before ID at head - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: .5, Amount: 2, ID: 5}, @@ -532,7 +532,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { a.load(asksSnapshot) // Update all instances move one after ID - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 8, Amount: 2, ID: 5}, @@ -550,7 +550,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { a.load(asksSnapshot) // Update all instances move one after ID to tail - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 12, Amount: 2, ID: 5}, @@ -565,7 +565,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 12, 86, 6) // Update all instances then pop new instance - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 12, Amount: 2, ID: 5}, @@ -584,7 +584,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { a.load(asksSnapshot) // Update all instances pop at head - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 0.5, Amount: 2, ID: 0}, {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, @@ -600,7 +600,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 14, 87, 7) // bookmark head and move to mid - err = a.updateInsertByID(Tranches{{Price: 7.5, Amount: 2, ID: 0}}) + err = a.updateInsertByID(Levels{{Price: 7.5, Amount: 2, ID: 0}}) if err != nil { t.Fatal(err) } @@ -608,7 +608,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 14, 101, 7) // bookmark head and move to tail - err = a.updateInsertByID(Tranches{{Price: 12.5, Amount: 2, ID: 1}}) + err = a.updateInsertByID(Levels{{Price: 12.5, Amount: 2, ID: 1}}) if err != nil { t.Fatal(err) } @@ -616,7 +616,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 14, 124, 7) // move tail location to head - err = a.updateInsertByID(Tranches{{Price: 2.5, Amount: 2, ID: 1}}) + err = a.updateInsertByID(Levels{{Price: 2.5, Amount: 2, ID: 1}}) if err != nil { t.Fatal(err) } @@ -624,7 +624,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 14, 104, 7) // move tail location to mid - err = a.updateInsertByID(Tranches{{Price: 8, Amount: 2, ID: 5}}) + err = a.updateInsertByID(Levels{{Price: 8, Amount: 2, ID: 5}}) if err != nil { t.Fatal(err) } @@ -632,7 +632,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 14, 96, 7) // insert at tail dont match - err = a.updateInsertByID(Tranches{{Price: 30, Amount: 2, ID: 1234}}) + err = a.updateInsertByID(Levels{{Price: 30, Amount: 2, ID: 1234}}) if err != nil { t.Fatal(err) } @@ -640,7 +640,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 16, 156, 8) // insert between last and 2nd last - err = a.updateInsertByID(Tranches{{Price: 12, Amount: 2, ID: 12345}}) + err = a.updateInsertByID(Levels{{Price: 12, Amount: 2, ID: 12345}}) if err != nil { t.Fatal(err) } @@ -648,7 +648,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 18, 180, 9) // readjust at end - err = a.updateInsertByID(Tranches{{Price: 29, Amount: 3, ID: 1234}}) + err = a.updateInsertByID(Levels{{Price: 29, Amount: 3, ID: 1234}}) if err != nil { t.Fatal(err) } @@ -656,7 +656,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { Check(t, a, 19, 207, 9) // readjust further and decrease price past tail - err = a.updateInsertByID(Tranches{{Price: 31, Amount: 3, ID: 1234}}) + err = a.updateInsertByID(Levels{{Price: 31, Amount: 3, ID: 1234}}) if err != nil { t.Fatal(err) } @@ -667,7 +667,7 @@ func TestUpdateInsertByIDAsk(t *testing.T) { a.load(nil) // insert with no liquidity and jumbled - err = a.updateInsertByID(Tranches{ + err = a.updateInsertByID(Levels{ {Price: 11, Amount: 2, ID: 11}, {Price: 9, Amount: 2, ID: 9}, {Price: 7, Amount: 2, ID: 7}, @@ -685,8 +685,8 @@ func TestUpdateInsertByIDAsk(t *testing.T) { // 21614455 81.74 ns/op 0 B/op 0 allocs/op func BenchmarkUpdateInsertByID_asks(b *testing.B) { - asks := Tranches{} - asksSnapshot := Tranches{ + asks := Levels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -705,8 +705,8 @@ func BenchmarkUpdateInsertByID_asks(b *testing.B) { } func TestUpdateInsertByIDBids(t *testing.T) { - b := bidTranches{} - bidsSnapshot := Tranches{ + b := bidLevels{} + bidsSnapshot := Levels{ {Price: 11, Amount: 1, ID: 11}, {Price: 9, Amount: 1, ID: 9}, {Price: 7, Amount: 1, ID: 7}, @@ -717,7 +717,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { b.load(bidsSnapshot) // Update one instance with matching ID - err := b.updateInsertByID(Tranches{{Price: 1, Amount: 2, ID: 1}}) + err := b.updateInsertByID(Levels{{Price: 1, Amount: 2, ID: 1}}) if err != nil { t.Fatal(err) } @@ -728,7 +728,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { b.load(bidsSnapshot) // Update all instances with matching ID in order - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 5, Amount: 2, ID: 5}, @@ -743,7 +743,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 12, 72, 6) // Update all instances with matching ID in backwards - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 11, Amount: 2, ID: 11}, {Price: 9, Amount: 2, ID: 9}, {Price: 7, Amount: 2, ID: 7}, @@ -758,7 +758,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 12, 72, 6) // Update all instances with matching ID all over the ship - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 11, Amount: 2, ID: 11}, {Price: 3, Amount: 2, ID: 3}, {Price: 7, Amount: 2, ID: 7}, @@ -773,7 +773,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 12, 72, 6) // Update all instances move one before ID in middle - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 2, Amount: 2, ID: 5}, @@ -788,7 +788,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 12, 66, 6) // Update all instances move one before ID at head - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: .5, Amount: 2, ID: 5}, @@ -806,7 +806,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { b.load(bidsSnapshot) // Update all instances move one after ID - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 8, Amount: 2, ID: 5}, @@ -824,7 +824,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { b.load(bidsSnapshot) // Update all instances move one after ID to tail - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 12, Amount: 2, ID: 5}, @@ -839,7 +839,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 12, 86, 6) // Update all instances then pop new instance - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, {Price: 12, Amount: 2, ID: 5}, @@ -858,7 +858,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { b.load(bidsSnapshot) // Update all instances pop at tail - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 0.5, Amount: 2, ID: 0}, {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, @@ -874,7 +874,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 14, 87, 7) // bookmark head and move to mid - err = b.updateInsertByID(Tranches{{Price: 9.5, Amount: 2, ID: 5}}) + err = b.updateInsertByID(Levels{{Price: 9.5, Amount: 2, ID: 5}}) if err != nil { t.Fatal(err) } @@ -882,7 +882,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 14, 82, 7) // bookmark head and move to tail - err = b.updateInsertByID(Tranches{{Price: 0.25, Amount: 2, ID: 11}}) + err = b.updateInsertByID(Levels{{Price: 0.25, Amount: 2, ID: 11}}) if err != nil { t.Fatal(err) } @@ -890,7 +890,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 14, 60.5, 7) // move tail location to head - err = b.updateInsertByID(Tranches{{Price: 10, Amount: 2, ID: 11}}) + err = b.updateInsertByID(Levels{{Price: 10, Amount: 2, ID: 11}}) if err != nil { t.Fatal(err) } @@ -898,7 +898,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 14, 80, 7) // move tail location to mid - err = b.updateInsertByID(Tranches{{Price: 7.5, Amount: 2, ID: 0}}) + err = b.updateInsertByID(Levels{{Price: 7.5, Amount: 2, ID: 0}}) if err != nil { t.Fatal(err) } @@ -906,7 +906,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 14, 94, 7) // insert at head dont match - err = b.updateInsertByID(Tranches{{Price: 30, Amount: 2, ID: 1234}}) + err = b.updateInsertByID(Levels{{Price: 30, Amount: 2, ID: 1234}}) if err != nil { t.Fatal(err) } @@ -914,21 +914,21 @@ func TestUpdateInsertByIDBids(t *testing.T) { Check(t, b, 16, 154, 8) // insert between last and 2nd last - err = b.updateInsertByID(Tranches{{Price: 1.5, Amount: 2, ID: 12345}}) + err = b.updateInsertByID(Levels{{Price: 1.5, Amount: 2, ID: 12345}}) if err != nil { t.Fatal(err) } Check(t, b, 18, 157, 9) // readjust at end - err = b.updateInsertByID(Tranches{{Price: 1, Amount: 3, ID: 1}}) + err = b.updateInsertByID(Levels{{Price: 1, Amount: 3, ID: 1}}) if err != nil { t.Fatal(err) } Check(t, b, 19, 158, 9) // readjust further and decrease price past tail - err = b.updateInsertByID(Tranches{{Price: .9, Amount: 3, ID: 1}}) + err = b.updateInsertByID(Levels{{Price: .9, Amount: 3, ID: 1}}) if err != nil { t.Fatal(err) } @@ -938,7 +938,7 @@ func TestUpdateInsertByIDBids(t *testing.T) { b.load(nil) // insert with no liquidity and jumbled - err = b.updateInsertByID(Tranches{ + err = b.updateInsertByID(Levels{ {Price: 0.5, Amount: 2, ID: 0}, {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, @@ -956,8 +956,8 @@ func TestUpdateInsertByIDBids(t *testing.T) { // 20328886 59.94 ns/op 0 B/op 0 allocs/op func BenchmarkUpdateInsertByID_bids(b *testing.B) { - bids := Tranches{} - bidsSnapshot := Tranches{ + bids := Levels{} + bidsSnapshot := Levels{ {Price: 0.5, Amount: 2, ID: 0}, {Price: 1, Amount: 2, ID: 1}, {Price: 3, Amount: 2, ID: 3}, @@ -977,8 +977,8 @@ func BenchmarkUpdateInsertByID_bids(b *testing.B) { } func TestInsertUpdatesBid(t *testing.T) { - b := bidTranches{} - bidsSnapshot := Tranches{ + b := bidLevels{} + bidsSnapshot := Levels{ {Price: 11, Amount: 1, ID: 11}, {Price: 9, Amount: 1, ID: 9}, {Price: 7, Amount: 1, ID: 7}, @@ -988,7 +988,7 @@ func TestInsertUpdatesBid(t *testing.T) { } b.load(bidsSnapshot) - err := b.insertUpdates(Tranches{ + err := b.insertUpdates(Levels{ {Price: 11, Amount: 1, ID: 11}, {Price: 9, Amount: 1, ID: 9}, {Price: 7, Amount: 1, ID: 7}, @@ -1001,7 +1001,7 @@ func TestInsertUpdatesBid(t *testing.T) { Check(t, b, 6, 36, 6) // Insert at head - err = b.insertUpdates(Tranches{{Price: 12, Amount: 1, ID: 11}}) + err = b.insertUpdates(Levels{{Price: 12, Amount: 1, ID: 11}}) if err != nil { t.Fatal(err) } @@ -1009,7 +1009,7 @@ func TestInsertUpdatesBid(t *testing.T) { Check(t, b, 7, 48, 7) // Insert at tail - err = b.insertUpdates(Tranches{{Price: 0.5, Amount: 1, ID: 12}}) + err = b.insertUpdates(Levels{{Price: 0.5, Amount: 1, ID: 12}}) if err != nil { t.Fatal(err) } @@ -1017,7 +1017,7 @@ func TestInsertUpdatesBid(t *testing.T) { Check(t, b, 8, 48.5, 8) // Insert at mid - err = b.insertUpdates(Tranches{{Price: 5.5, Amount: 1, ID: 13}}) + err = b.insertUpdates(Levels{{Price: 5.5, Amount: 1, ID: 13}}) if err != nil { t.Fatal(err) } @@ -1028,7 +1028,7 @@ func TestInsertUpdatesBid(t *testing.T) { b.load(nil) // Add one at head - err = b.insertUpdates(Tranches{{Price: 5.5, Amount: 1, ID: 13}}) + err = b.insertUpdates(Levels{{Price: 5.5, Amount: 1, ID: 13}}) if err != nil { t.Fatal(err) } @@ -1037,8 +1037,8 @@ func TestInsertUpdatesBid(t *testing.T) { } func TestInsertUpdatesAsk(t *testing.T) { - a := askTranches{} - askSnapshot := Tranches{ + a := askLevels{} + askSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -1048,7 +1048,7 @@ func TestInsertUpdatesAsk(t *testing.T) { } a.load(askSnapshot) - err := a.insertUpdates(Tranches{ + err := a.insertUpdates(Levels{ {Price: 11, Amount: 1, ID: 11}, {Price: 9, Amount: 1, ID: 9}, {Price: 7, Amount: 1, ID: 7}, @@ -1061,7 +1061,7 @@ func TestInsertUpdatesAsk(t *testing.T) { Check(t, a, 6, 36, 6) // Insert at tail - err = a.insertUpdates(Tranches{{Price: 12, Amount: 1, ID: 11}}) + err = a.insertUpdates(Levels{{Price: 12, Amount: 1, ID: 11}}) if err != nil { t.Fatal(err) } @@ -1069,7 +1069,7 @@ func TestInsertUpdatesAsk(t *testing.T) { Check(t, a, 7, 48, 7) // Insert at head - err = a.insertUpdates(Tranches{{Price: 0.5, Amount: 1, ID: 12}}) + err = a.insertUpdates(Levels{{Price: 0.5, Amount: 1, ID: 12}}) if err != nil { t.Fatal(err) } @@ -1077,7 +1077,7 @@ func TestInsertUpdatesAsk(t *testing.T) { Check(t, a, 8, 48.5, 8) // Insert at mid - err = a.insertUpdates(Tranches{{Price: 5.5, Amount: 1, ID: 13}}) + err = a.insertUpdates(Levels{{Price: 5.5, Amount: 1, ID: 13}}) if err != nil { t.Fatal(err) } @@ -1088,7 +1088,7 @@ func TestInsertUpdatesAsk(t *testing.T) { a.load(nil) // Add one at head - err = a.insertUpdates(Tranches{{Price: 5.5, Amount: 1, ID: 13}}) + err = a.insertUpdates(Levels{{Price: 5.5, Amount: 1, ID: 13}}) if err != nil { t.Fatal(err) } @@ -1099,65 +1099,59 @@ func TestInsertUpdatesAsk(t *testing.T) { // check checks depth values after an update has taken place func Check(t *testing.T, depth any, liquidity, value float64, expectedLen int) { t.Helper() - b, isBid := depth.(bidTranches) - a, isAsk := depth.(askTranches) + b, isBid := depth.(bidLevels) + a, isAsk := depth.(askLevels) - var ts Tranches + var l Levels switch { case isBid: - ts = b.Tranches + l = b.Levels case isAsk: - ts = a.Tranches + l = a.Levels default: t.Fatal("value passed in is not of type bids or asks") } - liquidityTotal, valueTotal := ts.amount() + liquidityTotal, valueTotal := l.amount() if liquidityTotal != liquidity { - ts.display() - t.Fatalf("mismatched liquidity expecting %v but received %v", - liquidity, - liquidityTotal) + l.display() + t.Fatalf("mismatched liquidity expecting %v but received %v", liquidity, liquidityTotal) } if valueTotal != value { - ts.display() - t.Fatalf("mismatched total value expecting %v but received %v", - value, - valueTotal) + l.display() + t.Fatalf("mismatched total value expecting %v but received %v", value, valueTotal) } - if len(ts) != expectedLen { - ts.display() - t.Fatalf("mismatched expected length count expecting %v but received %v", - expectedLen, - len(ts)) + if len(l) != expectedLen { + l.display() + t.Fatalf("mismatched expected length count expecting %v but received %v", expectedLen, len(l)) } - if len(ts) == 0 { + if len(l) == 0 { return } var price float64 - for x := range ts { + for x := range l { switch { case price == 0: - price = ts[x].Price - case isBid && price < ts[x].Price: - ts.display() + price = l[x].Price + case isBid && price < l[x].Price: + l.display() t.Fatal("Bid pricing out of order should be descending") - case isAsk && price > ts[x].Price: - ts.display() + case isAsk && price > l[x].Price: + l.display() t.Fatal("Ask pricing out of order should be ascending") default: - price = ts[x].Price + price = l[x].Price } } } func TestAmount(t *testing.T) { - a := askTranches{} - askSnapshot := Tranches{ + a := askLevels{} + askSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, @@ -1183,7 +1177,7 @@ func TestGetMovementByBaseAmount(t *testing.T) { Name string BaseAmount float64 ReferencePrice float64 - BidLiquidity Tranches + BidLiquidity Levels ExpectedNominal float64 ExpectedImpact float64 ExpectedCost float64 @@ -1206,7 +1200,7 @@ func TestGetMovementByBaseAmount(t *testing.T) { }, { Name: "thrasher test", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, BaseAmount: 10, ReferencePrice: 10000, ExpectedNominal: 0.8999999999999999, @@ -1214,8 +1208,8 @@ func TestGetMovementByBaseAmount(t *testing.T) { ExpectedCost: 900, }, { - Name: "consume first tranche", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + Name: "consume first level", + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, BaseAmount: 2, ReferencePrice: 10000, ExpectedNominal: 0, @@ -1223,8 +1217,8 @@ func TestGetMovementByBaseAmount(t *testing.T) { ExpectedCost: 0, }, { - Name: "consume most of first tranche", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + Name: "consume most of first level", + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, BaseAmount: 1.5, ReferencePrice: 10000, ExpectedNominal: 0, @@ -1233,7 +1227,7 @@ func TestGetMovementByBaseAmount(t *testing.T) { }, { Name: "consume full liquidity", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, BaseAmount: 12, ReferencePrice: 10000, ExpectedNominal: 1.0833333333333395, @@ -1250,7 +1244,7 @@ func TestGetMovementByBaseAmount(t *testing.T) { if err != nil { t.Fatal(err) } - movement, err := depth.bidTranches.getMovementByBase(tt.BaseAmount, tt.ReferencePrice, false) + movement, err := depth.bidLevels.getMovementByBase(tt.BaseAmount, tt.ReferencePrice, false) require.ErrorIs(t, err, tt.ExpectedError) if movement == nil { @@ -1291,7 +1285,7 @@ func TestGetBaseAmountFromNominalSlippage(t *testing.T) { Name string NominalSlippage float64 ReferencePrice float64 - BidLiquidity Tranches + BidLiquidity Levels ExpectedShift *Movement ExpectedError error }{ @@ -1318,7 +1312,7 @@ func TestGetBaseAmountFromNominalSlippage(t *testing.T) { }, { Name: "thrasher test", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, NominalSlippage: 1, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1331,8 +1325,8 @@ func TestGetBaseAmountFromNominalSlippage(t *testing.T) { }, }, { - Name: "consume first tranche - take one amount out of second", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + Name: "consume first level - take one amount out of second", + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, NominalSlippage: 0.33333333333334, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1346,7 +1340,7 @@ func TestGetBaseAmountFromNominalSlippage(t *testing.T) { }, { Name: "consume full liquidity", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, NominalSlippage: 10, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1361,7 +1355,7 @@ func TestGetBaseAmountFromNominalSlippage(t *testing.T) { }, { Name: "scotts lovely slippery slippage requirements", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, NominalSlippage: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000001, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1381,7 +1375,7 @@ func TestGetBaseAmountFromNominalSlippage(t *testing.T) { err := depth.LoadSnapshot(tt.BidLiquidity, nil, 0, time.Now(), time.Now(), true) assert.NoError(t, err, "LoadSnapshot should not error") - base, err := depth.bidTranches.hitBidsByNominalSlippage(tt.NominalSlippage, tt.ReferencePrice) + base, err := depth.bidLevels.hitBidsByNominalSlippage(tt.NominalSlippage, tt.ReferencePrice) if tt.ExpectedError != nil { assert.ErrorIs(t, err, tt.ExpectedError, "Should error correctly") } else { @@ -1412,7 +1406,7 @@ func TestGetBaseAmountFromImpact(t *testing.T) { Name string ImpactSlippage float64 ReferencePrice float64 - BidLiquidity Tranches + BidLiquidity Levels ExpectedShift *Movement ExpectedError error }{ @@ -1438,7 +1432,7 @@ func TestGetBaseAmountFromImpact(t *testing.T) { }, { Name: "thrasher test", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, ImpactSlippage: 1, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1451,8 +1445,8 @@ func TestGetBaseAmountFromImpact(t *testing.T) { }, }, { - Name: "consume first tranche and second tranche", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + Name: "consume first level and second level", + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, ImpactSlippage: 2, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1466,7 +1460,7 @@ func TestGetBaseAmountFromImpact(t *testing.T) { }, { Name: "consume full liquidity", - BidLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, + BidLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 9900, Amount: 7}, {Price: 9800, Amount: 3}}, ImpactSlippage: 10, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1489,7 +1483,7 @@ func TestGetBaseAmountFromImpact(t *testing.T) { if err != nil { t.Fatal(err) } - base, err := depth.bidTranches.hitBidsByImpactSlippage(tt.ImpactSlippage, tt.ReferencePrice) + base, err := depth.bidLevels.hitBidsByImpactSlippage(tt.ImpactSlippage, tt.ReferencePrice) require.ErrorIs(t, err, tt.ExpectedError) if !base.IsEqual(tt.ExpectedShift) { @@ -1506,7 +1500,7 @@ func TestGetMovementByQuoteAmount(t *testing.T) { Name string QuoteAmount float64 ReferencePrice float64 - AskLiquidity Tranches + AskLiquidity Levels ExpectedNominal float64 ExpectedImpact float64 ExpectedCost float64 @@ -1529,7 +1523,7 @@ func TestGetMovementByQuoteAmount(t *testing.T) { }, { Name: "thrasher test", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, QuoteAmount: 100900, ReferencePrice: 10000, ExpectedNominal: 0.8999999999999999, @@ -1537,8 +1531,8 @@ func TestGetMovementByQuoteAmount(t *testing.T) { ExpectedCost: 900, }, { - Name: "consume first tranche", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + Name: "consume first level", + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, QuoteAmount: 20000, ReferencePrice: 10000, ExpectedNominal: 0, @@ -1546,8 +1540,8 @@ func TestGetMovementByQuoteAmount(t *testing.T) { ExpectedCost: 0, }, { - Name: "consume most of first tranche", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + Name: "consume most of first level", + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, QuoteAmount: 15000, ReferencePrice: 10000, ExpectedNominal: 0, @@ -1556,7 +1550,7 @@ func TestGetMovementByQuoteAmount(t *testing.T) { }, { Name: "consume full liquidity", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, QuoteAmount: 121300, ReferencePrice: 10000, ExpectedNominal: 1.0833333333333395, @@ -1573,7 +1567,7 @@ func TestGetMovementByQuoteAmount(t *testing.T) { if err != nil { t.Fatal(err) } - movement, err := depth.askTranches.getMovementByQuotation(tt.QuoteAmount, tt.ReferencePrice, false) + movement, err := depth.askLevels.getMovementByQuotation(tt.QuoteAmount, tt.ReferencePrice, false) require.ErrorIs(t, err, tt.ExpectedError) if movement == nil { @@ -1603,7 +1597,7 @@ func TestGetQuoteAmountFromNominalSlippage(t *testing.T) { Name string NominalSlippage float64 ReferencePrice float64 - AskLiquidity Tranches + AskLiquidity Levels ExpectedShift *Movement ExpectedError error }{ @@ -1624,8 +1618,8 @@ func TestGetQuoteAmountFromNominalSlippage(t *testing.T) { ExpectedError: errNoLiquidity, }, { - Name: "consume first tranche - one amount on second tranche", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + Name: "consume first level - one amount on second level", + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, NominalSlippage: 0.33333333333334, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1638,8 +1632,8 @@ func TestGetQuoteAmountFromNominalSlippage(t *testing.T) { }, }, { - Name: "last tranche total agg meeting 1 percent nominally", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + Name: "last level total agg meeting 1 percent nominally", + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, NominalSlippage: 1, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1652,8 +1646,8 @@ func TestGetQuoteAmountFromNominalSlippage(t *testing.T) { }, }, { - Name: "take full second tranche", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + Name: "take full second level", + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, NominalSlippage: 0.7777777777777738, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1667,7 +1661,7 @@ func TestGetQuoteAmountFromNominalSlippage(t *testing.T) { }, { Name: "consume full liquidity", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, NominalSlippage: 10, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1682,7 +1676,7 @@ func TestGetQuoteAmountFromNominalSlippage(t *testing.T) { }, { Name: "scotts lovely slippery slippage requirements", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, NominalSlippage: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000001, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1702,7 +1696,7 @@ func TestGetQuoteAmountFromNominalSlippage(t *testing.T) { err := depth.LoadSnapshot(nil, tt.AskLiquidity, 0, time.Now(), time.Now(), true) assert.NoError(t, err, "LoadSnapshot should not error") - quote, err := depth.askTranches.liftAsksByNominalSlippage(tt.NominalSlippage, tt.ReferencePrice) + quote, err := depth.askLevels.liftAsksByNominalSlippage(tt.NominalSlippage, tt.ReferencePrice) if tt.ExpectedError != nil { assert.ErrorIs(t, err, tt.ExpectedError, "Should error correctly") } else { @@ -1718,7 +1712,7 @@ func TestGetQuoteAmountFromImpact(t *testing.T) { Name string ImpactSlippage float64 ReferencePrice float64 - AskLiquidity Tranches + AskLiquidity Levels ExpectedShift *Movement ExpectedError error }{ @@ -1740,7 +1734,7 @@ func TestGetQuoteAmountFromImpact(t *testing.T) { }, { Name: "thrasher test", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, ImpactSlippage: 1, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1753,8 +1747,8 @@ func TestGetQuoteAmountFromImpact(t *testing.T) { }, }, { - Name: "consume first tranche and second tranche", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + Name: "consume first level and second level", + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, ImpactSlippage: 2, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1768,7 +1762,7 @@ func TestGetQuoteAmountFromImpact(t *testing.T) { }, { Name: "consume full liquidity", - AskLiquidity: Tranches{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, + AskLiquidity: Levels{{Price: 10000, Amount: 2}, {Price: 10100, Amount: 7}, {Price: 10200, Amount: 3}}, ImpactSlippage: 10, ReferencePrice: 10000, ExpectedShift: &Movement{ @@ -1790,7 +1784,7 @@ func TestGetQuoteAmountFromImpact(t *testing.T) { err := depth.LoadSnapshot(nil, tt.AskLiquidity, 0, time.Now(), time.Now(), true) assert.NoError(t, err, "LoadSnapshot should not error") - quote, err := depth.askTranches.liftAsksByImpactSlippage(tt.ImpactSlippage, tt.ReferencePrice) + quote, err := depth.askLevels.liftAsksByImpactSlippage(tt.ImpactSlippage, tt.ReferencePrice) if tt.ExpectedError != nil { assert.ErrorIs(t, err, tt.ExpectedError, "Should error correctly") } else { @@ -1803,22 +1797,22 @@ func TestGetQuoteAmountFromImpact(t *testing.T) { func TestGetHeadPrice(t *testing.T) { t.Parallel() depth := NewDepth(id) - _, err := depth.bidTranches.getHeadPriceNoLock() + _, err := depth.bidLevels.getHeadPriceNoLock() require.ErrorIs(t, err, errNoLiquidity) - _, err = depth.askTranches.getHeadPriceNoLock() + _, err = depth.askLevels.getHeadPriceNoLock() require.ErrorIs(t, err, errNoLiquidity) err = depth.LoadSnapshot(bid, ask, 0, time.Now(), time.Now(), true) require.NoError(t, err, "LoadSnapshot must not error") - val, err := depth.bidTranches.getHeadPriceNoLock() + val, err := depth.bidLevels.getHeadPriceNoLock() require.NoError(t, err) if val != 1336 { t.Fatal("unexpected value") } - val, err = depth.askTranches.getHeadPriceNoLock() + val, err = depth.askLevels.getHeadPriceNoLock() require.NoError(t, err) if val != 1337 { @@ -1845,8 +1839,8 @@ func TestFinalizeFields(t *testing.T) { // 8384302 150.9 ns/op 480 B/op 1 allocs/op func BenchmarkRetrieve(b *testing.B) { - asks := Tranches{} - asksSnapshot := Tranches{ + asks := Levels{} + asksSnapshot := Levels{ {Price: 1, Amount: 1, ID: 1}, {Price: 3, Amount: 1, ID: 3}, {Price: 5, Amount: 1, ID: 5}, diff --git a/exchanges/orderbook/orderbook.go b/exchanges/orderbook/orderbook.go index c2f06f2e..ae5b1289 100644 --- a/exchanges/orderbook/orderbook.go +++ b/exchanges/orderbook/orderbook.go @@ -13,7 +13,7 @@ import ( ) // Get checks and returns the orderbook given an exchange name and currency pair -func Get(exchange string, p currency.Pair, a asset.Item) (*Base, error) { +func Get(exchange string, p currency.Pair, a asset.Item) (*Book, error) { return s.Retrieve(exchange, p, a) } @@ -41,7 +41,7 @@ func SubscribeToExchangeOrderbooks(exchange string) (dispatch.Pipe, error) { } // Update stores orderbook data -func (s *store) Update(b *Base) error { +func (s *store) Update(b *Book) error { s.m.RLock() book, ok := s.orderbooks[key.ExchangePairAsset{Exchange: b.Exchange, Base: b.Pair.Base.Item, Quote: b.Pair.Quote.Item, Asset: b.Asset}] s.m.RUnlock() @@ -58,7 +58,7 @@ func (s *store) Update(b *Base) error { return s.signalMux.Publish(book.Depth, book.RouterID) } -func (s *store) track(b *Base) (book, error) { +func (s *store) track(b *Book) (book, error) { s.m.Lock() defer s.m.Unlock() id, ok := s.exchangeRouters[b.Exchange] @@ -94,7 +94,7 @@ func (s *store) DeployDepth(exchange string, p currency.Pair, a asset.Item) (*De s.m.RUnlock() var err error if !ok { - ob, err = s.track(&Base{Exchange: exchange, Pair: p, Asset: a}) + ob, err = s.track(&Book{Exchange: exchange, Pair: p, Asset: a}) } return ob.Depth, err } @@ -110,9 +110,9 @@ func (s *store) GetDepth(exchange string, p currency.Pair, a asset.Item) (*Depth return ob.Depth, nil } -// Retrieve gets orderbook depth data from the stored tranches and returns the +// Retrieve gets orderbook depth data from the stored Levels and returns the // base equivalent copy -func (s *store) Retrieve(exchange string, p currency.Pair, a asset.Item) (*Base, error) { +func (s *store) Retrieve(exchange string, p currency.Pair, a asset.Item) (*Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -129,13 +129,13 @@ func (s *store) Retrieve(exchange string, p currency.Pair, a asset.Item) (*Base, } // GetDepth returns the concrete book allowing the caller to stream orderbook changes -func (b *Base) GetDepth() (*Depth, error) { +func (b *Book) GetDepth() (*Depth, error) { return s.GetDepth(b.Exchange, b.Pair, b.Asset) } // TotalBidsAmount returns the total amount of bids and the total orderbook // bids value -func (b *Base) TotalBidsAmount() (amountCollated, total float64) { +func (b *Book) TotalBidsAmount() (amountCollated, total float64) { for x := range b.Bids { amountCollated += b.Bids[x].Amount total += b.Bids[x].Amount * b.Bids[x].Price @@ -145,7 +145,7 @@ func (b *Base) TotalBidsAmount() (amountCollated, total float64) { // TotalAsksAmount returns the total amount of asks and the total orderbook // asks value -func (b *Base) TotalAsksAmount() (amountCollated, total float64) { +func (b *Book) TotalAsksAmount() (amountCollated, total float64) { for y := range b.Asks { amountCollated += b.Asks[y].Amount total += b.Asks[y].Amount * b.Asks[y].Price @@ -157,7 +157,7 @@ func (b *Base) TotalAsksAmount() (amountCollated, total float64) { // set and will reject any book with incorrect values. // Bids should always go from a high price to a low price and // Asks should always go from a low price to a higher price -func (b *Base) Verify() error { +func (b *Book) Verify() error { if !b.VerifyOrderbook { return nil } @@ -189,10 +189,10 @@ func (b *Base) Verify() error { // checker defines specific functionality to determine ascending/descending // validation -type checker func(current, previous Tranche) error +type checker func(current, previous Level) error // asc specifically defines ascending price check -var asc = func(current, previous Tranche) error { +var asc = func(current, previous Level) error { if current.Price < previous.Price { return errPriceOutOfOrder } @@ -200,7 +200,7 @@ var asc = func(current, previous Tranche) error { } // dsc specifically defines descending price check -var dsc = func(current, previous Tranche) error { +var dsc = func(current, previous Level) error { if current.Price > previous.Price { return errPriceOutOfOrder } @@ -208,7 +208,7 @@ var dsc = func(current, previous Tranche) error { } // checkAlignment validates full orderbook -func checkAlignment(depth Tranches, fundingRate, priceDuplication, isIDAligned, requiresChecksumString bool, c checker, exch string) error { +func checkAlignment(depth Levels, fundingRate, priceDuplication, isIDAligned, requiresChecksumString bool, c checker, exch string) error { for i := range depth { if depth[i].Price == 0 { switch { @@ -249,7 +249,7 @@ func checkAlignment(depth Tranches, fundingRate, priceDuplication, isIDAligned, // Process processes incoming orderbooks, creating or updating the orderbook // list -func (b *Base) Process() error { +func (b *Book) Process() error { if b.Exchange == "" { return errExchangeNameUnset } @@ -278,25 +278,25 @@ func (b *Base) Process() error { // using a sort algorithm as the algorithm could be impeded by a worst case time // complexity when elements are shifted as opposed to just swapping element // values. -func (ts *Tranches) Reverse() { - eLen := len(*ts) +func (l *Levels) Reverse() { + eLen := len(*l) var target int for i := eLen/2 - 1; i >= 0; i-- { target = eLen - 1 - i - (*ts)[i], (*ts)[target] = (*ts)[target], (*ts)[i] + (*l)[i], (*l)[target] = (*l)[target], (*l)[i] } } // SortAsks sorts ask items to the correct ascending order if pricing values are // scattered. If order from exchange is descending consider using the Reverse // function. -func (ts Tranches) SortAsks() { - sort.Slice(ts, func(i, j int) bool { return ts[i].Price < ts[j].Price }) +func (l Levels) SortAsks() { + sort.Slice(l, func(i, j int) bool { return l[i].Price < l[j].Price }) } // SortBids sorts bid items to the correct descending order if pricing values // are scattered. If order from exchange is ascending consider using the Reverse // function. -func (ts Tranches) SortBids() { - sort.Slice(ts, func(i, j int) bool { return ts[i].Price > ts[j].Price }) +func (l Levels) SortBids() { + sort.Slice(l, func(i, j int) bool { return l[i].Price > l[j].Price }) } diff --git a/exchanges/orderbook/orderbook_test.go b/exchanges/orderbook/orderbook_test.go index 8a8a6c8b..20733527 100644 --- a/exchanges/orderbook/orderbook_test.go +++ b/exchanges/orderbook/orderbook_test.go @@ -32,11 +32,11 @@ func TestSubscribeToExchangeOrderbooks(t *testing.T) { p := currency.NewBTCUSD() - b := Base{ + b := Book{ Pair: p, Asset: asset.Spot, Exchange: "SubscribeToExchangeOrderbooks", - Bids: []Tranche{{Price: 100, Amount: 1}, {Price: 99, Amount: 1}}, + Bids: []Level{{Price: 100, Amount: 1}, {Price: 99, Amount: 1}}, } require.NoError(t, b.Process(), "process must not error") @@ -47,7 +47,7 @@ func TestSubscribeToExchangeOrderbooks(t *testing.T) { func TestVerify(t *testing.T) { t.Parallel() - b := Base{ + b := Book{ Exchange: "TestExchange", Asset: asset.Spot, Pair: currency.NewBTCUSD(), @@ -59,15 +59,15 @@ func TestVerify(t *testing.T) { t.Fatalf("expecting %v error but received %v", nil, err) } - b.Asks = []Tranche{{ID: 1337, Price: 99, Amount: 1}, {ID: 1337, Price: 100, Amount: 1}} + b.Asks = []Level{{ID: 1337, Price: 99, Amount: 1}, {ID: 1337, Price: 100, Amount: 1}} err = b.Verify() require.ErrorIs(t, err, errIDDuplication) - b.Asks = []Tranche{{Price: 100, Amount: 1}, {Price: 100, Amount: 1}} + b.Asks = []Level{{Price: 100, Amount: 1}, {Price: 100, Amount: 1}} err = b.Verify() require.ErrorIs(t, err, errDuplication) - b.Asks = []Tranche{{Price: 100, Amount: 1}, {Price: 99, Amount: 1}} + b.Asks = []Level{{Price: 100, Amount: 1}, {Price: 99, Amount: 1}} b.IsFundingRate = true err = b.Verify() require.ErrorIs(t, err, errPeriodUnset) @@ -77,23 +77,23 @@ func TestVerify(t *testing.T) { err = b.Verify() require.ErrorIs(t, err, errPriceOutOfOrder) - b.Asks = []Tranche{{Price: 100, Amount: 1}, {Price: 100, Amount: 0}} + b.Asks = []Level{{Price: 100, Amount: 1}, {Price: 100, Amount: 0}} err = b.Verify() require.ErrorIs(t, err, errAmountInvalid) - b.Asks = []Tranche{{Price: 100, Amount: 1}, {Price: 0, Amount: 100}} + b.Asks = []Level{{Price: 100, Amount: 1}, {Price: 0, Amount: 100}} err = b.Verify() require.ErrorIs(t, err, errPriceNotSet) - b.Bids = []Tranche{{ID: 1337, Price: 100, Amount: 1}, {ID: 1337, Price: 99, Amount: 1}} + b.Bids = []Level{{ID: 1337, Price: 100, Amount: 1}, {ID: 1337, Price: 99, Amount: 1}} err = b.Verify() require.ErrorIs(t, err, errIDDuplication) - b.Bids = []Tranche{{Price: 100, Amount: 1}, {Price: 100, Amount: 1}} + b.Bids = []Level{{Price: 100, Amount: 1}, {Price: 100, Amount: 1}} err = b.Verify() require.ErrorIs(t, err, errDuplication) - b.Bids = []Tranche{{Price: 99, Amount: 1}, {Price: 100, Amount: 1}} + b.Bids = []Level{{Price: 99, Amount: 1}, {Price: 100, Amount: 1}} b.IsFundingRate = true err = b.Verify() require.ErrorIs(t, err, errPeriodUnset) @@ -103,73 +103,62 @@ func TestVerify(t *testing.T) { err = b.Verify() require.ErrorIs(t, err, errPriceOutOfOrder) - b.Bids = []Tranche{{Price: 100, Amount: 1}, {Price: 100, Amount: 0}} + b.Bids = []Level{{Price: 100, Amount: 1}, {Price: 100, Amount: 0}} err = b.Verify() require.ErrorIs(t, err, errAmountInvalid) - b.Bids = []Tranche{{Price: 100, Amount: 1}, {Price: 0, Amount: 100}} + b.Bids = []Level{{Price: 100, Amount: 1}, {Price: 0, Amount: 100}} err = b.Verify() require.ErrorIs(t, err, errPriceNotSet) } -func TestCalculateTotalBids(t *testing.T) { +func TestTotalBidsAmount(t *testing.T) { t.Parallel() - base := Base{ - Pair: currency.NewBTCUSD(), - Bids: []Tranche{{Price: 100, Amount: 10}}, - LastUpdated: time.Now(), - } - - a, b := base.TotalBidsAmount() - if a != 10 && b != 1000 { - t.Fatal("TestCalculateTotalBids expected a = 10 and b = 1000") - } + b := Book{Pair: currency.NewBTCUSD(), Bids: []Level{{Price: 100, Amount: 10}}, LastUpdated: time.Now()} + ac, total := b.TotalBidsAmount() + assert.Equal(t, 10.0, ac, "should return amount") + assert.Equal(t, 1000.0, total, "should return total") } -func TestCalculateTotalAsks(t *testing.T) { +func TestTotalAsksAmount(t *testing.T) { t.Parallel() - base := Base{ - Pair: currency.NewBTCUSD(), - Asks: []Tranche{{Price: 100, Amount: 10}}, - } - - a, b := base.TotalAsksAmount() - if a != 10 && b != 1000 { - t.Fatal("TestCalculateTotalAsks expected a = 10 and b = 1000") - } + b := Book{Pair: currency.NewBTCUSD(), Asks: []Level{{Price: 100, Amount: 10}}} + ac, total := b.TotalAsksAmount() + assert.Equal(t, 10.0, ac, "should return correct amount") + assert.Equal(t, 1000.0, total, "should return correct total") } func TestGetOrderbook(t *testing.T) { t.Parallel() - c := currency.NewBTCUSD() - base := &Base{ - Pair: c, - Asks: []Tranche{{Price: 100, Amount: 10}}, - Bids: []Tranche{{Price: 200, Amount: 10}}, + pair := currency.NewBTCUSD() + b := &Book{ + Pair: pair, + Asks: []Level{{Price: 100, Amount: 10}}, + Bids: []Level{{Price: 200, Amount: 10}}, Exchange: "Exchange", Asset: asset.Spot, } - require.NoError(t, base.Process(), "Process must not error") + require.NoError(t, b.Process(), "Process must not error") - result, err := Get("Exchange", c, asset.Spot) + result, err := Get("Exchange", pair, asset.Spot) require.NoError(t, err, "Get must not error") - assert.True(t, result.Pair.Equal(c)) + assert.True(t, result.Pair.Equal(pair)) - _, err = Get("nonexistent", c, asset.Spot) + _, err = Get("nonexistent", pair, asset.Spot) assert.ErrorIs(t, err, ErrOrderbookNotFound) - c.Base = currency.NewCode("blah") - _, err = Get("Exchange", c, asset.Spot) + pair.Base = currency.NewCode("blah") + _, err = Get("Exchange", pair, asset.Spot) assert.ErrorIs(t, err, ErrOrderbookNotFound) newCurrency := currency.NewPair(currency.BTC, currency.AUD) _, err = Get("Exchange", newCurrency, asset.Spot) assert.ErrorIs(t, err, ErrOrderbookNotFound) - base.Pair = newCurrency - require.NoError(t, base.Process(), "Process must not error") + b.Pair = newCurrency + require.NoError(t, b.Process(), "Process must not error") got, err := Get("Exchange", newCurrency, asset.Spot) require.NoError(t, err, "Get must not error") @@ -179,218 +168,152 @@ func TestGetOrderbook(t *testing.T) { func TestGetDepth(t *testing.T) { t.Parallel() - c := currency.NewBTCUSD() - base := &Base{ - Pair: c, - Asks: []Tranche{{Price: 100, Amount: 10}}, - Bids: []Tranche{{Price: 200, Amount: 10}}, + pair := currency.NewBTCUSD() + b := &Book{ + Pair: pair, + Asks: []Level{{Price: 100, Amount: 10}}, + Bids: []Level{{Price: 200, Amount: 10}}, Exchange: "Exchange", Asset: asset.Spot, } - require.NoError(t, base.Process(), "Process must not error") + require.NoError(t, b.Process(), "Process must not error") - result, err := GetDepth("Exchange", c, asset.Spot) + result, err := GetDepth("Exchange", pair, asset.Spot) require.NoError(t, err, "GetDepth must not error") - assert.True(t, result.pair.Equal(c)) + assert.True(t, result.pair.Equal(pair)) - _, err = GetDepth("nonexistent", c, asset.Spot) + _, err = GetDepth("nonexistent", pair, asset.Spot) assert.ErrorIs(t, err, ErrOrderbookNotFound) - c.Base = currency.NewCode("blah") - _, err = GetDepth("Exchange", c, asset.Spot) + pair.Base = currency.NewCode("blah") + _, err = GetDepth("Exchange", pair, asset.Spot) assert.ErrorIs(t, err, ErrOrderbookNotFound) newCurrency := currency.NewPair(currency.BTC, currency.DOGE) _, err = GetDepth("Exchange", newCurrency, asset.Futures) assert.ErrorIs(t, err, ErrOrderbookNotFound) - base.Pair = newCurrency - require.NoError(t, base.Process(), "Process must not error") + b.Pair = newCurrency + require.NoError(t, b.Process(), "Process must not error") _, err = GetDepth("Exchange", newCurrency, asset.Empty) assert.ErrorIs(t, err, ErrOrderbookNotFound) } -func TestBaseGetDepth(t *testing.T) { +func TestBookGetDepth(t *testing.T) { t.Parallel() - c := currency.NewPair(currency.BTC, currency.UST) - base := &Base{ - Pair: c, - Asks: []Tranche{{Price: 100, Amount: 10}}, - Bids: []Tranche{{Price: 200, Amount: 10}}, + pair := currency.NewPair(currency.BTC, currency.UST) + b := &Book{ + Pair: pair, + Asks: []Level{{Price: 100, Amount: 10}}, + Bids: []Level{{Price: 200, Amount: 10}}, Exchange: "Exchange", Asset: asset.Spot, } - _, err := base.GetDepth() + _, err := b.GetDepth() assert.ErrorIs(t, err, ErrOrderbookNotFound) - require.NoError(t, base.Process(), "Process must not error") + require.NoError(t, b.Process(), "Process must not error") - result, err := base.GetDepth() + result, err := b.GetDepth() require.NoError(t, err, "GetDepth must not error") - assert.True(t, result.pair.Equal(c)) + assert.True(t, result.pair.Equal(pair)) } func TestDeployDepth(t *testing.T) { - c := currency.NewBTCUSD() - _, err := DeployDepth("", c, asset.Spot) + pair := currency.NewBTCUSD() + _, err := DeployDepth("", pair, asset.Spot) require.ErrorIs(t, err, errExchangeNameUnset) _, err = DeployDepth("test", currency.EMPTYPAIR, asset.Spot) require.ErrorIs(t, err, errPairNotSet) - _, err = DeployDepth("test", c, asset.Empty) + _, err = DeployDepth("test", pair, asset.Empty) require.ErrorIs(t, err, errAssetTypeNotSet) - d, err := DeployDepth("test", c, asset.Spot) + d, err := DeployDepth("test", pair, asset.Spot) require.NoError(t, err) require.NotNil(t, d) - _, err = DeployDepth("test", c, asset.Spot) + _, err = DeployDepth("test", pair, asset.Spot) require.NoError(t, err) } -func TestCreateNewOrderbook(t *testing.T) { - c := currency.NewBTCUSD() - base := &Base{ - Pair: c, - Asks: []Tranche{{Price: 100, Amount: 10}}, - Bids: []Tranche{{Price: 200, Amount: 10}}, - Exchange: "testCreateNewOrderbook", - Asset: asset.Spot, - } - - err := base.Process() - require.NoError(t, err, "Process must not error") - - result, err := Get("testCreateNewOrderbook", c, asset.Spot) - if err != nil { - t.Fatal("TestCreateNewOrderbook failed to create new orderbook", err) - } - - if !result.Pair.Equal(c) { - t.Fatal("TestCreateNewOrderbook result pair is incorrect") - } - - a, b := result.TotalAsksAmount() - if a != 10 && b != 1000 { - t.Fatal("TestCreateNewOrderbook CalculateTotalAsks value is incorrect") - } - - a, b = result.TotalBidsAmount() - if a != 10 && b != 2000 { - t.Fatal("TestCreateNewOrderbook CalculateTotalBids value is incorrect") - } -} - func TestProcessOrderbook(t *testing.T) { - base := Base{ - Asks: []Tranche{{Price: 100, Amount: 10}}, - Bids: []Tranche{{Price: 200, Amount: 10}}, + b := Book{ + Asks: []Level{{Price: 100, Amount: 10}}, + Bids: []Level{{Price: 200, Amount: 10}}, Exchange: "ProcessOrderbook", } // test for empty pair - base.Pair = currency.EMPTYPAIR - err := base.Process() + err := b.Process() assert.ErrorIs(t, err, errPairNotSet) // test for empty asset type - c := currency.NewBTCUSD() - base.Pair = c - err = base.Process() - if err == nil { - t.Error("empty asset type should throw an err") - } + pair := currency.NewBTCUSD() + b.Pair = pair + err = b.Process() + require.ErrorIs(t, err, errAssetTypeNotSet) // now process a valid orderbook - base.Asset = asset.Spot - err = base.Process() - if err != nil { - t.Error("unexpected result: ", err) - } - result, err := Get("ProcessOrderbook", c, asset.Spot) - if err != nil { - t.Fatal("TestProcessOrderbook failed to create new orderbook") - } - if !result.Pair.Equal(c) { - t.Fatal("TestProcessOrderbook result pair is incorrect") - } + b.Asset = asset.Spot + require.NoError(t, b.Process(), "Process must not error") + + result, err := Get("ProcessOrderbook", currency.NewBTCUSD(), asset.Spot) + require.NoError(t, err, "Get must not error") + assert.True(t, result.Pair.Equal(pair)) // now test for processing a pair with a different quote currency - c, err = currency.NewPairFromStrings("BTC", "GBP") - if err != nil { - t.Fatal(err) - } - base.Pair = c - err = base.Process() - if err != nil { - t.Error("Process() error", err) - } - result, err = Get("ProcessOrderbook", c, asset.Spot) - if err != nil { - t.Fatal("TestProcessOrderbook failed to retrieve new orderbook") - } - if !result.Pair.Equal(c) { - t.Fatal("TestProcessOrderbook result pair is incorrect") - } + pair, err = currency.NewPairFromStrings("BTC", "GBP") + require.NoError(t, err) + + b.Pair = pair + require.NoError(t, b.Process(), "Process must not error") + + result, err = Get("ProcessOrderbook", pair, asset.Spot) + require.NoError(t, err, "Get must not error") + assert.True(t, result.Pair.Equal(pair)) // now test for processing a pair which has a different base currency - c, err = currency.NewPairFromStrings("LTC", "GBP") - if err != nil { - t.Fatal(err) - } - base.Pair = c - err = base.Process() - if err != nil { - t.Error("Process() error", err) - } - result, err = Get("ProcessOrderbook", c, asset.Spot) - if err != nil { - t.Fatal("TestProcessOrderbook failed to retrieve new orderbook") - } - if !result.Pair.Equal(c) { - t.Fatal("TestProcessOrderbook result pair is incorrect") - } + pair, err = currency.NewPairFromStrings("LTC", "GBP") + require.NoError(t, err, "NewPairFromStrings must not error") - base.Asks = []Tranche{{Price: 200, Amount: 200}} - base.Asset = asset.Spot - err = base.Process() - if err != nil { - t.Error("Process() error", err) - } + b.Pair = pair + require.NoError(t, b.Process(), "Process must not error") - result, err = Get("ProcessOrderbook", c, asset.Spot) - if err != nil { - t.Fatal("TestProcessOrderbook failed to retrieve new orderbook") - } + result, err = Get("ProcessOrderbook", pair, asset.Spot) + require.NoError(t, err, "Get must not error") + assert.True(t, result.Pair.Equal(pair)) - a, b := result.TotalAsksAmount() - if a != 200 && b != 40000 { - t.Fatal("TestProcessOrderbook CalculateTotalsAsks incorrect values") - } + b.Asks = []Level{{Price: 200, Amount: 200}} + b.Asset = asset.Spot + require.NoError(t, b.Process(), "Process must not error") - base.Bids = []Tranche{{Price: 420, Amount: 200}} - base.Exchange = "Blah" - base.Asset = asset.CoinMarginedFutures - err = base.Process() - if err != nil { - t.Error("Process() error", err) - } + result, err = Get("ProcessOrderbook", pair, asset.Spot) + require.NoError(t, err, "Get must not error") - _, err = Get("Blah", c, asset.CoinMarginedFutures) - if err != nil { - t.Fatal("TestProcessOrderbook failed to create new orderbook") - } + ac, total := result.TotalAsksAmount() + assert.Equal(t, 200.0, ac, "TotalAsksAmount should return 200") + assert.Equal(t, 40000.0, total, "TotalAsksAmount should return 40000") - if a != 200 && b != 84000 { - t.Fatal("TestProcessOrderbook CalculateTotalsBids incorrect values") - } + b.Bids = []Level{{Price: 420, Amount: 200}} + b.Exchange = "Blah" + b.Asset = asset.CoinMarginedFutures + + require.NoError(t, b.Process(), "Process must not error") + + result, err = Get("Blah", pair, asset.CoinMarginedFutures) + require.NoError(t, err, "Get must not error") + + ac, total = result.TotalBidsAmount() + assert.Equal(t, 200.0, ac, "TotalBidsAmount should return 200") + assert.Equal(t, 84000.0, total, "TotalBidsAmount should return 84000") type quick struct { Name string P currency.Pair - Bids []Tranche - Asks []Tranche + Bids []Level + Asks []Level } var testArray []quick @@ -415,9 +338,9 @@ func TestProcessOrderbook(t *testing.T) { newPairs := currency.NewPair(currency.NewCode("BTC"+strconv.FormatInt(rand.Int63(), 10)), currency.NewCode("USD"+strconv.FormatInt(rand.Int63(), 10))) //nolint:gosec // no need to import crypo/rand for testing - asks := []Tranche{{Price: rand.Float64(), Amount: rand.Float64()}} //nolint:gosec // no need to import crypo/rand for testing - bids := []Tranche{{Price: rand.Float64(), Amount: rand.Float64()}} //nolint:gosec // no need to import crypo/rand for testing - base := &Base{ + asks := []Level{{Price: rand.Float64(), Amount: rand.Float64()}} //nolint:gosec // no need to import crypo/rand for testing + bids := []Level{{Price: rand.Float64(), Amount: rand.Float64()}} //nolint:gosec // no need to import crypo/rand for testing + b := &Book{ Pair: newPairs, Asks: asks, Bids: bids, @@ -426,7 +349,7 @@ func TestProcessOrderbook(t *testing.T) { } m.Lock() - err = base.Process() + err = b.Process() if err != nil { t.Error(err) catastrophicFailure = true @@ -473,19 +396,19 @@ func TestProcessOrderbook(t *testing.T) { wg.Wait() } -func deployUnorderedSlice() Tranches { - ts := make([]Tranche, 1000) +func levelsFixtureRandom() Levels { + lvls := make([]Level, 1000) for x := range 1000 { - ts[x] = Tranche{Amount: 1, Price: rand.Float64(), ID: rand.Int63()} //nolint:gosec // Not needed in tests + lvls[x] = Level{Amount: 1, Price: rand.Float64(), ID: rand.Int63()} //nolint:gosec // Not needed in tests } - return ts + return lvls } func TestSorting(t *testing.T) { - var b Base + var b Book b.VerifyOrderbook = true - b.Asks = deployUnorderedSlice() + b.Asks = levelsFixtureRandom() err := b.Verify() require.ErrorIs(t, err, errPriceOutOfOrder) @@ -495,7 +418,7 @@ func TestSorting(t *testing.T) { t.Fatal(err) } - b.Bids = deployUnorderedSlice() + b.Bids = levelsFixtureRandom() err = b.Verify() require.ErrorIs(t, err, errPriceOutOfOrder) @@ -506,21 +429,16 @@ func TestSorting(t *testing.T) { } } -func deploySliceOrdered() Tranches { - ts := make([]Tranche, 1000) +func levelsFixture() Levels { + lvls := make(Levels, 1000) for i := range 1000 { - ts[i] = Tranche{Amount: 1, Price: float64(i + 1), ID: rand.Int63()} //nolint:gosec // Not needed in tests + lvls[i] = Level{Amount: 1, Price: float64(i + 1), ID: rand.Int63()} //nolint:gosec // Not needed in tests } - return ts + return lvls } func TestReverse(t *testing.T) { - b := Base{ - VerifyOrderbook: true, - } - - b.Bids = deploySliceOrdered() - require.Len(t, b.Bids, 1000) + b := Book{VerifyOrderbook: true, Bids: levelsFixture()} assert.ErrorIs(t, b.Verify(), errPriceOutOfOrder) b.Bids.Reverse() @@ -535,23 +453,23 @@ func TestReverse(t *testing.T) { // 705985 1856 ns/op 0 B/op 0 allocs/op func BenchmarkReverse(b *testing.B) { - s := deploySliceOrdered() - if len(s) != 1000 { + lvls := levelsFixture() + if len(lvls) != 1000 { b.Fatal("incorrect length") } for b.Loop() { - s.Reverse() + lvls.Reverse() } } // 361266 3556 ns/op 24 B/op 1 allocs/op (old) // 385783 3000 ns/op 152 B/op 3 allocs/op (new) func BenchmarkSortAsksDecending(b *testing.B) { - s := deploySliceOrdered() - bucket := make(Tranches, len(s)) + lvls := levelsFixture() + bucket := make(Levels, len(lvls)) for b.Loop() { - copy(bucket, s) + copy(bucket, lvls) bucket.SortAsks() } } @@ -559,11 +477,11 @@ func BenchmarkSortAsksDecending(b *testing.B) { // 266998 4292 ns/op 40 B/op 2 allocs/op (old) // 372396 3001 ns/op 152 B/op 3 allocs/op (new) func BenchmarkSortBidsAscending(b *testing.B) { - s := deploySliceOrdered() - s.Reverse() - bucket := make(Tranches, len(s)) + lvls := levelsFixture() + lvls.Reverse() + bucket := make(Levels, len(lvls)) for b.Loop() { - copy(bucket, s) + copy(bucket, lvls) bucket.SortBids() } } @@ -571,10 +489,10 @@ func BenchmarkSortBidsAscending(b *testing.B) { // 22119 46532 ns/op 35 B/op 1 allocs/op (old) // 16233 76951 ns/op 167 B/op 3 allocs/op (new) func BenchmarkSortAsksStandard(b *testing.B) { - s := deployUnorderedSlice() - bucket := make(Tranches, len(s)) + lvls := levelsFixtureRandom() + bucket := make(Levels, len(lvls)) for b.Loop() { - copy(bucket, s) + copy(bucket, lvls) bucket.SortAsks() } } @@ -582,10 +500,10 @@ func BenchmarkSortAsksStandard(b *testing.B) { // 19504 62518 ns/op 53 B/op 2 allocs/op (old) // 15698 72859 ns/op 168 B/op 3 allocs/op (new) func BenchmarkSortBidsStandard(b *testing.B) { - s := deployUnorderedSlice() - bucket := make(Tranches, len(s)) + lvls := levelsFixtureRandom() + bucket := make(Levels, len(lvls)) for b.Loop() { - copy(bucket, s) + copy(bucket, lvls) bucket.SortBids() } } @@ -593,10 +511,10 @@ func BenchmarkSortBidsStandard(b *testing.B) { // 376708 3559 ns/op 24 B/op 1 allocs/op (old) // 377113 3020 ns/op 152 B/op 3 allocs/op (new) func BenchmarkSortAsksAscending(b *testing.B) { - s := deploySliceOrdered() - bucket := make(Tranches, len(s)) + lvls := levelsFixture() + bucket := make(Levels, len(lvls)) for b.Loop() { - copy(bucket, s) + copy(bucket, lvls) bucket.SortAsks() } } @@ -604,18 +522,18 @@ func BenchmarkSortAsksAscending(b *testing.B) { // 262874 4364 ns/op 40 B/op 2 allocs/op (old) // 401788 3348 ns/op 152 B/op 3 allocs/op (new) func BenchmarkSortBidsDescending(b *testing.B) { - s := deploySliceOrdered() - s.Reverse() - bucket := make(Tranches, len(s)) + lvls := levelsFixture() + lvls.Reverse() + bucket := make(Levels, len(lvls)) for b.Loop() { - copy(bucket, s) + copy(bucket, lvls) bucket.SortBids() } } func TestCheckAlignment(t *testing.T) { t.Parallel() - itemWithFunding := Tranches{{Amount: 1337, Price: 0, Period: 1337}} + itemWithFunding := Levels{{Amount: 1337, Price: 0, Period: 1337}} err := checkAlignment(itemWithFunding, true, true, false, false, dsc, "Bitfinex") if err != nil { t.Error(err) @@ -639,16 +557,16 @@ func TestCheckAlignment(t *testing.T) { // 5572401 210.9 ns/op 0 B/op 0 allocs/op (current) // 3748009 312.7 ns/op 32 B/op 1 allocs/op (previous) func BenchmarkProcess(b *testing.B) { - base := &Base{ + book := &Book{ Pair: currency.NewBTCUSD(), - Asks: make(Tranches, 100), - Bids: make(Tranches, 100), + Asks: make(Levels, 100), + Bids: make(Levels, 100), Exchange: "BenchmarkProcessOrderbook", Asset: asset.Spot, } for b.Loop() { - if err := base.Process(); err != nil { + if err := book.Process(); err != nil { b.Fatal(err) } } diff --git a/exchanges/orderbook/orderbook_types.go b/exchanges/orderbook/orderbook_types.go index 3dd04e68..66856113 100644 --- a/exchanges/orderbook/orderbook_types.go +++ b/exchanges/orderbook/orderbook_types.go @@ -57,8 +57,8 @@ type store struct { m sync.RWMutex } -// Tranche defines a segmented portions of an order or options book -type Tranche struct { +// Level contains an orderbook price and the aggregated order amount at that price. +type Level struct { Amount float64 // StrAmount is a string representation of the amount. e.g. 0.00000100 this // parsed as a float will constrict comparison to 1e-6 not 1e-8 or @@ -79,10 +79,10 @@ type Tranche struct { OrderCount int64 } -// Base holds the fields for the orderbook base -type Base struct { - Bids Tranches - Asks Tranches +// Book contains an orderbook +type Book struct { + Bids Levels + Asks Levels Exchange string Pair currency.Pair @@ -171,8 +171,8 @@ type Update struct { LastPushed time.Time Asset asset.Item Action - Bids []Tranche - Asks []Tranche + Bids []Level + Asks []Level Pair currency.Pair // Checksum defines the expected value when the books have been verified Checksum uint32 @@ -200,7 +200,7 @@ type Movement struct { // Purchases defines the amount of currency purchased. Purchased float64 // AverageOrderCost defines the average order cost of position as it slips - // through the orderbook tranches. + // through the orderbook Levels. AverageOrderCost float64 // FullBookSideConsumed defines if the orderbook liquidty has been consumed // by the requested amount. This might not represent the actual book on the @@ -209,10 +209,10 @@ type Movement struct { FullBookSideConsumed bool } -// SideAmounts define the amounts total for the tranches, total value in +// SideAmounts define the amounts total for the Levels, total value in // quotation and the cumulative base amounts. type SideAmounts struct { - Tranches int64 + Levels int64 QuoteValue float64 BaseAmount float64 } diff --git a/exchanges/poloniex/poloniex_websocket.go b/exchanges/poloniex/poloniex_websocket.go index f76e264e..8d06f277 100644 --- a/exchanges/poloniex/poloniex_websocket.go +++ b/exchanges/poloniex/poloniex_websocket.go @@ -435,8 +435,8 @@ func (p *Poloniex) WsProcessOrderbookSnapshot(data []any) error { errTypeAssertionFailure) } - var book orderbook.Base - book.Asks = make(orderbook.Tranches, 0, len(askData)) + var book orderbook.Book + book.Asks = make(orderbook.Levels, 0, len(askData)) for price, volume := range askData { var p float64 p, err = strconv.ParseFloat(price, 64) @@ -453,10 +453,10 @@ func (p *Poloniex) WsProcessOrderbookSnapshot(data []any) error { if err != nil { return err } - book.Asks = append(book.Asks, orderbook.Tranche{Price: p, Amount: a}) + book.Asks = append(book.Asks, orderbook.Level{Price: p, Amount: a}) } - book.Bids = make(orderbook.Tranches, 0, len(bidData)) + book.Bids = make(orderbook.Levels, 0, len(bidData)) for price, volume := range bidData { var p float64 p, err = strconv.ParseFloat(price, 64) @@ -473,7 +473,7 @@ func (p *Poloniex) WsProcessOrderbookSnapshot(data []any) error { if err != nil { return err } - book.Bids = append(book.Bids, orderbook.Tranche{Price: p, Amount: a}) + book.Bids = append(book.Bids, orderbook.Level{Price: p, Amount: a}) } // Both sides are completely out of order - sort needs to be used @@ -535,9 +535,9 @@ func (p *Poloniex) WsProcessOrderbookUpdate(sequenceNumber float64, data []any, UpdateTime: time.UnixMilli(tsMilli), } if bs == 1 { - update.Bids = []orderbook.Tranche{{Price: price, Amount: volume}} + update.Bids = []orderbook.Level{{Price: price, Amount: volume}} } else { - update.Asks = []orderbook.Tranche{{Price: price, Amount: volume}} + update.Asks = []orderbook.Level{{Price: price, Amount: volume}} } return p.Websocket.Orderbook.Update(update) } diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index c84aa24f..7eef5f08 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -275,14 +275,14 @@ func (p *Poloniex) UpdateTicker(ctx context.Context, currencyPair currency.Pair, } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (p *Poloniex) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (p *Poloniex) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := p.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - callingBook := &orderbook.Base{ + callingBook := &orderbook.Book{ Exchange: p.Name, Pair: pair, Asset: assetType, @@ -310,24 +310,24 @@ func (p *Poloniex) UpdateOrderbook(ctx context.Context, pair currency.Pair, asse continue } } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: p.Name, Pair: enabledPairs[i], Asset: assetType, VerifyOrderbook: p.CanVerifyOrderbook, } - book.Bids = make(orderbook.Tranches, len(data.Bids)) + book.Bids = make(orderbook.Levels, len(data.Bids)) for y := range data.Bids { - book.Bids[y] = orderbook.Tranche{ + book.Bids[y] = orderbook.Level{ Amount: data.Bids[y].Amount, Price: data.Bids[y].Price, } } - book.Asks = make(orderbook.Tranches, len(data.Asks)) + book.Asks = make(orderbook.Levels, len(data.Asks)) for y := range data.Asks { - book.Asks[y] = orderbook.Tranche{ + book.Asks[y] = orderbook.Level{ Amount: data.Asks[y].Amount, Price: data.Asks[y].Price, } diff --git a/exchanges/sharedtestvalues/customex.go b/exchanges/sharedtestvalues/customex.go index df8c2a2a..b442a126 100644 --- a/exchanges/sharedtestvalues/customex.go +++ b/exchanges/sharedtestvalues/customex.go @@ -67,7 +67,7 @@ func (c *CustomEx) UpdateTicker(_ context.Context, _ currency.Pair, _ asset.Item } // UpdateOrderbook is a mock method for CustomEx -func (c *CustomEx) UpdateOrderbook(_ context.Context, _ currency.Pair, _ asset.Item) (*orderbook.Base, error) { +func (c *CustomEx) UpdateOrderbook(_ context.Context, _ currency.Pair, _ asset.Item) (*orderbook.Book, error) { return nil, nil } diff --git a/exchanges/yobit/yobit_wrapper.go b/exchanges/yobit/yobit_wrapper.go index eaea6b4e..c90ea9c9 100644 --- a/exchanges/yobit/yobit_wrapper.go +++ b/exchanges/yobit/yobit_wrapper.go @@ -192,14 +192,14 @@ func (y *Yobit) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (y *Yobit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (y *Yobit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if err := y.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - book := &orderbook.Base{ + book := &orderbook.Book{ Exchange: y.Name, Pair: p, Asset: assetType, @@ -216,7 +216,7 @@ func (y *Yobit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType for i := range orderbookNew.Bids { book.Bids = append(book.Bids, - orderbook.Tranche{ + orderbook.Level{ Price: orderbookNew.Bids[i][0], Amount: orderbookNew.Bids[i][1], }) @@ -224,7 +224,7 @@ func (y *Yobit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType for i := range orderbookNew.Asks { book.Asks = append(book.Asks, - orderbook.Tranche{ + orderbook.Level{ Price: orderbookNew.Asks[i][0], Amount: orderbookNew.Asks[i][1], }) diff --git a/gctscript/modules/wrapper_types.go b/gctscript/modules/wrapper_types.go index ff16eb52..1ae4f1fa 100644 --- a/gctscript/modules/wrapper_types.go +++ b/gctscript/modules/wrapper_types.go @@ -29,7 +29,7 @@ var Wrapper GCTExchange type GCTExchange interface { Exchanges(enabledOnly bool) []string IsEnabled(exch string) bool - Orderbook(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) + Orderbook(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*orderbook.Book, error) Ticker(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*ticker.Price, error) Pairs(exch string, enabledOnly bool, item asset.Item) (*currency.Pairs, error) QueryOrder(ctx context.Context, exch, orderid string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) diff --git a/gctscript/wrappers/gct/exchange/exchange.go b/gctscript/wrappers/gct/exchange/exchange.go index e943053d..bb95d2a0 100644 --- a/gctscript/wrappers/gct/exchange/exchange.go +++ b/gctscript/wrappers/gct/exchange/exchange.go @@ -45,7 +45,7 @@ func (e Exchange) IsEnabled(exch string) bool { } // Orderbook returns current orderbook requested exchange, pair and asset -func (e Exchange) Orderbook(ctx context.Context, exch string, pair currency.Pair, a asset.Item) (*orderbook.Base, error) { +func (e Exchange) Orderbook(ctx context.Context, exch string, pair currency.Pair, a asset.Item) (*orderbook.Book, error) { ex, err := e.GetExchange(exch) if err != nil { return nil, err diff --git a/gctscript/wrappers/validator/validator.go b/gctscript/wrappers/validator/validator.go index a8b77d21..185bb331 100644 --- a/gctscript/wrappers/validator/validator.go +++ b/gctscript/wrappers/validator/validator.go @@ -46,22 +46,22 @@ func (w Wrapper) IsEnabled(exch string) (v bool) { } // Orderbook validator for test execution/scripts -func (w Wrapper) Orderbook(_ context.Context, exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) { +func (w Wrapper) Orderbook(_ context.Context, exch string, pair currency.Pair, item asset.Item) (*orderbook.Book, error) { if exch == exchError.String() { return nil, errTestFailed } - return &orderbook.Base{ + return &orderbook.Book{ Exchange: exch, Asset: item, Pair: pair, - Bids: []orderbook.Tranche{ + Bids: []orderbook.Level{ { Amount: 1, Price: 1, }, }, - Asks: []orderbook.Tranche{ + Asks: []orderbook.Level{ { Amount: 1, Price: 1,