Websocket orderbook buffering (#333)

* Initial commit setting up a map orderbook system with a buffer. It will write to the buffer, sort apply to main orderbook and then process.

* Moves namespaces again

* Updates orderbook to use a sweet new WebsocketOrderbookUpdate type to handle all updates whether its using ID or not. So good. Adds many tests

* Starting to implement orderbook update handling per exchange. Updates namespaces again. Hopefuylly will find a way to update via ID not timestamp, too many endpoints dont provide update timestamps

* Changes orderbookbuffer to use BufferUpdate type instead of orderbook.Base to achieve more functionality and no need for type conversion functions. Updates tests

* Updates all instances of ws.orderbook.Update. Simplifies some orderbook logic

* Introduces toggleable buffer. Renames orderbooks. Completes implementation for everywhere but OKGroup due to hash calculation

* Implements orderbook update for okgroup, but forgets about the orderbook hash checking

* Fixes okgroup checksum calculation. Fixes linting issue. Removes redundant Kraken tests.

* Introduces sorting toggle and separates from buffer toggle. Uses benchmarks to highlight performance gains

* Fixes Gemini rate limit and parsing. Removes comments and fixes typos

* Fixes bitfinex orderbook processing

* Inbuilt sorting, minor fixes for websocket implementations. Improves test coverage

* Adds surprise LakeBTC websocket support

* Fixes data race

* Fixes rebasing issues due to namespace movements

* Addresses PR nits: moves folder namespace from ws to websocket. Removes line spaces in imports. Fixes lakebtc websocket returns and defer fucntions. Fixes comments

* Adds poloniex orderook sorting support

* Enables bitstamp and hitbtc orderbook sorting. Fixes poloniex's sorting

* Renames namespaces and combines monitor and connection into wshandler. Removes unused SPOT const. Changes how orderbook stuff is loaded. It is done in startup with a setup. Removes exchange name from loadsnapshot as well

* Removes the connection.go from rebasing issues. Removes error response from functions used in goroutines

* Fixes test with exchange name output change

* Fixes issues where copy and paste and replace all were used poorly
This commit is contained in:
Scott
2019-08-13 09:32:59 +10:00
committed by Adrian Gallagher
parent 2078ba907f
commit 0fbf8b172a
110 changed files with 2197 additions and 1909 deletions

View File

@@ -37,6 +37,7 @@ const (
configDefaultHTTPTimeout = time.Second * 15
configDefaultWebsocketResponseCheckTimeout = time.Millisecond * 30
configDefaultWebsocketResponseMaxLimit = time.Second * 7
configDefaultWebsocketOrderbookBufferLimit = 5
configMaxAuthFailres = 3
defaultNTPAllowedDifference = 50000000
defaultNTPAllowedNegativeDifference = 50000000
@@ -161,6 +162,7 @@ type ExchangeConfig struct {
HTTPTimeout time.Duration `json:"httpTimeout"`
WebsocketResponseCheckTimeout time.Duration `json:"websocketResponseCheckTimeout"`
WebsocketResponseMaxLimit time.Duration `json:"websocketResponseMaxLimit"`
WebsocketOrderbookBufferLimit int `json:"websocketOrderbookBufferLimit"`
HTTPUserAgent string `json:"httpUserAgent"`
HTTPDebugging bool `json:"httpDebugging"`
AuthenticatedAPISupport bool `json:"authenticatedApiSupport"`
@@ -837,7 +839,10 @@ func (c *Config) CheckExchangeConfigValues() error {
log.Warnf("Exchange %s Websocket response max limit value not set, defaulting to %v.", c.Exchanges[i].Name, configDefaultWebsocketResponseMaxLimit)
c.Exchanges[i].WebsocketResponseMaxLimit = configDefaultWebsocketResponseMaxLimit
}
if c.Exchanges[i].WebsocketOrderbookBufferLimit <= 0 {
log.Warnf("Exchange %s Websocket orderbook buffer limit value not set, defaulting to %v.", c.Exchanges[i].Name, configDefaultWebsocketOrderbookBufferLimit)
c.Exchanges[i].WebsocketOrderbookBufferLimit = configDefaultWebsocketOrderbookBufferLimit
}
err := c.CheckPairConsistency(c.Exchanges[i].Name)
if err != nil {
log.Errorf("Exchange %s: CheckPairConsistency error: %s", c.Exchanges[i].Name, err)

View File

@@ -666,6 +666,7 @@ func TestCheckExchangeConfigValues(t *testing.T) {
checkExchangeConfigValues.Exchanges[0].WebsocketResponseMaxLimit = 0
checkExchangeConfigValues.Exchanges[0].WebsocketResponseCheckTimeout = 0
checkExchangeConfigValues.Exchanges[0].WebsocketOrderbookBufferLimit = 0
checkExchangeConfigValues.Exchanges[0].HTTPTimeout = 0
err = checkExchangeConfigValues.CheckExchangeConfigValues()
if err != nil {
@@ -682,8 +683,8 @@ func TestCheckExchangeConfigValues(t *testing.T) {
t.Fatalf("Test failed. Expected exchange %s to have updated WebsocketResponseMaxLimit value", checkExchangeConfigValues.Exchanges[0].Name)
}
if checkExchangeConfigValues.Exchanges[0].WebsocketResponseCheckTimeout == 0 {
t.Fatalf("Test failed. Expected exchange %s to have updated WebsocketResponseCheckTimeout value", checkExchangeConfigValues.Exchanges[0].Name)
if checkExchangeConfigValues.Exchanges[0].WebsocketOrderbookBufferLimit == 0 {
t.Fatalf("Test failed. Expected exchange %s to have updated WebsocketOrderbookBufferLimit value", checkExchangeConfigValues.Exchanges[0].Name)
}
checkExchangeConfigValues.Exchanges[0].APIKey = "Key"