mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-08 15:11:07 +00:00
Okx: Fix sending trades to the websocket DataHandler (#1833)
* Send trades down the DataHandler, add test * Send the trades down to the DataHandler Update the test to process trades for each asset type Add raw trade data from OKX Update the timestamp in the method * Replace pair repetition with p var * Update the test, remove repetition * Rename trade var in the test * Fix nits and slice sorting * Compare trades * Fix nits
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -30,6 +32,7 @@ import (
|
|||||||
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
|
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
|
||||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||||
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
|
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
|
||||||
|
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
|
||||||
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
|
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
|
||||||
testsubs "github.com/thrasher-corp/gocryptotrader/internal/testing/subscriptions"
|
testsubs "github.com/thrasher-corp/gocryptotrader/internal/testing/subscriptions"
|
||||||
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
||||||
@@ -4045,6 +4048,75 @@ func setupWS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWSProcessTrades(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
ok := new(Okx) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
||||||
|
require.NoError(t, testexch.Setup(ok), "Test instance Setup must not error")
|
||||||
|
assets, err := ok.getAssetsFromInstrumentID("BTC-USDT")
|
||||||
|
require.NoError(t, err, "getAssetsFromInstrumentID must not error")
|
||||||
|
|
||||||
|
p := currency.NewPairWithDelimiter("BTC", "USDT", currency.DashDelimiter)
|
||||||
|
|
||||||
|
for _, a := range assets {
|
||||||
|
err := ok.Websocket.AddSubscriptions(ok.Websocket.Conn, &subscription.Subscription{
|
||||||
|
Asset: a,
|
||||||
|
Pairs: currency.Pairs{p},
|
||||||
|
Channel: subscription.AllTradesChannel,
|
||||||
|
Key: fmt.Sprintf("%s-%s", p, a)})
|
||||||
|
require.NoError(t, err, "AddSubscriptions must not error")
|
||||||
|
}
|
||||||
|
testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", ok.WsHandleData)
|
||||||
|
|
||||||
|
exp := []trade.Data{
|
||||||
|
{
|
||||||
|
Timestamp: time.UnixMilli(1740394561685).UTC(),
|
||||||
|
Price: 95634.9,
|
||||||
|
Amount: 0.00011186,
|
||||||
|
Side: order.Buy,
|
||||||
|
TID: "674510826",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Timestamp: time.UnixMilli(1740394561686).UTC(),
|
||||||
|
Price: 95635.3,
|
||||||
|
Amount: 0.00011194,
|
||||||
|
Side: order.Sell,
|
||||||
|
TID: "674510827",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
total := len(assets) * len(exp)
|
||||||
|
require.Len(t, ok.Websocket.DataHandler, total, "Must see correct number of trades")
|
||||||
|
|
||||||
|
trades := make(map[asset.Item][]trade.Data)
|
||||||
|
|
||||||
|
for len(ok.Websocket.DataHandler) > 0 {
|
||||||
|
resp := <-ok.Websocket.DataHandler
|
||||||
|
switch v := resp.(type) {
|
||||||
|
case trade.Data:
|
||||||
|
trades[v.AssetType] = append(trades[v.AssetType], v)
|
||||||
|
case error:
|
||||||
|
t.Error(v)
|
||||||
|
default:
|
||||||
|
t.Errorf("Unexpected type in DataHandler: %T (%s)", v, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, assetType := range assets {
|
||||||
|
require.Len(t, trades[assetType], len(exp), "Must have received %d trades for asset %v", len(exp), assetType)
|
||||||
|
slices.SortFunc(trades[assetType], func(a, b trade.Data) int {
|
||||||
|
return strings.Compare(a.TID, b.TID)
|
||||||
|
})
|
||||||
|
for i, tradeData := range trades[assetType] {
|
||||||
|
expected := exp[i]
|
||||||
|
expected.AssetType = assetType
|
||||||
|
expected.Exchange = ok.Name
|
||||||
|
expected.CurrencyPair = p
|
||||||
|
require.Equal(t, expected, tradeData, "Trade %d (TID: %s) for asset %v must match expected data", i, tradeData.TID, assetType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ************************** Public Channel Subscriptions *****************************
|
// ************************** Public Channel Subscriptions *****************************
|
||||||
|
|
||||||
func TestInstrumentsSubscription(t *testing.T) {
|
func TestInstrumentsSubscription(t *testing.T) {
|
||||||
|
|||||||
@@ -1219,6 +1219,13 @@ func (ok *Okx) wsProcessTrades(data []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveTradeData := ok.IsSaveTradeDataEnabled()
|
||||||
|
tradeFeed := ok.IsTradeFeedEnabled()
|
||||||
|
if !saveTradeData && !tradeFeed {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var assets []asset.Item
|
var assets []asset.Item
|
||||||
if response.Argument.InstrumentType != "" {
|
if response.Argument.InstrumentType != "" {
|
||||||
assetType, err := assetTypeFromInstrumentType(response.Argument.InstrumentType)
|
assetType, err := assetTypeFromInstrumentType(response.Argument.InstrumentType)
|
||||||
@@ -1245,13 +1252,21 @@ func (ok *Okx) wsProcessTrades(data []byte) error {
|
|||||||
CurrencyPair: pair,
|
CurrencyPair: pair,
|
||||||
Exchange: ok.Name,
|
Exchange: ok.Name,
|
||||||
Side: response.Data[i].Side,
|
Side: response.Data[i].Side,
|
||||||
Timestamp: response.Data[i].Timestamp.Time(),
|
Timestamp: response.Data[i].Timestamp.Time().UTC(),
|
||||||
TID: response.Data[i].TradeID,
|
TID: response.Data[i].TradeID,
|
||||||
Price: response.Data[i].Price.Float64(),
|
Price: response.Data[i].Price.Float64(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return trade.AddTradesToBuffer(trades...)
|
if tradeFeed {
|
||||||
|
for i := range trades {
|
||||||
|
ok.Websocket.DataHandler <- trades[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if saveTradeData {
|
||||||
|
return trade.AddTradesToBuffer(trades...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// wsProcessOrders handles websocket order push data responses.
|
// wsProcessOrders handles websocket order push data responses.
|
||||||
|
|||||||
2
exchanges/okx/testdata/wsAllTrades.json
vendored
Normal file
2
exchanges/okx/testdata/wsAllTrades.json
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
{"arg":{"channel":"trades","instId":"BTC-USDT"},"data":[{"instId":"BTC-USDT","tradeId":"674510826","px":"95634.9","sz":"0.00011186","side":"buy","ts":"1740394561685","count":"1"}]}
|
||||||
|
{"arg":{"channel":"trades","instId":"BTC-USDT"},"data":[{"instId":"BTC-USDT","tradeId":"674510827","px":"95635.3","sz":"0.00011194","side":"sell","ts":"1740394561686","count":"1"}]}
|
||||||
2
testdata/configtest.json
vendored
2
testdata/configtest.json
vendored
@@ -2273,7 +2273,7 @@
|
|||||||
"autoPairUpdates": true,
|
"autoPairUpdates": true,
|
||||||
"websocketAPI": true,
|
"websocketAPI": true,
|
||||||
"saveTradeData": false,
|
"saveTradeData": false,
|
||||||
"tradeFeed": false,
|
"tradeFeed": true,
|
||||||
"fillsFeed": false
|
"fillsFeed": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user