cmd/exchange_template, exchanges: Update templates and propogate to exchanges (#1777)

* Added TimeInForce type and updated related files

* Linter issue fix and minor coinbasepro type update

* Bitrex consts update

* added unit test and minor changes in bittrex

* Unit tests update

* Fix minor linter issues

* Update TestStringToTimeInForce unit test

* Exchange test template change

* A different approach

* fix conflict with gateio timeInForce

* minor exchange template update

* Minor fix to test_files template

* Update order tests

* Complete updating the order unit tests

* Updating exchange wrapper and test template files

* update kucoin and deribit wrapper to match the time in force change

* minor comment update

* fix time-in-force related test errors

* linter issue fix

* ADD_NEW_EXCHANGE documentation update

* time in force constants, functions and unit tests update

* shift tif policies to TimeInForce

* Update time-in-force, related functions, and unit tests

* fix linter issue and time-in-force processing

* added a good till crossing tif value

* order type fix and fix related tim-in-force entries

* update time-in-force unmarshaling and unit test

* consistency guideline added

* fix time-in-force error in gateio

* linter issue fix

* update based on review comments

* add unit test and fix missing issues

* minor fix and added benchmark unit test

* change GTT to GTC for limit

* fix linter issue

* added time-in-force value to place order param

* fix minor issues based on review comment and move tif code to separate files

* update on exchanges linked to time-in-force

* resolve missing review comments

* minor linter issues fix

* added time-in-force handler and update timeInForce parametered endpoint

* minor fixes based on review

* nits fix

* update based on review

* linter fix

* rm getTimeInForce func and minor change to time-in-force

* minor change

* update based on review comments

* wrappers and time-in-force calling approach

* minor change

* update gateio string to timeInForce conversion and unit test

* update exchange template

* update wrapper template file

* policy comments, and template files update

* rename all exchange types name to Exchange

* update on template files and template generation

* templates and generation code and other updates

* linter issue fix

* added subscriptions and websocket templates

* update ADD_NEW_EXCHANGE.md with recent binance functions and implementations

* rename template files and update unit tests

* minor template and unit test fix

* rename templates and fix on unit tests

* update on template files and documentation

* removed unnecessary tag fix and update templates

* fix Add_NEW_EXCHANGE.md doc file

* formatting, comments, and error checks update on template files

* rename exchange receivers to e and ex for consistency

* rename unit test exchange receiver and minor updates

* linter issues fix

* fix deribit issue and minor style update

* fix test issues caused by receiver change

* raname local variables exchange declaration variables

* update templates comments

* update templates and related comments

* renamed ex to e

* update template comments

* toggle WS to false to improve coverage

* template comments update

* added test coverage to Ws enabled and minor changes

---------

Co-authored-by: Samuel Reid <43227667+cranktakular@users.noreply.github.com>
This commit is contained in:
Samuael A.
2025-07-17 03:46:36 +03:00
committed by GitHub
parent 485397a0c7
commit 3f534a15f1
163 changed files with 20453 additions and 20313 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -80,8 +80,8 @@ var subscriptionNames = map[string]string{
var standardMarginAssetTypes = []asset.Item{asset.Spot, asset.Margin, asset.CrossMargin}
// WsConnectSpot initiates a websocket connection
func (g *Gateio) WsConnectSpot(ctx context.Context, conn websocket.Connection) error {
err := g.CurrencyPairs.IsAssetEnabled(asset.Spot)
func (e *Exchange) WsConnectSpot(ctx context.Context, conn websocket.Connection) error {
err := e.CurrencyPairs.IsAssetEnabled(asset.Spot)
if err != nil {
return err
}
@@ -103,7 +103,7 @@ func (g *Gateio) WsConnectSpot(ctx context.Context, conn websocket.Connection) e
}
// websocketLogin authenticates the websocket connection
func (g *Gateio) websocketLogin(ctx context.Context, conn websocket.Connection, channel string) error {
func (e *Exchange) websocketLogin(ctx context.Context, conn websocket.Connection, channel string) error {
if conn == nil {
return fmt.Errorf("%w: %T", common.ErrNilPointer, conn)
}
@@ -112,7 +112,7 @@ func (g *Gateio) websocketLogin(ctx context.Context, conn websocket.Connection,
return errChannelEmpty
}
creds, err := g.GetCredentials(ctx)
creds, err := e.GetCredentials(ctx)
if err != nil {
return err
}
@@ -156,7 +156,7 @@ func (g *Gateio) websocketLogin(ctx context.Context, conn websocket.Connection,
return fmt.Errorf("%s: %s", wsErr.Errors.Label, wsErr.Errors.Message)
}
func (g *Gateio) generateWsSignature(secret, event, channel string, t int64) (string, error) {
func (e *Exchange) generateWsSignature(secret, event, channel string, t int64) (string, error) {
msg := "channel=" + channel + "&event=" + event + "&time=" + strconv.FormatInt(t, 10)
mac := hmac.New(sha512.New, []byte(secret))
if _, err := mac.Write([]byte(msg)); err != nil {
@@ -166,51 +166,51 @@ func (g *Gateio) generateWsSignature(secret, event, channel string, t int64) (st
}
// WsHandleSpotData handles spot data
func (g *Gateio) WsHandleSpotData(ctx context.Context, respRaw []byte) error {
func (e *Exchange) WsHandleSpotData(ctx context.Context, respRaw []byte) error {
push, err := parseWSHeader(respRaw)
if err != nil {
return err
}
if push.RequestID != "" {
return g.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw)
return e.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw)
}
if push.Event == subscribeEvent || push.Event == unsubscribeEvent {
return g.Websocket.Match.RequireMatchWithData(push.ID, respRaw)
return e.Websocket.Match.RequireMatchWithData(push.ID, respRaw)
}
switch push.Channel { // TODO: Convert function params below to only use push.Result
case spotTickerChannel:
return g.processTicker(push.Result, push.Time)
return e.processTicker(push.Result, push.Time)
case spotTradesChannel:
return g.processTrades(push.Result)
return e.processTrades(push.Result)
case spotCandlesticksChannel:
return g.processCandlestick(push.Result)
return e.processCandlestick(push.Result)
case spotOrderbookTickerChannel:
return g.processOrderbookTicker(push.Result, push.Time)
return e.processOrderbookTicker(push.Result, push.Time)
case spotOrderbookUpdateChannel:
return g.processOrderbookUpdate(ctx, push.Result, push.Time)
return e.processOrderbookUpdate(ctx, push.Result, push.Time)
case spotOrderbookChannel:
return g.processOrderbookSnapshot(push.Result, push.Time)
return e.processOrderbookSnapshot(push.Result, push.Time)
case spotOrdersChannel:
return g.processSpotOrders(respRaw)
return e.processSpotOrders(respRaw)
case spotUserTradesChannel:
return g.processUserPersonalTrades(respRaw)
return e.processUserPersonalTrades(respRaw)
case spotBalancesChannel:
return g.processSpotBalances(ctx, respRaw)
return e.processSpotBalances(ctx, respRaw)
case marginBalancesChannel:
return g.processMarginBalances(ctx, respRaw)
return e.processMarginBalances(ctx, respRaw)
case spotFundingBalanceChannel:
return g.processFundingBalances(respRaw)
return e.processFundingBalances(respRaw)
case crossMarginBalanceChannel:
return g.processCrossMarginBalance(ctx, respRaw)
return e.processCrossMarginBalance(ctx, respRaw)
case crossMarginLoanChannel:
return g.processCrossMarginLoans(respRaw)
return e.processCrossMarginLoans(respRaw)
case spotPongChannel:
default:
g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
Message: g.Name + websocket.UnhandledMessage + string(respRaw),
e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
Message: e.Name + websocket.UnhandledMessage + string(respRaw),
}
return errors.New(websocket.UnhandledMessage)
}
@@ -256,16 +256,16 @@ func parseWSHeader(msg []byte) (r *WSResponse, errs error) {
return r, errs
}
func (g *Gateio) processTicker(incoming []byte, pushTime time.Time) error {
func (e *Exchange) processTicker(incoming []byte, pushTime time.Time) error {
var data WsTicker
if err := json.Unmarshal(incoming, &data); err != nil {
return err
}
out := make([]ticker.Price, 0, len(standardMarginAssetTypes))
for _, a := range standardMarginAssetTypes {
if enabled, _ := g.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled {
if enabled, _ := e.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled {
out = append(out, ticker.Price{
ExchangeName: g.Name,
ExchangeName: e.Name,
Volume: data.BaseVolume.Float64(),
QuoteVolume: data.QuoteVolume.Float64(),
High: data.High24H.Float64(),
@@ -279,13 +279,13 @@ func (g *Gateio) processTicker(incoming []byte, pushTime time.Time) error {
})
}
}
g.Websocket.DataHandler <- out
e.Websocket.DataHandler <- out
return nil
}
func (g *Gateio) processTrades(incoming []byte) error {
saveTradeData := g.IsSaveTradeDataEnabled()
if !saveTradeData && !g.IsTradeFeedEnabled() {
func (e *Exchange) processTrades(incoming []byte) error {
saveTradeData := e.IsSaveTradeDataEnabled()
if !saveTradeData && !e.IsTradeFeedEnabled() {
return nil
}
@@ -300,12 +300,12 @@ func (g *Gateio) processTrades(incoming []byte) error {
}
for _, a := range standardMarginAssetTypes {
if enabled, _ := g.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled {
if err := g.Websocket.Trade.Update(saveTradeData, trade.Data{
if enabled, _ := e.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled {
if err := e.Websocket.Trade.Update(saveTradeData, trade.Data{
Timestamp: data.CreateTime.Time(),
CurrencyPair: data.CurrencyPair,
AssetType: a,
Exchange: g.Name,
Exchange: e.Name,
Price: data.Price.Float64(),
Amount: data.Amount.Float64(),
Side: side,
@@ -319,7 +319,7 @@ func (g *Gateio) processTrades(incoming []byte) error {
return nil
}
func (g *Gateio) processCandlestick(incoming []byte) error {
func (e *Exchange) processCandlestick(incoming []byte) error {
var data WsCandlesticks
if err := json.Unmarshal(incoming, &data); err != nil {
return err
@@ -335,11 +335,11 @@ func (g *Gateio) processCandlestick(incoming []byte) error {
out := make([]websocket.KlineData, 0, len(standardMarginAssetTypes))
for _, a := range standardMarginAssetTypes {
if enabled, _ := g.CurrencyPairs.IsPairEnabled(currencyPair, a); enabled {
if enabled, _ := e.CurrencyPairs.IsPairEnabled(currencyPair, a); enabled {
out = append(out, websocket.KlineData{
Pair: currencyPair,
AssetType: a,
Exchange: g.Name,
Exchange: e.Name,
StartTime: data.Timestamp.Time(),
Interval: icp[0],
OpenPrice: data.OpenPrice.Float64(),
@@ -350,17 +350,17 @@ func (g *Gateio) processCandlestick(incoming []byte) error {
})
}
}
g.Websocket.DataHandler <- out
e.Websocket.DataHandler <- out
return nil
}
func (g *Gateio) processOrderbookTicker(incoming []byte, lastPushed time.Time) error {
func (e *Exchange) processOrderbookTicker(incoming []byte, lastPushed time.Time) error {
var data WsOrderbookTickerData
if err := json.Unmarshal(incoming, &data); err != nil {
return err
}
return g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Exchange: g.Name,
return e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Exchange: e.Name,
Pair: data.Pair,
Asset: asset.Spot,
LastUpdated: data.UpdateTime.Time(),
@@ -370,7 +370,7 @@ func (g *Gateio) processOrderbookTicker(incoming []byte, lastPushed time.Time) e
})
}
func (g *Gateio) processOrderbookUpdate(ctx context.Context, incoming []byte, lastPushed time.Time) error {
func (e *Exchange) processOrderbookUpdate(ctx context.Context, incoming []byte, lastPushed time.Time) error {
var data WsOrderbookUpdate
if err := json.Unmarshal(incoming, &data); err != nil {
return err
@@ -385,7 +385,7 @@ func (g *Gateio) processOrderbookUpdate(ctx context.Context, incoming []byte, la
bids[x].Price = data.Bids[x][0].Float64()
bids[x].Amount = data.Bids[x][1].Float64()
}
return g.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, g, data.FirstUpdateID, &orderbook.Update{
return e.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, e, data.FirstUpdateID, &orderbook.Update{
UpdateID: data.LastUpdateID,
UpdateTime: data.UpdateTime.Time(),
LastPushed: lastPushed,
@@ -397,7 +397,7 @@ func (g *Gateio) processOrderbookUpdate(ctx context.Context, incoming []byte, la
})
}
func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) error {
func (e *Exchange) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) error {
var data WsOrderbookSnapshot
if err := json.Unmarshal(incoming, &data); err != nil {
return err
@@ -415,9 +415,9 @@ 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.Book{
Exchange: g.Name,
if enabled, _ := e.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled {
if err := e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Exchange: e.Name,
Pair: data.CurrencyPair,
Asset: a,
LastUpdated: data.UpdateTime.Time(),
@@ -432,7 +432,7 @@ func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time)
return nil
}
func (g *Gateio) processSpotOrders(data []byte) error {
func (e *Exchange) processSpotOrders(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -459,7 +459,7 @@ func (g *Gateio) processSpotOrders(data []byte) error {
}
details[x] = order.Detail{
Amount: resp.Result[x].Amount.Float64(),
Exchange: g.Name,
Exchange: e.Name,
OrderID: resp.Result[x].ID,
Side: side,
Type: orderType,
@@ -472,12 +472,12 @@ func (g *Gateio) processSpotOrders(data []byte) error {
LastUpdated: resp.Result[x].UpdateTime.Time(),
}
}
g.Websocket.DataHandler <- details
e.Websocket.DataHandler <- details
return nil
}
func (g *Gateio) processUserPersonalTrades(data []byte) error {
if !g.IsFillsFeedEnabled() {
func (e *Exchange) processUserPersonalTrades(data []byte) error {
if !e.IsFillsFeedEnabled() {
return nil
}
@@ -499,7 +499,7 @@ func (g *Gateio) processUserPersonalTrades(data []byte) error {
}
fills[x] = fill.Data{
Timestamp: resp.Result[x].CreateTime.Time(),
Exchange: g.Name,
Exchange: e.Name,
CurrencyPair: resp.Result[x].CurrencyPair,
Side: side,
OrderID: resp.Result[x].OrderID,
@@ -508,10 +508,10 @@ func (g *Gateio) processUserPersonalTrades(data []byte) error {
Amount: resp.Result[x].Amount.Float64(),
}
}
return g.Websocket.Fills.Update(fills...)
return e.Websocket.Fills.Update(fills...)
}
func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error {
func (e *Exchange) processSpotBalances(ctx context.Context, data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -522,7 +522,7 @@ func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error {
if err != nil {
return err
}
creds, err := g.GetCredentials(ctx)
creds, err := e.GetCredentials(ctx)
if err != nil {
return err
}
@@ -540,11 +540,11 @@ func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error {
},
}
}
g.Websocket.DataHandler <- changes
return account.ProcessChange(g.Name, changes, creds)
e.Websocket.DataHandler <- changes
return account.ProcessChange(e.Name, changes, creds)
}
func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error {
func (e *Exchange) processMarginBalances(ctx context.Context, data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -555,7 +555,7 @@ func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error {
if err != nil {
return err
}
creds, err := g.GetCredentials(ctx)
creds, err := e.GetCredentials(ctx)
if err != nil {
return err
}
@@ -572,11 +572,11 @@ func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error {
},
}
}
g.Websocket.DataHandler <- changes
return account.ProcessChange(g.Name, changes, creds)
e.Websocket.DataHandler <- changes
return account.ProcessChange(e.Name, changes, creds)
}
func (g *Gateio) processFundingBalances(data []byte) error {
func (e *Exchange) processFundingBalances(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -587,11 +587,11 @@ func (g *Gateio) processFundingBalances(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- resp
e.Websocket.DataHandler <- resp
return nil
}
func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) error {
func (e *Exchange) processCrossMarginBalance(ctx context.Context, data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -602,7 +602,7 @@ func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) err
if err != nil {
return err
}
creds, err := g.GetCredentials(ctx)
creds, err := e.GetCredentials(ctx)
if err != nil {
return err
}
@@ -619,11 +619,11 @@ func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) err
},
}
}
g.Websocket.DataHandler <- changes
return account.ProcessChange(g.Name, changes, creds)
e.Websocket.DataHandler <- changes
return account.ProcessChange(e.Name, changes, creds)
}
func (g *Gateio) processCrossMarginLoans(data []byte) error {
func (e *Exchange) processCrossMarginLoans(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -634,17 +634,17 @@ func (g *Gateio) processCrossMarginLoans(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- resp
e.Websocket.DataHandler <- resp
return nil
}
// generateSubscriptionsSpot returns configured subscriptions
func (g *Gateio) generateSubscriptionsSpot() (subscription.List, error) {
return g.Features.Subscriptions.ExpandTemplates(g)
func (e *Exchange) generateSubscriptionsSpot() (subscription.List, error) {
return e.Features.Subscriptions.ExpandTemplates(e)
}
// GetSubscriptionTemplate returns a subscription channel template
func (g *Gateio) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) {
func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) {
return template.New("master.tmpl").
Funcs(sprig.FuncMap()).
Funcs(template.FuncMap{
@@ -657,16 +657,16 @@ func (g *Gateio) GetSubscriptionTemplate(_ *subscription.Subscription) (*templat
}
// manageSubs sends a websocket message to subscribe or unsubscribe from a list of channel
func (g *Gateio) manageSubs(ctx context.Context, event string, conn websocket.Connection, subs subscription.List) error {
func (e *Exchange) manageSubs(ctx context.Context, event string, conn websocket.Connection, subs subscription.List) error {
var errs error
subs, errs = subs.ExpandTemplates(g)
subs, errs = subs.ExpandTemplates(e)
if errs != nil {
return errs
}
for _, s := range subs {
if err := func() error {
msg, err := g.manageSubReq(ctx, event, conn, s)
msg, err := e.manageSubReq(ctx, event, conn, s)
if err != nil {
return err
}
@@ -682,9 +682,9 @@ func (g *Gateio) manageSubs(ctx context.Context, event string, conn websocket.Co
return fmt.Errorf("(%d) %s", resp.Error.Code, resp.Error.Message)
}
if event == "unsubscribe" {
return g.Websocket.RemoveSubscriptions(conn, s)
return e.Websocket.RemoveSubscriptions(conn, s)
}
return g.Websocket.AddSuccessfulSubscriptions(conn, s)
return e.Websocket.AddSuccessfulSubscriptions(conn, s)
}(); err != nil {
errs = common.AppendError(errs, fmt.Errorf("%s %s %s: %w", s.Channel, s.Asset, s.Pairs, err))
}
@@ -693,7 +693,7 @@ func (g *Gateio) manageSubs(ctx context.Context, event string, conn websocket.Co
}
// manageSubReq constructs the subscription management message for a subscription
func (g *Gateio) manageSubReq(ctx context.Context, event string, conn websocket.Connection, s *subscription.Subscription) (*WsInput, error) {
func (e *Exchange) manageSubReq(ctx context.Context, event string, conn websocket.Connection, s *subscription.Subscription) (*WsInput, error) {
req := &WsInput{
ID: conn.GenerateMessageID(false),
Event: event,
@@ -702,11 +702,11 @@ func (g *Gateio) manageSubReq(ctx context.Context, event string, conn websocket.
Payload: strings.Split(s.QualifiedChannel, ","),
}
if s.Authenticated {
creds, err := g.GetCredentials(ctx)
creds, err := e.GetCredentials(ctx)
if err != nil {
return nil, err
}
sig, err := g.generateWsSignature(creds.Secret, event, req.Channel, req.Time)
sig, err := e.generateWsSignature(creds.Secret, event, req.Channel, req.Time)
if err != nil {
return nil, err
}
@@ -720,18 +720,18 @@ func (g *Gateio) manageSubReq(ctx context.Context, event string, conn websocket.
}
// Subscribe sends a websocket message to stop receiving data from the channel
func (g *Gateio) Subscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error {
return g.manageSubs(ctx, subscribeEvent, conn, subs)
func (e *Exchange) Subscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error {
return e.manageSubs(ctx, subscribeEvent, conn, subs)
}
// Unsubscribe sends a websocket message to stop receiving data from the channel
func (g *Gateio) Unsubscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error {
return g.manageSubs(ctx, unsubscribeEvent, conn, subs)
func (e *Exchange) Unsubscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error {
return e.manageSubs(ctx, unsubscribeEvent, conn, subs)
}
// GenerateWebsocketMessageID generates a message ID for the individual connection
func (g *Gateio) GenerateWebsocketMessageID(bool) int64 {
return g.Counter.IncrementAndGet()
func (e *Exchange) GenerateWebsocketMessageID(bool) int64 {
return e.Counter.IncrementAndGet()
}
// channelName converts global channel names to gateio specific channel names
@@ -754,7 +754,7 @@ func singleSymbolChannel(name string) bool {
// ValidateSubscriptions implements the subscription.ListValidator interface.
// It ensures that, for each orderbook pair asset, only one type of subscription (e.g., best bid/ask, orderbook update, or orderbook snapshot)
// is active at a time. Multiple concurrent subscriptions for the same asset are disallowed to prevent orderbook data corruption.
func (g *Gateio) ValidateSubscriptions(l subscription.List) error {
func (e *Exchange) ValidateSubscriptions(l subscription.List) error {
orderbookGuard := map[key.PairAsset]string{}
for _, s := range l {
n := channelName(s)
@@ -920,7 +920,7 @@ const subTplText = `
type GeneratePayload func(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error)
// handleSubscription sends a websocket message to receive data from the channel
func (g *Gateio) handleSubscription(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List, generatePayload GeneratePayload) error {
func (e *Exchange) handleSubscription(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List, generatePayload GeneratePayload) error {
payloads, err := generatePayload(ctx, conn, event, channelsToSubscribe)
if err != nil {
return err
@@ -941,9 +941,9 @@ func (g *Gateio) handleSubscription(ctx context.Context, conn websocket.Connecti
continue
}
if event == subscribeEvent {
errs = common.AppendError(errs, g.Websocket.AddSuccessfulSubscriptions(conn, channelsToSubscribe[k]))
errs = common.AppendError(errs, e.Websocket.AddSuccessfulSubscriptions(conn, channelsToSubscribe[k]))
} else {
errs = common.AppendError(errs, g.Websocket.RemoveSubscriptions(conn, channelsToSubscribe[k]))
errs = common.AppendError(errs, e.Websocket.RemoveSubscriptions(conn, channelsToSubscribe[k]))
}
}
}
@@ -955,13 +955,13 @@ type resultHolder struct {
}
// SendWebsocketRequest sends a websocket request to the exchange
func (g *Gateio) SendWebsocketRequest(ctx context.Context, epl request.EndpointLimit, channel string, connSignature, params, result any, expectedResponses int) error {
func (e *Exchange) SendWebsocketRequest(ctx context.Context, epl request.EndpointLimit, channel string, connSignature, params, result any, expectedResponses int) error {
paramPayload, err := json.Marshal(params)
if err != nil {
return err
}
conn, err := g.Websocket.GetConnection(connSignature)
conn, err := e.Websocket.GetConnection(connSignature)
if err != nil {
return err
}

View File

@@ -37,8 +37,8 @@ var defaultDeliveryFuturesSubscriptions = []string{
}
// WsDeliveryFuturesConnect initiates a websocket connection for delivery futures account
func (g *Gateio) WsDeliveryFuturesConnect(ctx context.Context, conn websocket.Connection) error {
if err := g.CurrencyPairs.IsAssetEnabled(asset.DeliveryFutures); err != nil {
func (e *Exchange) WsDeliveryFuturesConnect(ctx context.Context, conn websocket.Connection) error {
if err := e.CurrencyPairs.IsAssetEnabled(asset.DeliveryFutures); err != nil {
return err
}
if err := conn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil {
@@ -63,18 +63,18 @@ func (g *Gateio) WsDeliveryFuturesConnect(ctx context.Context, conn websocket.Co
// GenerateDeliveryFuturesDefaultSubscriptions returns delivery futures default subscriptions params.
// TODO: Update to use the new subscription template system
func (g *Gateio) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.List, error) {
func (e *Exchange) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.List, error) {
ctx := context.TODO()
_, err := g.GetCredentials(ctx)
_, err := e.GetCredentials(ctx)
if err != nil {
g.Websocket.SetCanUseAuthenticatedEndpoints(false)
e.Websocket.SetCanUseAuthenticatedEndpoints(false)
}
channelsToSubscribe := defaultDeliveryFuturesSubscriptions
if g.Websocket.CanUseAuthenticatedEndpoints() {
if e.Websocket.CanUseAuthenticatedEndpoints() {
channelsToSubscribe = append(channelsToSubscribe, futuresOrdersChannel, futuresUserTradesChannel, futuresBalancesChannel)
}
pairs, err := g.GetEnabledPairs(asset.DeliveryFutures)
pairs, err := e.GetEnabledPairs(asset.DeliveryFutures)
if err != nil {
if errors.Is(err, asset.ErrNotEnabled) {
return nil, nil // no enabled pairs, subscriptions require an associated pair.
@@ -96,7 +96,7 @@ func (g *Gateio) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.Lis
params["frequency"] = kline.HundredMilliseconds
params["level"] = strconv.FormatUint(deliveryFuturesUpdateLimit, 10)
}
fPair, err := g.FormatExchangeCurrency(pairs[j], asset.DeliveryFutures)
fPair, err := e.FormatExchangeCurrency(pairs[j], asset.DeliveryFutures)
if err != nil {
return nil, err
}
@@ -112,25 +112,25 @@ func (g *Gateio) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.Lis
}
// DeliveryFuturesSubscribe sends a websocket message to stop receiving data from the channel
func (g *Gateio) DeliveryFuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return g.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, g.generateDeliveryFuturesPayload)
func (e *Exchange) DeliveryFuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return e.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, e.generateDeliveryFuturesPayload)
}
// DeliveryFuturesUnsubscribe sends a websocket message to stop receiving data from the channel
func (g *Gateio) DeliveryFuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return g.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, g.generateDeliveryFuturesPayload)
func (e *Exchange) DeliveryFuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return e.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, e.generateDeliveryFuturesPayload)
}
func (g *Gateio) generateDeliveryFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) {
func (e *Exchange) generateDeliveryFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) {
if len(channelsToSubscribe) == 0 {
return nil, errors.New("cannot generate payload, no channels supplied")
}
var creds *account.Credentials
var err error
if g.Websocket.CanUseAuthenticatedEndpoints() {
creds, err = g.GetCredentials(ctx)
if e.Websocket.CanUseAuthenticatedEndpoints() {
creds, err = e.GetCredentials(ctx)
if err != nil {
g.Websocket.SetCanUseAuthenticatedEndpoints(false)
e.Websocket.SetCanUseAuthenticatedEndpoints(false)
}
}
outbound := make([]WsInput, 0, len(channelsToSubscribe))
@@ -142,7 +142,7 @@ func (g *Gateio) generateDeliveryFuturesPayload(ctx context.Context, conn websoc
timestamp := time.Now()
var params []string
params = []string{channelsToSubscribe[i].Pairs[0].String()}
if g.Websocket.CanUseAuthenticatedEndpoints() {
if e.Websocket.CanUseAuthenticatedEndpoints() {
switch channelsToSubscribe[i].Channel {
case futuresOrdersChannel, futuresUserTradesChannel,
futuresLiquidatesChannel, futuresAutoDeleveragesChannel,
@@ -154,7 +154,7 @@ func (g *Gateio) generateDeliveryFuturesPayload(ctx context.Context, conn websoc
params = append([]string{value}, params...)
}
var sigTemp string
sigTemp, err = g.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix())
sigTemp, err = e.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix())
if err != nil {
return nil, err
}

View File

@@ -58,12 +58,12 @@ var defaultFuturesSubscriptions = []string{
}
// WsFuturesConnect initiates a websocket connection for futures account
func (g *Gateio) WsFuturesConnect(ctx context.Context, conn websocket.Connection) error {
func (e *Exchange) WsFuturesConnect(ctx context.Context, conn websocket.Connection) error {
a := asset.USDTMarginedFutures
if conn.GetURL() == btcFuturesWebsocketURL {
a = asset.CoinMarginedFutures
}
if err := g.CurrencyPairs.IsAssetEnabled(a); err != nil {
if err := e.CurrencyPairs.IsAssetEnabled(a); err != nil {
return err
}
if err := conn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil {
@@ -88,13 +88,13 @@ func (g *Gateio) WsFuturesConnect(ctx context.Context, conn websocket.Connection
// GenerateFuturesDefaultSubscriptions returns default subscriptions information.
// TODO: Update to use the new subscription template system
func (g *Gateio) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription.List, error) {
func (e *Exchange) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription.List, error) {
channelsToSubscribe := defaultFuturesSubscriptions
if g.Websocket.CanUseAuthenticatedEndpoints() {
if e.Websocket.CanUseAuthenticatedEndpoints() {
channelsToSubscribe = append(channelsToSubscribe, futuresOrdersChannel, futuresUserTradesChannel, futuresBalancesChannel)
}
pairs, err := g.GetEnabledPairs(a)
pairs, err := e.GetEnabledPairs(a)
if err != nil {
if errors.Is(err, asset.ErrNotEnabled) {
return nil, nil // no enabled pairs, subscriptions require an associated pair.
@@ -117,7 +117,7 @@ func (g *Gateio) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription
params["frequency"] = kline.TwentyMilliseconds
params["level"] = strconv.FormatUint(futuresOrderbookUpdateLimit, 10)
}
fPair, err := g.FormatExchangeCurrency(pairs[j], a)
fPair, err := e.FormatExchangeCurrency(pairs[j], a)
if err != nil {
return nil, err
}
@@ -133,84 +133,84 @@ func (g *Gateio) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription
}
// FuturesSubscribe sends a websocket message to stop receiving data from the channel
func (g *Gateio) FuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return g.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, g.generateFuturesPayload)
func (e *Exchange) FuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return e.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, e.generateFuturesPayload)
}
// FuturesUnsubscribe sends a websocket message to stop receiving data from the channel
func (g *Gateio) FuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return g.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, g.generateFuturesPayload)
func (e *Exchange) FuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return e.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, e.generateFuturesPayload)
}
// WsHandleFuturesData handles futures websocket data
func (g *Gateio) WsHandleFuturesData(ctx context.Context, respRaw []byte, a asset.Item) error {
func (e *Exchange) WsHandleFuturesData(ctx context.Context, respRaw []byte, a asset.Item) error {
push, err := parseWSHeader(respRaw)
if err != nil {
return err
}
if push.RequestID != "" {
return g.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw)
return e.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw)
}
if push.Event == subscribeEvent || push.Event == unsubscribeEvent {
return g.Websocket.Match.RequireMatchWithData(push.ID, respRaw)
return e.Websocket.Match.RequireMatchWithData(push.ID, respRaw)
}
switch push.Channel {
case futuresTickersChannel:
return g.processFuturesTickers(respRaw, a)
return e.processFuturesTickers(respRaw, a)
case futuresTradesChannel:
return g.processFuturesTrades(respRaw, a)
return e.processFuturesTrades(respRaw, a)
case futuresOrderbookChannel:
return g.processFuturesOrderbookSnapshot(push.Event, push.Result, a, push.Time)
return e.processFuturesOrderbookSnapshot(push.Event, push.Result, a, push.Time)
case futuresOrderbookTickerChannel:
return g.processFuturesOrderbookTicker(push.Result)
return e.processFuturesOrderbookTicker(push.Result)
case futuresOrderbookUpdateChannel:
return g.processFuturesOrderbookUpdate(ctx, push.Result, a, push.Time)
return e.processFuturesOrderbookUpdate(ctx, push.Result, a, push.Time)
case futuresCandlesticksChannel:
return g.processFuturesCandlesticks(respRaw, a)
return e.processFuturesCandlesticks(respRaw, a)
case futuresOrdersChannel:
processed, err := g.processFuturesOrdersPushData(respRaw, a)
processed, err := e.processFuturesOrdersPushData(respRaw, a)
if err != nil {
return err
}
g.Websocket.DataHandler <- processed
e.Websocket.DataHandler <- processed
return nil
case futuresUserTradesChannel:
return g.procesFuturesUserTrades(respRaw, a)
return e.procesFuturesUserTrades(respRaw, a)
case futuresLiquidatesChannel:
return g.processFuturesLiquidatesNotification(respRaw)
return e.processFuturesLiquidatesNotification(respRaw)
case futuresAutoDeleveragesChannel:
return g.processFuturesAutoDeleveragesNotification(respRaw)
return e.processFuturesAutoDeleveragesNotification(respRaw)
case futuresAutoPositionCloseChannel:
return g.processPositionCloseData(respRaw)
return e.processPositionCloseData(respRaw)
case futuresBalancesChannel:
return g.processBalancePushData(ctx, respRaw, a)
return e.processBalancePushData(ctx, respRaw, a)
case futuresReduceRiskLimitsChannel:
return g.processFuturesReduceRiskLimitNotification(respRaw)
return e.processFuturesReduceRiskLimitNotification(respRaw)
case futuresPositionsChannel:
return g.processFuturesPositionsNotification(respRaw)
return e.processFuturesPositionsNotification(respRaw)
case futuresAutoOrdersChannel:
return g.processFuturesAutoOrderPushData(respRaw)
return e.processFuturesAutoOrderPushData(respRaw)
default:
g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
Message: g.Name + websocket.UnhandledMessage + string(respRaw),
e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
Message: e.Name + websocket.UnhandledMessage + string(respRaw),
}
return errors.New(websocket.UnhandledMessage)
}
}
func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) {
func (e *Exchange) generateFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) {
if len(channelsToSubscribe) == 0 {
return nil, errors.New("cannot generate payload, no channels supplied")
}
var creds *account.Credentials
var err error
if g.Websocket.CanUseAuthenticatedEndpoints() {
creds, err = g.GetCredentials(ctx)
if e.Websocket.CanUseAuthenticatedEndpoints() {
creds, err = e.GetCredentials(ctx)
if err != nil {
g.Websocket.SetCanUseAuthenticatedEndpoints(false)
e.Websocket.SetCanUseAuthenticatedEndpoints(false)
}
}
@@ -223,7 +223,7 @@ func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Conn
timestamp := time.Now()
var params []string
params = []string{channelsToSubscribe[i].Pairs[0].String()}
if g.Websocket.CanUseAuthenticatedEndpoints() {
if e.Websocket.CanUseAuthenticatedEndpoints() {
switch channelsToSubscribe[i].Channel {
case futuresOrdersChannel, futuresUserTradesChannel,
futuresLiquidatesChannel, futuresAutoDeleveragesChannel,
@@ -237,7 +237,7 @@ func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Conn
params...)
}
var sigTemp string
sigTemp, err = g.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix())
sigTemp, err = e.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix())
if err != nil {
return nil, err
}
@@ -298,7 +298,7 @@ func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Conn
return outbound, nil
}
func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error {
func (e *Exchange) processFuturesTickers(data []byte, assetType asset.Item) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -312,7 +312,7 @@ func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error
tickerPriceDatas := make([]ticker.Price, len(resp.Result))
for x := range resp.Result {
tickerPriceDatas[x] = ticker.Price{
ExchangeName: g.Name,
ExchangeName: e.Name,
Volume: resp.Result[x].Volume24HBase.Float64(),
QuoteVolume: resp.Result[x].Volume24HQuote.Float64(),
High: resp.Result[x].High24H.Float64(),
@@ -323,13 +323,13 @@ func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error
LastUpdated: resp.Time.Time(),
}
}
g.Websocket.DataHandler <- tickerPriceDatas
e.Websocket.DataHandler <- tickerPriceDatas
return nil
}
func (g *Gateio) processFuturesTrades(data []byte, assetType asset.Item) error {
saveTradeData := g.IsSaveTradeDataEnabled()
if !saveTradeData && !g.IsTradeFeedEnabled() {
func (e *Exchange) processFuturesTrades(data []byte, assetType asset.Item) error {
saveTradeData := e.IsSaveTradeDataEnabled()
if !saveTradeData && !e.IsTradeFeedEnabled() {
return nil
}
@@ -350,16 +350,16 @@ func (g *Gateio) processFuturesTrades(data []byte, assetType asset.Item) error {
Timestamp: resp.Result[x].CreateTime.Time(),
CurrencyPair: resp.Result[x].Contract,
AssetType: assetType,
Exchange: g.Name,
Exchange: e.Name,
Price: resp.Result[x].Price.Float64(),
Amount: resp.Result[x].Size,
TID: strconv.FormatInt(resp.Result[x].ID, 10),
}
}
return g.Websocket.Trade.Update(saveTradeData, trades...)
return e.Websocket.Trade.Update(saveTradeData, trades...)
}
func (g *Gateio) processFuturesCandlesticks(data []byte, assetType asset.Item) error {
func (e *Exchange) processFuturesCandlesticks(data []byte, assetType asset.Item) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -383,7 +383,7 @@ func (g *Gateio) processFuturesCandlesticks(data []byte, assetType asset.Item) e
klineDatas[x] = websocket.KlineData{
Pair: currencyPair,
AssetType: assetType,
Exchange: g.Name,
Exchange: e.Name,
StartTime: resp.Result[x].Timestamp.Time(),
Interval: icp[0],
OpenPrice: resp.Result[x].OpenPrice.Float64(),
@@ -393,21 +393,21 @@ func (g *Gateio) processFuturesCandlesticks(data []byte, assetType asset.Item) e
Volume: resp.Result[x].Volume,
}
}
g.Websocket.DataHandler <- klineDatas
e.Websocket.DataHandler <- klineDatas
return nil
}
func (g *Gateio) processFuturesOrderbookTicker(incoming []byte) error {
func (e *Exchange) processFuturesOrderbookTicker(incoming []byte) error {
var data WsFuturesOrderbookTicker
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- data
e.Websocket.DataHandler <- data
return nil
}
func (g *Gateio) processFuturesOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error {
func (e *Exchange) processFuturesOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error {
var data WsFuturesAndOptionsOrderbookUpdate
if err := json.Unmarshal(incoming, &data); err != nil {
return err
@@ -423,7 +423,7 @@ func (g *Gateio) processFuturesOrderbookUpdate(ctx context.Context, incoming []b
bids[x].Amount = data.Bids[x].Size
}
return g.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, g, data.FirstUpdatedID, &orderbook.Update{
return e.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, e, data.FirstUpdatedID, &orderbook.Update{
UpdateID: data.LastUpdatedID,
UpdateTime: data.Timestamp.Time(),
LastPushed: pushTime,
@@ -435,7 +435,7 @@ func (g *Gateio) processFuturesOrderbookUpdate(ctx context.Context, incoming []b
})
}
func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, assetType asset.Item, lastPushed time.Time) error {
func (e *Exchange) processFuturesOrderbookSnapshot(event string, incoming []byte, assetType asset.Item, lastPushed time.Time) error {
if event == "all" {
var data WsFuturesOrderbookSnapshot
err := json.Unmarshal(incoming, &data)
@@ -444,11 +444,11 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte,
}
base := orderbook.Book{
Asset: assetType,
Exchange: g.Name,
Exchange: e.Name,
Pair: data.Contract,
LastUpdated: data.Timestamp.Time(),
LastPushed: lastPushed,
ValidateOrderbook: g.ValidateOrderbook,
ValidateOrderbook: e.ValidateOrderbook,
}
base.Asks = make([]orderbook.Level, len(data.Asks))
for x := range data.Asks {
@@ -460,7 +460,7 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte,
base.Bids[x].Amount = data.Bids[x].Size
base.Bids[x].Price = data.Bids[x].Price.Float64()
}
return g.Websocket.Orderbook.LoadSnapshot(&base)
return e.Websocket.Orderbook.LoadSnapshot(&base)
}
var data []WsFuturesOrderbookUpdateEvent
err := json.Unmarshal(incoming, &data)
@@ -496,15 +496,15 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte,
if err != nil {
return err
}
err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Asks: ab[0],
Bids: ab[1],
Asset: assetType,
Exchange: g.Name,
Exchange: e.Name,
Pair: currencyPair,
LastUpdated: lastPushed,
LastPushed: lastPushed,
ValidateOrderbook: g.ValidateOrderbook,
ValidateOrderbook: e.ValidateOrderbook,
})
if err != nil {
return err
@@ -513,7 +513,7 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte,
return nil
}
func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item) ([]order.Detail, error) {
func (e *Exchange) processFuturesOrdersPushData(data []byte, assetType asset.Item) ([]order.Detail, error) {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -537,8 +537,8 @@ func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item)
status, err = order.StringToOrderStatus(resp.Result[x].Status)
}
if err != nil {
g.Websocket.DataHandler <- order.ClassificationError{
Exchange: g.Name,
e.Websocket.DataHandler <- order.ClassificationError{
Exchange: e.Name,
OrderID: strconv.FormatInt(resp.Result[x].ID, 10),
Err: err,
}
@@ -546,7 +546,7 @@ func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item)
orderDetails[x] = order.Detail{
Amount: resp.Result[x].Size,
Exchange: g.Name,
Exchange: e.Name,
OrderID: strconv.FormatInt(resp.Result[x].ID, 10),
Status: status,
Pair: resp.Result[x].Contract,
@@ -562,8 +562,8 @@ func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item)
return orderDetails, nil
}
func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) error {
if !g.IsFillsFeedEnabled() {
func (e *Exchange) procesFuturesUserTrades(data []byte, assetType asset.Item) error {
if !e.IsFillsFeedEnabled() {
return nil
}
@@ -581,7 +581,7 @@ func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) erro
for x := range resp.Result {
fills[x] = fill.Data{
Timestamp: resp.Result[x].CreateTime.Time(),
Exchange: g.Name,
Exchange: e.Name,
CurrencyPair: resp.Result[x].Contract,
OrderID: resp.Result[x].OrderID,
TradeID: resp.Result[x].ID,
@@ -590,10 +590,10 @@ func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) erro
AssetType: assetType,
}
}
return g.Websocket.Fills.Update(fills...)
return e.Websocket.Fills.Update(fills...)
}
func (g *Gateio) processFuturesLiquidatesNotification(data []byte) error {
func (e *Exchange) processFuturesLiquidatesNotification(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -604,11 +604,11 @@ func (g *Gateio) processFuturesLiquidatesNotification(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}
func (g *Gateio) processFuturesAutoDeleveragesNotification(data []byte) error {
func (e *Exchange) processFuturesAutoDeleveragesNotification(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -619,11 +619,11 @@ func (g *Gateio) processFuturesAutoDeleveragesNotification(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}
func (g *Gateio) processPositionCloseData(data []byte) error {
func (e *Exchange) processPositionCloseData(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -634,11 +634,11 @@ func (g *Gateio) processPositionCloseData(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}
func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetType asset.Item) error {
func (e *Exchange) processBalancePushData(ctx context.Context, data []byte, assetType asset.Item) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -649,7 +649,7 @@ func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetT
if err != nil {
return err
}
creds, err := g.GetCredentials(ctx)
creds, err := e.GetCredentials(ctx)
if err != nil {
return err
}
@@ -670,11 +670,11 @@ func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetT
},
}
}
g.Websocket.DataHandler <- changes
return account.ProcessChange(g.Name, changes, creds)
e.Websocket.DataHandler <- changes
return account.ProcessChange(e.Name, changes, creds)
}
func (g *Gateio) processFuturesReduceRiskLimitNotification(data []byte) error {
func (e *Exchange) processFuturesReduceRiskLimitNotification(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -685,11 +685,11 @@ func (g *Gateio) processFuturesReduceRiskLimitNotification(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}
func (g *Gateio) processFuturesPositionsNotification(data []byte) error {
func (e *Exchange) processFuturesPositionsNotification(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -700,11 +700,11 @@ func (g *Gateio) processFuturesPositionsNotification(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}
func (g *Gateio) processFuturesAutoOrderPushData(data []byte) error {
func (e *Exchange) processFuturesAutoOrderPushData(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -715,6 +715,6 @@ func (g *Gateio) processFuturesAutoOrderPushData(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}

View File

@@ -67,8 +67,8 @@ var defaultOptionsSubscriptions = []string{
}
// WsOptionsConnect initiates a websocket connection to options websocket endpoints.
func (g *Gateio) WsOptionsConnect(ctx context.Context, conn websocket.Connection) error {
err := g.CurrencyPairs.IsAssetEnabled(asset.Options)
func (e *Exchange) WsOptionsConnect(ctx context.Context, conn websocket.Connection) error {
err := e.CurrencyPairs.IsAssetEnabled(asset.Options)
if err != nil {
return err
}
@@ -95,18 +95,18 @@ func (g *Gateio) WsOptionsConnect(ctx context.Context, conn websocket.Connection
// GenerateOptionsDefaultSubscriptions generates list of channel subscriptions for options asset type.
// TODO: Update to use the new subscription template system
func (g *Gateio) GenerateOptionsDefaultSubscriptions() (subscription.List, error) {
func (e *Exchange) GenerateOptionsDefaultSubscriptions() (subscription.List, error) {
ctx := context.TODO()
channelsToSubscribe := defaultOptionsSubscriptions
var userID int64
if g.Websocket.CanUseAuthenticatedEndpoints() {
if e.Websocket.CanUseAuthenticatedEndpoints() {
var err error
_, err = g.GetCredentials(ctx)
_, err = e.GetCredentials(ctx)
if err != nil {
g.Websocket.SetCanUseAuthenticatedEndpoints(false)
e.Websocket.SetCanUseAuthenticatedEndpoints(false)
goto getEnabledPairs
}
response, err := g.GetSubAccountBalances(ctx, "")
response, err := e.GetSubAccountBalances(ctx, "")
if err != nil {
return nil, err
}
@@ -116,14 +116,14 @@ func (g *Gateio) GenerateOptionsDefaultSubscriptions() (subscription.List, error
optionsBalancesChannel,
)
userID = response[0].UserID
} else if g.Verbose {
} else if e.Verbose {
log.Errorf(log.ExchangeSys, "no subaccount found for authenticated options channel subscriptions")
}
}
getEnabledPairs:
pairs, err := g.GetEnabledPairs(asset.Options)
pairs, err := e.GetEnabledPairs(asset.Options)
if err != nil {
if errors.Is(err, asset.ErrNotEnabled) {
return nil, nil // no enabled pairs, subscriptions require an associated pair.
@@ -156,7 +156,7 @@ getEnabledPairs:
}
params["user_id"] = userID
}
fPair, err := g.FormatExchangeCurrency(pairs[j], asset.Options)
fPair, err := e.FormatExchangeCurrency(pairs[j], asset.Options)
if err != nil {
return nil, err
}
@@ -171,7 +171,7 @@ getEnabledPairs:
return subscriptions, nil
}
func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) {
func (e *Exchange) generateOptionsPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) {
if len(channelsToSubscribe) == 0 {
return nil, errors.New("cannot generate payload, no channels supplied")
}
@@ -191,7 +191,7 @@ func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Conn
optionsUnderlyingPriceChannel,
optionsUnderlyingCandlesticksChannel:
var uly currency.Pair
uly, err = g.GetUnderlyingFromCurrencyPair(channelsToSubscribe[i].Pairs[0])
uly, err = e.GetUnderlyingFromCurrencyPair(channelsToSubscribe[i].Pairs[0])
if err != nil {
return nil, err
}
@@ -230,12 +230,12 @@ func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Conn
}
params = append([]string{strconv.FormatInt(userID, 10)}, params...)
var creds *account.Credentials
creds, err = g.GetCredentials(ctx)
creds, err = e.GetCredentials(ctx)
if err != nil {
return nil, err
}
var sigTemp string
sigTemp, err = g.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix())
sigTemp, err = e.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix())
if err != nil {
return nil, err
}
@@ -285,106 +285,106 @@ func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Conn
}
// OptionsSubscribe sends a websocket message to stop receiving data for asset type options
func (g *Gateio) OptionsSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return g.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, g.generateOptionsPayload)
func (e *Exchange) OptionsSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return e.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, e.generateOptionsPayload)
}
// OptionsUnsubscribe sends a websocket message to stop receiving data for asset type options
func (g *Gateio) OptionsUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return g.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, g.generateOptionsPayload)
func (e *Exchange) OptionsUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error {
return e.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, e.generateOptionsPayload)
}
// WsHandleOptionsData handles options websocket data
func (g *Gateio) WsHandleOptionsData(ctx context.Context, respRaw []byte) error {
func (e *Exchange) WsHandleOptionsData(ctx context.Context, respRaw []byte) error {
push, err := parseWSHeader(respRaw)
if err != nil {
return err
}
if push.Event == subscribeEvent || push.Event == unsubscribeEvent {
return g.Websocket.Match.RequireMatchWithData(push.ID, respRaw)
return e.Websocket.Match.RequireMatchWithData(push.ID, respRaw)
}
switch push.Channel {
case optionsContractTickersChannel:
return g.processOptionsContractTickers(push.Result)
return e.processOptionsContractTickers(push.Result)
case optionsUnderlyingTickersChannel:
return g.processOptionsUnderlyingTicker(push.Result)
return e.processOptionsUnderlyingTicker(push.Result)
case optionsTradesChannel,
optionsUnderlyingTradesChannel:
return g.processOptionsTradesPushData(respRaw)
return e.processOptionsTradesPushData(respRaw)
case optionsUnderlyingPriceChannel:
return g.processOptionsUnderlyingPricePushData(push.Result)
return e.processOptionsUnderlyingPricePushData(push.Result)
case optionsMarkPriceChannel:
return g.processOptionsMarkPrice(push.Result)
return e.processOptionsMarkPrice(push.Result)
case optionsSettlementChannel:
return g.processOptionsSettlementPushData(push.Result)
return e.processOptionsSettlementPushData(push.Result)
case optionsContractsChannel:
return g.processOptionsContractPushData(push.Result)
return e.processOptionsContractPushData(push.Result)
case optionsContractCandlesticksChannel,
optionsUnderlyingCandlesticksChannel:
return g.processOptionsCandlestickPushData(respRaw)
return e.processOptionsCandlestickPushData(respRaw)
case optionsOrderbookChannel:
return g.processOptionsOrderbookSnapshotPushData(push.Event, push.Result, push.Time)
return e.processOptionsOrderbookSnapshotPushData(push.Event, push.Result, push.Time)
case optionsOrderbookTickerChannel:
return g.processOrderbookTickerPushData(respRaw)
return e.processOrderbookTickerPushData(respRaw)
case optionsOrderbookUpdateChannel:
return g.processOptionsOrderbookUpdate(ctx, push.Result, asset.Options, push.Time)
return e.processOptionsOrderbookUpdate(ctx, push.Result, asset.Options, push.Time)
case optionsOrdersChannel:
return g.processOptionsOrderPushData(respRaw)
return e.processOptionsOrderPushData(respRaw)
case optionsUserTradesChannel:
return g.processOptionsUserTradesPushData(respRaw)
return e.processOptionsUserTradesPushData(respRaw)
case optionsLiquidatesChannel:
return g.processOptionsLiquidatesPushData(respRaw)
return e.processOptionsLiquidatesPushData(respRaw)
case optionsUserSettlementChannel:
return g.processOptionsUsersPersonalSettlementsPushData(respRaw)
return e.processOptionsUsersPersonalSettlementsPushData(respRaw)
case optionsPositionCloseChannel:
return g.processPositionCloseData(respRaw)
return e.processPositionCloseData(respRaw)
case optionsBalancesChannel:
return g.processBalancePushData(ctx, respRaw, asset.Options)
return e.processBalancePushData(ctx, respRaw, asset.Options)
case optionsPositionsChannel:
return g.processOptionsPositionPushData(respRaw)
return e.processOptionsPositionPushData(respRaw)
default:
g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
Message: g.Name + websocket.UnhandledMessage + string(respRaw),
e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
Message: e.Name + websocket.UnhandledMessage + string(respRaw),
}
return errors.New(websocket.UnhandledMessage)
}
}
func (g *Gateio) processOptionsContractTickers(incoming []byte) error {
func (e *Exchange) processOptionsContractTickers(incoming []byte) error {
var data OptionsTicker
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- &ticker.Price{
e.Websocket.DataHandler <- &ticker.Price{
Pair: data.Name,
Last: data.LastPrice.Float64(),
Bid: data.Bid1Price.Float64(),
Ask: data.Ask1Price.Float64(),
AskSize: data.Ask1Size,
BidSize: data.Bid1Size,
ExchangeName: g.Name,
ExchangeName: e.Name,
AssetType: asset.Options,
}
return nil
}
func (g *Gateio) processOptionsUnderlyingTicker(incoming []byte) error {
func (e *Exchange) processOptionsUnderlyingTicker(incoming []byte) error {
var data WsOptionUnderlyingTicker
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- &data
e.Websocket.DataHandler <- &data
return nil
}
func (g *Gateio) processOptionsTradesPushData(data []byte) error {
saveTradeData := g.IsSaveTradeDataEnabled()
func (e *Exchange) processOptionsTradesPushData(data []byte) error {
saveTradeData := e.IsSaveTradeDataEnabled()
if !saveTradeData &&
!g.IsTradeFeedEnabled() {
!e.IsTradeFeedEnabled() {
return nil
}
resp := struct {
@@ -403,56 +403,56 @@ func (g *Gateio) processOptionsTradesPushData(data []byte) error {
Timestamp: resp.Result[x].CreateTime.Time(),
CurrencyPair: resp.Result[x].Contract,
AssetType: asset.Options,
Exchange: g.Name,
Exchange: e.Name,
Price: resp.Result[x].Price,
Amount: resp.Result[x].Size,
TID: strconv.FormatInt(resp.Result[x].ID, 10),
}
}
return g.Websocket.Trade.Update(saveTradeData, trades...)
return e.Websocket.Trade.Update(saveTradeData, trades...)
}
func (g *Gateio) processOptionsUnderlyingPricePushData(incoming []byte) error {
func (e *Exchange) processOptionsUnderlyingPricePushData(incoming []byte) error {
var data WsOptionsUnderlyingPrice
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- &data
e.Websocket.DataHandler <- &data
return nil
}
func (g *Gateio) processOptionsMarkPrice(incoming []byte) error {
func (e *Exchange) processOptionsMarkPrice(incoming []byte) error {
var data WsOptionsMarkPrice
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- &data
e.Websocket.DataHandler <- &data
return nil
}
func (g *Gateio) processOptionsSettlementPushData(incoming []byte) error {
func (e *Exchange) processOptionsSettlementPushData(incoming []byte) error {
var data WsOptionsSettlement
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- &data
e.Websocket.DataHandler <- &data
return nil
}
func (g *Gateio) processOptionsContractPushData(incoming []byte) error {
func (e *Exchange) processOptionsContractPushData(incoming []byte) error {
var data WsOptionsContract
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- &data
e.Websocket.DataHandler <- &data
return nil
}
func (g *Gateio) processOptionsCandlestickPushData(data []byte) error {
func (e *Exchange) processOptionsCandlestickPushData(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -476,7 +476,7 @@ func (g *Gateio) processOptionsCandlestickPushData(data []byte) error {
klineDatas[x] = websocket.KlineData{
Pair: currencyPair,
AssetType: asset.Options,
Exchange: g.Name,
Exchange: e.Name,
StartTime: resp.Result[x].Timestamp.Time(),
Interval: icp[0],
OpenPrice: resp.Result[x].OpenPrice.Float64(),
@@ -486,21 +486,21 @@ func (g *Gateio) processOptionsCandlestickPushData(data []byte) error {
Volume: resp.Result[x].Amount.Float64(),
}
}
g.Websocket.DataHandler <- klineDatas
e.Websocket.DataHandler <- klineDatas
return nil
}
func (g *Gateio) processOrderbookTickerPushData(incoming []byte) error {
func (e *Exchange) processOrderbookTickerPushData(incoming []byte) error {
var data WsOptionsOrderbookTicker
err := json.Unmarshal(incoming, &data)
if err != nil {
return err
}
g.Websocket.DataHandler <- &data
e.Websocket.DataHandler <- &data
return nil
}
func (g *Gateio) processOptionsOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error {
func (e *Exchange) processOptionsOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error {
var data WsFuturesAndOptionsOrderbookUpdate
if err := json.Unmarshal(incoming, &data); err != nil {
return err
@@ -515,7 +515,7 @@ func (g *Gateio) processOptionsOrderbookUpdate(ctx context.Context, incoming []b
bids[x].Price = data.Bids[x].Price.Float64()
bids[x].Amount = data.Bids[x].Size
}
return g.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, g, data.FirstUpdatedID, &orderbook.Update{
return e.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, e, data.FirstUpdatedID, &orderbook.Update{
UpdateID: data.LastUpdatedID,
UpdateTime: data.Timestamp.Time(),
LastPushed: pushTime,
@@ -527,7 +527,7 @@ func (g *Gateio) processOptionsOrderbookUpdate(ctx context.Context, incoming []b
})
}
func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming []byte, lastPushed time.Time) error {
func (e *Exchange) processOptionsOrderbookSnapshotPushData(event string, incoming []byte, lastPushed time.Time) error {
if event == "all" {
var data WsOptionsOrderbookSnapshot
err := json.Unmarshal(incoming, &data)
@@ -536,11 +536,11 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming
}
base := orderbook.Book{
Asset: asset.Options,
Exchange: g.Name,
Exchange: e.Name,
Pair: data.Contract,
LastUpdated: data.Timestamp.Time(),
LastPushed: lastPushed,
ValidateOrderbook: g.ValidateOrderbook,
ValidateOrderbook: e.ValidateOrderbook,
}
base.Asks = make([]orderbook.Level, len(data.Asks))
for x := range data.Asks {
@@ -552,7 +552,7 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming
base.Bids[x].Amount = data.Bids[x].Size
base.Bids[x].Price = data.Bids[x].Price.Float64()
}
return g.Websocket.Orderbook.LoadSnapshot(&base)
return e.Websocket.Orderbook.LoadSnapshot(&base)
}
var data []WsFuturesOrderbookUpdateEvent
err := json.Unmarshal(incoming, &data)
@@ -586,15 +586,15 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming
if err != nil {
return err
}
err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Asks: ab[0],
Bids: ab[1],
Asset: asset.Options,
Exchange: g.Name,
Exchange: e.Name,
Pair: currencyPair,
LastUpdated: lastPushed,
LastPushed: lastPushed,
ValidateOrderbook: g.ValidateOrderbook,
ValidateOrderbook: e.ValidateOrderbook,
})
if err != nil {
return err
@@ -603,7 +603,7 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming
return nil
}
func (g *Gateio) processOptionsOrderPushData(data []byte) error {
func (e *Exchange) processOptionsOrderPushData(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -627,7 +627,7 @@ func (g *Gateio) processOptionsOrderPushData(data []byte) error {
}
orderDetails[x] = order.Detail{
Amount: resp.Result[x].Size,
Exchange: g.Name,
Exchange: e.Name,
OrderID: strconv.FormatInt(resp.Result[x].ID, 10),
Status: status,
Pair: resp.Result[x].Contract,
@@ -638,12 +638,12 @@ func (g *Gateio) processOptionsOrderPushData(data []byte) error {
AccountID: resp.Result[x].User,
}
}
g.Websocket.DataHandler <- orderDetails
e.Websocket.DataHandler <- orderDetails
return nil
}
func (g *Gateio) processOptionsUserTradesPushData(data []byte) error {
if !g.IsFillsFeedEnabled() {
func (e *Exchange) processOptionsUserTradesPushData(data []byte) error {
if !e.IsFillsFeedEnabled() {
return nil
}
resp := struct {
@@ -660,7 +660,7 @@ func (g *Gateio) processOptionsUserTradesPushData(data []byte) error {
for x := range resp.Result {
fills[x] = fill.Data{
Timestamp: resp.Result[x].CreateTime.Time(),
Exchange: g.Name,
Exchange: e.Name,
CurrencyPair: resp.Result[x].Contract,
OrderID: resp.Result[x].OrderID,
TradeID: resp.Result[x].ID,
@@ -668,10 +668,10 @@ func (g *Gateio) processOptionsUserTradesPushData(data []byte) error {
Amount: resp.Result[x].Size,
}
}
return g.Websocket.Fills.Update(fills...)
return e.Websocket.Fills.Update(fills...)
}
func (g *Gateio) processOptionsLiquidatesPushData(data []byte) error {
func (e *Exchange) processOptionsLiquidatesPushData(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -682,11 +682,11 @@ func (g *Gateio) processOptionsLiquidatesPushData(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}
func (g *Gateio) processOptionsUsersPersonalSettlementsPushData(data []byte) error {
func (e *Exchange) processOptionsUsersPersonalSettlementsPushData(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -697,11 +697,11 @@ func (g *Gateio) processOptionsUsersPersonalSettlementsPushData(data []byte) err
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}
func (g *Gateio) processOptionsPositionPushData(data []byte) error {
func (e *Exchange) processOptionsPositionPushData(data []byte) error {
resp := struct {
Time types.Time `json:"time"`
Channel string `json:"channel"`
@@ -712,6 +712,6 @@ func (g *Gateio) processOptionsPositionPushData(data []byte) error {
if err != nil {
return err
}
g.Websocket.DataHandler <- &resp
e.Websocket.DataHandler <- &resp
return nil
}

View File

@@ -18,13 +18,13 @@ var (
)
// authenticateFutures sends an authentication message to the websocket connection
func (g *Gateio) authenticateFutures(ctx context.Context, conn websocket.Connection) error {
return g.websocketLogin(ctx, conn, "futures.login")
func (e *Exchange) authenticateFutures(ctx context.Context, conn websocket.Connection) error {
return e.websocketLogin(ctx, conn, "futures.login")
}
// WebsocketFuturesSubmitOrder submits an order via the websocket connection
func (g *Gateio) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item, order *ContractOrderCreateParams) (*WebsocketFuturesOrderResponse, error) {
resps, err := g.WebsocketFuturesSubmitOrders(ctx, a, order)
func (e *Exchange) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item, order *ContractOrderCreateParams) (*WebsocketFuturesOrderResponse, error) {
resps, err := e.WebsocketFuturesSubmitOrders(ctx, a, order)
if err != nil {
return nil, err
}
@@ -35,7 +35,7 @@ func (g *Gateio) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item,
}
// WebsocketFuturesSubmitOrders submits orders via the websocket connection. All orders must be for the same asset.
func (g *Gateio) WebsocketFuturesSubmitOrders(ctx context.Context, a asset.Item, orders ...*ContractOrderCreateParams) ([]WebsocketFuturesOrderResponse, error) {
func (e *Exchange) WebsocketFuturesSubmitOrders(ctx context.Context, a asset.Item, orders ...*ContractOrderCreateParams) ([]WebsocketFuturesOrderResponse, error) {
if len(orders) == 0 {
return nil, errOrdersEmpty
}
@@ -65,16 +65,16 @@ func (g *Gateio) WebsocketFuturesSubmitOrders(ctx context.Context, a asset.Item,
if len(orders) == 1 {
var singleResponse WebsocketFuturesOrderResponse
err := g.SendWebsocketRequest(ctx, perpetualSubmitOrderEPL, "futures.order_place", a, orders[0], &singleResponse, 2)
err := e.SendWebsocketRequest(ctx, perpetualSubmitOrderEPL, "futures.order_place", a, orders[0], &singleResponse, 2)
return []WebsocketFuturesOrderResponse{singleResponse}, err
}
var resp []WebsocketFuturesOrderResponse
return resp, g.SendWebsocketRequest(ctx, perpetualSubmitBatchOrdersEPL, "futures.order_batch_place", a, orders, &resp, 2)
return resp, e.SendWebsocketRequest(ctx, perpetualSubmitBatchOrdersEPL, "futures.order_batch_place", a, orders, &resp, 2)
}
// WebsocketFuturesCancelOrder cancels an order via the websocket connection.
func (g *Gateio) WebsocketFuturesCancelOrder(ctx context.Context, orderID string, contract currency.Pair, a asset.Item) (*WebsocketFuturesOrderResponse, error) {
func (e *Exchange) WebsocketFuturesCancelOrder(ctx context.Context, orderID string, contract currency.Pair, a asset.Item) (*WebsocketFuturesOrderResponse, error) {
if orderID == "" {
return nil, order.ErrOrderIDNotSet
}
@@ -88,11 +88,11 @@ func (g *Gateio) WebsocketFuturesCancelOrder(ctx context.Context, orderID string
}{OrderID: orderID}
var resp WebsocketFuturesOrderResponse
return &resp, g.SendWebsocketRequest(ctx, perpetualCancelOrderEPL, "futures.order_cancel", a, params, &resp, 1)
return &resp, e.SendWebsocketRequest(ctx, perpetualCancelOrderEPL, "futures.order_cancel", a, params, &resp, 1)
}
// WebsocketFuturesCancelAllOpenFuturesOrders cancels multiple orders via the websocket.
func (g *Gateio) WebsocketFuturesCancelAllOpenFuturesOrders(ctx context.Context, contract currency.Pair, a asset.Item, side string) ([]WebsocketFuturesOrderResponse, error) {
func (e *Exchange) WebsocketFuturesCancelAllOpenFuturesOrders(ctx context.Context, contract currency.Pair, a asset.Item, side string) ([]WebsocketFuturesOrderResponse, error) {
if err := validateFuturesPairAsset(contract, a); err != nil {
return nil, err
}
@@ -107,11 +107,11 @@ func (g *Gateio) WebsocketFuturesCancelAllOpenFuturesOrders(ctx context.Context,
}{Contract: contract, Side: side}
var resp []WebsocketFuturesOrderResponse
return resp, g.SendWebsocketRequest(ctx, perpetualCancelOpenOrdersEPL, "futures.order_cancel_cp", a, params, &resp, 2)
return resp, e.SendWebsocketRequest(ctx, perpetualCancelOpenOrdersEPL, "futures.order_cancel_cp", a, params, &resp, 2)
}
// WebsocketFuturesAmendOrder amends an order via the websocket connection
func (g *Gateio) WebsocketFuturesAmendOrder(ctx context.Context, amend *WebsocketFuturesAmendOrder) (*WebsocketFuturesOrderResponse, error) {
func (e *Exchange) WebsocketFuturesAmendOrder(ctx context.Context, amend *WebsocketFuturesAmendOrder) (*WebsocketFuturesOrderResponse, error) {
if amend == nil {
return nil, fmt.Errorf("%w: %T", common.ErrNilPointer, amend)
}
@@ -129,11 +129,11 @@ func (g *Gateio) WebsocketFuturesAmendOrder(ctx context.Context, amend *Websocke
}
var resp WebsocketFuturesOrderResponse
return &resp, g.SendWebsocketRequest(ctx, perpetualAmendOrderEPL, "futures.order_amend", amend.Asset, amend, &resp, 1)
return &resp, e.SendWebsocketRequest(ctx, perpetualAmendOrderEPL, "futures.order_amend", amend.Asset, amend, &resp, 1)
}
// WebsocketFuturesOrderList fetches a list of orders via the websocket connection
func (g *Gateio) WebsocketFuturesOrderList(ctx context.Context, list *WebsocketFutureOrdersList) ([]WebsocketFuturesOrderResponse, error) {
func (e *Exchange) WebsocketFuturesOrderList(ctx context.Context, list *WebsocketFutureOrdersList) ([]WebsocketFuturesOrderResponse, error) {
if list == nil {
return nil, fmt.Errorf("%w: %T", common.ErrNilPointer, list)
}
@@ -147,11 +147,11 @@ func (g *Gateio) WebsocketFuturesOrderList(ctx context.Context, list *WebsocketF
}
var resp []WebsocketFuturesOrderResponse
return resp, g.SendWebsocketRequest(ctx, perpetualGetOrdersEPL, "futures.order_list", list.Asset, list, &resp, 1)
return resp, e.SendWebsocketRequest(ctx, perpetualGetOrdersEPL, "futures.order_list", list.Asset, list, &resp, 1)
}
// WebsocketFuturesGetOrderStatus gets the status of an order via the websocket connection.
func (g *Gateio) WebsocketFuturesGetOrderStatus(ctx context.Context, contract currency.Pair, a asset.Item, orderID string) (*WebsocketFuturesOrderResponse, error) {
func (e *Exchange) WebsocketFuturesGetOrderStatus(ctx context.Context, contract currency.Pair, a asset.Item, orderID string) (*WebsocketFuturesOrderResponse, error) {
if err := validateFuturesPairAsset(contract, a); err != nil {
return nil, err
}
@@ -165,7 +165,7 @@ func (g *Gateio) WebsocketFuturesGetOrderStatus(ctx context.Context, contract cu
}{OrderID: orderID}
var resp WebsocketFuturesOrderResponse
return &resp, g.SendWebsocketRequest(ctx, perpetualFetchOrderEPL, "futures.order_status", a, params, &resp, 1)
return &resp, e.SendWebsocketRequest(ctx, perpetualFetchOrderEPL, "futures.order_status", a, params, &resp, 1)
}
// validateFuturesPairAsset enforces that a futures pair's quote currency matches the given asset

View File

@@ -18,22 +18,22 @@ var (
func TestWebsocketFuturesSubmitOrder(t *testing.T) {
t.Parallel()
_, err := g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, &ContractOrderCreateParams{})
_, err := e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, &ContractOrderCreateParams{})
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
out := &ContractOrderCreateParams{Contract: BTCUSDT}
_, err = g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, errInvalidPrice)
out.Price = "40000"
_, err = g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, errInvalidAmount)
out.Size = 1 // 1 lovely long contract
out.AutoSize = "silly_billies"
_, err = g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, errInvalidAutoSize)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Futures)
out.AutoSize = ""
got, err := g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
@@ -43,36 +43,36 @@ func TestWebsocketFuturesSubmitOrder(t *testing.T) {
func TestWebsocketFuturesSubmitOrders(t *testing.T) {
t.Parallel()
_, err := g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures)
_, err := e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures)
require.ErrorIs(t, err, errOrdersEmpty)
out := &ContractOrderCreateParams{}
_, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
out.Contract = BTCUSDT
_, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, errInvalidPrice)
out.Price = "40000"
_, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, errInvalidAmount)
out.Size = 1 // 1 lovely long contract
out.AutoSize = "silly_billies"
_, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, errInvalidAutoSize)
out.AutoSize = "close_long"
_, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
_, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out)
require.ErrorIs(t, err, errInvalidAmount)
out.AutoSize = ""
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Futures)
// test single order
got, err := g.WebsocketFuturesSubmitOrders(t.Context(), asset.CoinMarginedFutures, out)
@@ -87,18 +87,18 @@ func TestWebsocketFuturesSubmitOrders(t *testing.T) {
func TestWebsocketFuturesCancelOrder(t *testing.T) {
t.Parallel()
_, err := g.WebsocketFuturesCancelOrder(t.Context(), "", currency.EMPTYPAIR, asset.Empty)
_, err := e.WebsocketFuturesCancelOrder(t.Context(), "", currency.EMPTYPAIR, asset.Empty)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = g.WebsocketFuturesCancelOrder(t.Context(), "42069", currency.EMPTYPAIR, asset.Empty)
_, err = e.WebsocketFuturesCancelOrder(t.Context(), "42069", currency.EMPTYPAIR, asset.Empty)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
_, err = g.WebsocketFuturesCancelOrder(t.Context(), "42069", BTCUSDT, asset.Empty)
_, err = e.WebsocketFuturesCancelOrder(t.Context(), "42069", BTCUSDT, asset.Empty)
require.ErrorIs(t, err, asset.ErrNotSupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Futures)
got, err := g.WebsocketFuturesCancelOrder(t.Context(), "513160761072", BTCUSDT, asset.USDTMarginedFutures)
require.NoError(t, err)
@@ -107,18 +107,18 @@ func TestWebsocketFuturesCancelOrder(t *testing.T) {
func TestWebsocketFuturesCancelAllOpenFuturesOrders(t *testing.T) {
t.Parallel()
_, err := g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), currency.EMPTYPAIR, asset.Empty, "")
_, err := e.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), currency.EMPTYPAIR, asset.Empty, "")
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
_, err = g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.Empty, "bruh")
_, err = e.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.Empty, "bruh")
require.ErrorIs(t, err, asset.ErrNotSupported)
_, err = g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "bruh")
_, err = e.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "bruh")
require.ErrorIs(t, err, order.ErrSideIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Futures)
got, err := g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "bid")
require.NoError(t, err)
@@ -127,30 +127,30 @@ func TestWebsocketFuturesCancelAllOpenFuturesOrders(t *testing.T) {
func TestWebsocketFuturesAmendOrder(t *testing.T) {
t.Parallel()
_, err := g.WebsocketFuturesAmendOrder(t.Context(), nil)
_, err := e.WebsocketFuturesAmendOrder(t.Context(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
amend := &WebsocketFuturesAmendOrder{}
_, err = g.WebsocketFuturesAmendOrder(t.Context(), amend)
_, err = e.WebsocketFuturesAmendOrder(t.Context(), amend)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
amend.OrderID = "1337"
_, err = g.WebsocketFuturesAmendOrder(t.Context(), amend)
_, err = e.WebsocketFuturesAmendOrder(t.Context(), amend)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
amend.Contract = BTCUSDT
_, err = g.WebsocketFuturesAmendOrder(t.Context(), amend)
_, err = e.WebsocketFuturesAmendOrder(t.Context(), amend)
require.ErrorIs(t, err, asset.ErrNotSupported)
amend.Asset = asset.USDTMarginedFutures
_, err = g.WebsocketFuturesAmendOrder(t.Context(), amend)
_, err = e.WebsocketFuturesAmendOrder(t.Context(), amend)
require.ErrorIs(t, err, errInvalidAmount)
amend.Size = 2
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Futures)
amend.OrderID = "513170215869"
got, err := g.WebsocketFuturesAmendOrder(t.Context(), amend)
@@ -160,24 +160,24 @@ func TestWebsocketFuturesAmendOrder(t *testing.T) {
func TestWebsocketFuturesOrderList(t *testing.T) {
t.Parallel()
_, err := g.WebsocketFuturesOrderList(t.Context(), nil)
_, err := e.WebsocketFuturesOrderList(t.Context(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
list := &WebsocketFutureOrdersList{}
_, err = g.WebsocketFuturesOrderList(t.Context(), list)
_, err = e.WebsocketFuturesOrderList(t.Context(), list)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
list.Contract = BTCUSDT
_, err = g.WebsocketFuturesOrderList(t.Context(), list)
_, err = e.WebsocketFuturesOrderList(t.Context(), list)
require.ErrorIs(t, err, asset.ErrNotSupported)
list.Asset = asset.USDTMarginedFutures
_, err = g.WebsocketFuturesOrderList(t.Context(), list)
_, err = e.WebsocketFuturesOrderList(t.Context(), list)
require.ErrorIs(t, err, errStatusNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Futures)
list.Status = statusOpen
got, err := g.WebsocketFuturesOrderList(t.Context(), list)
@@ -187,18 +187,18 @@ func TestWebsocketFuturesOrderList(t *testing.T) {
func TestWebsocketFuturesGetOrderStatus(t *testing.T) {
t.Parallel()
_, err := g.WebsocketFuturesGetOrderStatus(t.Context(), currency.EMPTYPAIR, asset.Empty, "")
_, err := e.WebsocketFuturesGetOrderStatus(t.Context(), currency.EMPTYPAIR, asset.Empty, "")
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
_, err = g.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.Empty, "")
_, err = e.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.Empty, "")
require.ErrorIs(t, err, asset.ErrNotSupported)
_, err = g.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "")
_, err = e.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Futures)
got, err := g.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "513170215869")
require.NoError(t, err)

View File

@@ -20,13 +20,13 @@ var (
)
// authenticateSpot sends an authentication message to the websocket connection
func (g *Gateio) authenticateSpot(ctx context.Context, conn websocket.Connection) error {
return g.websocketLogin(ctx, conn, "spot.login")
func (e *Exchange) authenticateSpot(ctx context.Context, conn websocket.Connection) error {
return e.websocketLogin(ctx, conn, "spot.login")
}
// WebsocketSpotSubmitOrder submits an order via the websocket connection
func (g *Gateio) WebsocketSpotSubmitOrder(ctx context.Context, order *CreateOrderRequest) (*WebsocketOrderResponse, error) {
resps, err := g.WebsocketSpotSubmitOrders(ctx, order)
func (e *Exchange) WebsocketSpotSubmitOrder(ctx context.Context, order *CreateOrderRequest) (*WebsocketOrderResponse, error) {
resps, err := e.WebsocketSpotSubmitOrders(ctx, order)
if err != nil {
return nil, err
}
@@ -38,7 +38,7 @@ func (g *Gateio) WebsocketSpotSubmitOrder(ctx context.Context, order *CreateOrde
// WebsocketSpotSubmitOrders submits orders via the websocket connection. You can
// send multiple orders in a single request. But only for one asset route.
func (g *Gateio) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*CreateOrderRequest) ([]WebsocketOrderResponse, error) {
func (e *Exchange) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*CreateOrderRequest) ([]WebsocketOrderResponse, error) {
if len(orders) == 0 {
return nil, errOrdersEmpty
}
@@ -46,7 +46,7 @@ func (g *Gateio) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*Creat
for i := range orders {
if orders[i].Text == "" {
// API requires Text field, or it will be rejected
orders[i].Text = "t-" + strconv.FormatInt(g.Counter.IncrementAndGet(), 10)
orders[i].Text = "t-" + strconv.FormatInt(e.Counter.IncrementAndGet(), 10)
}
if orders[i].CurrencyPair.IsEmpty() {
return nil, currency.ErrCurrencyPairEmpty
@@ -64,14 +64,14 @@ func (g *Gateio) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*Creat
if len(orders) == 1 {
var singleResponse WebsocketOrderResponse
return []WebsocketOrderResponse{singleResponse}, g.SendWebsocketRequest(ctx, spotPlaceOrderEPL, "spot.order_place", asset.Spot, orders[0], &singleResponse, 2)
return []WebsocketOrderResponse{singleResponse}, e.SendWebsocketRequest(ctx, spotPlaceOrderEPL, "spot.order_place", asset.Spot, orders[0], &singleResponse, 2)
}
var resp []WebsocketOrderResponse
return resp, g.SendWebsocketRequest(ctx, spotBatchOrdersEPL, "spot.order_place", asset.Spot, orders, &resp, 2)
return resp, e.SendWebsocketRequest(ctx, spotBatchOrdersEPL, "spot.order_place", asset.Spot, orders, &resp, 2)
}
// WebsocketSpotCancelOrder cancels an order via the websocket connection
func (g *Gateio) WebsocketSpotCancelOrder(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) {
func (e *Exchange) WebsocketSpotCancelOrder(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) {
if orderID == "" {
return nil, order.ErrOrderIDNotSet
}
@@ -82,11 +82,11 @@ func (g *Gateio) WebsocketSpotCancelOrder(ctx context.Context, orderID string, p
params := &WebsocketOrderRequest{OrderID: orderID, Pair: pair.String(), Account: account}
var resp WebsocketOrderResponse
return &resp, g.SendWebsocketRequest(ctx, spotCancelSingleOrderEPL, "spot.order_cancel", asset.Spot, params, &resp, 1)
return &resp, e.SendWebsocketRequest(ctx, spotCancelSingleOrderEPL, "spot.order_cancel", asset.Spot, params, &resp, 1)
}
// WebsocketSpotCancelAllOrdersByIDs cancels multiple orders via the websocket
func (g *Gateio) WebsocketSpotCancelAllOrdersByIDs(ctx context.Context, o []WebsocketOrderBatchRequest) ([]WebsocketCancellAllResponse, error) {
func (e *Exchange) WebsocketSpotCancelAllOrdersByIDs(ctx context.Context, o []WebsocketOrderBatchRequest) ([]WebsocketCancellAllResponse, error) {
if len(o) == 0 {
return nil, errNoOrdersToCancel
}
@@ -101,11 +101,11 @@ func (g *Gateio) WebsocketSpotCancelAllOrdersByIDs(ctx context.Context, o []Webs
}
var resp []WebsocketCancellAllResponse
return resp, g.SendWebsocketRequest(ctx, spotCancelBatchOrdersEPL, "spot.order_cancel_ids", asset.Spot, o, &resp, 2)
return resp, e.SendWebsocketRequest(ctx, spotCancelBatchOrdersEPL, "spot.order_cancel_ids", asset.Spot, o, &resp, 2)
}
// WebsocketSpotCancelAllOrdersByPair cancels all orders for a specific pair
func (g *Gateio) WebsocketSpotCancelAllOrdersByPair(ctx context.Context, pair currency.Pair, side order.Side, account string) ([]WebsocketOrderResponse, error) {
func (e *Exchange) WebsocketSpotCancelAllOrdersByPair(ctx context.Context, pair currency.Pair, side order.Side, account string) ([]WebsocketOrderResponse, error) {
if !pair.IsEmpty() && side == order.UnknownSide {
// This case will cancel all orders for every pair, this can be introduced later
return nil, fmt.Errorf("'%v' %w while pair is set", side, order.ErrSideIsInvalid)
@@ -123,11 +123,11 @@ func (g *Gateio) WebsocketSpotCancelAllOrdersByPair(ctx context.Context, pair cu
}
var resp []WebsocketOrderResponse
return resp, g.SendWebsocketRequest(ctx, spotCancelAllOpenOrdersEPL, "spot.order_cancel_cp", asset.Spot, params, &resp, 1)
return resp, e.SendWebsocketRequest(ctx, spotCancelAllOpenOrdersEPL, "spot.order_cancel_cp", asset.Spot, params, &resp, 1)
}
// WebsocketSpotAmendOrder amends an order via the websocket connection
func (g *Gateio) WebsocketSpotAmendOrder(ctx context.Context, amend *WebsocketAmendOrder) (*WebsocketOrderResponse, error) {
func (e *Exchange) WebsocketSpotAmendOrder(ctx context.Context, amend *WebsocketAmendOrder) (*WebsocketOrderResponse, error) {
if amend == nil {
return nil, fmt.Errorf("%w: %T", common.ErrNilPointer, amend)
}
@@ -145,11 +145,11 @@ func (g *Gateio) WebsocketSpotAmendOrder(ctx context.Context, amend *WebsocketAm
}
var resp WebsocketOrderResponse
return &resp, g.SendWebsocketRequest(ctx, spotAmendOrderEPL, "spot.order_amend", asset.Spot, amend, &resp, 1)
return &resp, e.SendWebsocketRequest(ctx, spotAmendOrderEPL, "spot.order_amend", asset.Spot, amend, &resp, 1)
}
// WebsocketSpotGetOrderStatus gets the status of an order via the websocket connection
func (g *Gateio) WebsocketSpotGetOrderStatus(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) {
func (e *Exchange) WebsocketSpotGetOrderStatus(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) {
if orderID == "" {
return nil, order.ErrOrderIDNotSet
}
@@ -160,5 +160,5 @@ func (g *Gateio) WebsocketSpotGetOrderStatus(ctx context.Context, orderID string
params := &WebsocketOrderRequest{OrderID: orderID, Pair: pair.String(), Account: account}
var resp WebsocketOrderResponse
return &resp, g.SendWebsocketRequest(ctx, spotGetOrdersEPL, "spot.order_status", asset.Spot, params, &resp, 1)
return &resp, e.SendWebsocketRequest(ctx, spotGetOrdersEPL, "spot.order_status", asset.Spot, params, &resp, 1)
}

View File

@@ -15,12 +15,12 @@ import (
func TestWebsocketLogin(t *testing.T) {
t.Parallel()
err := g.websocketLogin(t.Context(), nil, "")
err := e.websocketLogin(t.Context(), nil, "")
require.ErrorIs(t, err, common.ErrNilPointer)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Spot)
c, err := g.Websocket.GetConnection(asset.Spot)
require.NoError(t, err)
@@ -34,23 +34,23 @@ func TestWebsocketLogin(t *testing.T) {
func TestWebsocketSpotSubmitOrder(t *testing.T) {
t.Parallel()
_, err := g.WebsocketSpotSubmitOrder(t.Context(), &CreateOrderRequest{})
_, err := e.WebsocketSpotSubmitOrder(t.Context(), &CreateOrderRequest{})
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
out := &CreateOrderRequest{CurrencyPair: currency.NewPair(currency.NewCode("GT"), currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"})}
_, err = g.WebsocketSpotSubmitOrder(t.Context(), out)
_, err = e.WebsocketSpotSubmitOrder(t.Context(), out)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
out.Side = strings.ToLower(order.Sell.String())
_, err = g.WebsocketSpotSubmitOrder(t.Context(), out)
_, err = e.WebsocketSpotSubmitOrder(t.Context(), out)
require.ErrorIs(t, err, errInvalidAmount)
out.Amount = 1
out.Type = "limit"
_, err = g.WebsocketSpotSubmitOrder(t.Context(), out)
_, err = e.WebsocketSpotSubmitOrder(t.Context(), out)
require.ErrorIs(t, err, errInvalidPrice)
out.Price = 100
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Spot)
got, err := g.WebsocketSpotSubmitOrder(t.Context(), out)
require.NoError(t, err)
@@ -59,26 +59,26 @@ func TestWebsocketSpotSubmitOrder(t *testing.T) {
func TestWebsocketSpotSubmitOrders(t *testing.T) {
t.Parallel()
_, err := g.WebsocketSpotSubmitOrders(t.Context())
_, err := e.WebsocketSpotSubmitOrders(t.Context())
require.ErrorIs(t, err, errOrdersEmpty)
out := &CreateOrderRequest{}
_, err = g.WebsocketSpotSubmitOrders(t.Context(), out)
_, err = e.WebsocketSpotSubmitOrders(t.Context(), out)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
out.CurrencyPair = currency.NewBTCUSDT()
_, err = g.WebsocketSpotSubmitOrders(t.Context(), out)
_, err = e.WebsocketSpotSubmitOrders(t.Context(), out)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
out.Side = strings.ToLower(order.Buy.String())
_, err = g.WebsocketSpotSubmitOrders(t.Context(), out)
_, err = e.WebsocketSpotSubmitOrders(t.Context(), out)
require.ErrorIs(t, err, errInvalidAmount)
out.Amount = 0.0003
out.Type = "limit"
_, err = g.WebsocketSpotSubmitOrders(t.Context(), out)
_, err = e.WebsocketSpotSubmitOrders(t.Context(), out)
require.ErrorIs(t, err, errInvalidPrice)
out.Price = 20000
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Spot)
// test single order
got, err := g.WebsocketSpotSubmitOrders(t.Context(), out)
@@ -93,14 +93,14 @@ func TestWebsocketSpotSubmitOrders(t *testing.T) {
func TestWebsocketSpotCancelOrder(t *testing.T) {
t.Parallel()
_, err := g.WebsocketSpotCancelOrder(t.Context(), "", currency.EMPTYPAIR, "")
_, err := e.WebsocketSpotCancelOrder(t.Context(), "", currency.EMPTYPAIR, "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = g.WebsocketSpotCancelOrder(t.Context(), "1337", currency.EMPTYPAIR, "")
_, err = e.WebsocketSpotCancelOrder(t.Context(), "1337", currency.EMPTYPAIR, "")
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Spot)
got, err := g.WebsocketSpotCancelOrder(t.Context(), "644913098758", BTCUSDT, "")
require.NoError(t, err)
@@ -109,20 +109,20 @@ func TestWebsocketSpotCancelOrder(t *testing.T) {
func TestWebsocketSpotCancelAllOrdersByIDs(t *testing.T) {
t.Parallel()
_, err := g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{})
_, err := e.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{})
require.ErrorIs(t, err, errNoOrdersToCancel)
out := WebsocketOrderBatchRequest{}
_, err = g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out})
_, err = e.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
out.OrderID = "1337"
_, err = g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out})
_, err = e.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out})
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
out.Pair = BTCUSDT
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Spot)
out.OrderID = "644913101755"
got, err := g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out})
@@ -132,12 +132,12 @@ func TestWebsocketSpotCancelAllOrdersByIDs(t *testing.T) {
func TestWebsocketSpotCancelAllOrdersByPair(t *testing.T) {
t.Parallel()
_, err := g.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.NewPairWithDelimiter("LTC", "USDT", "_"), 0, "")
_, err := e.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.NewPairWithDelimiter("LTC", "USDT", "_"), 0, "")
require.ErrorIs(t, err, order.ErrSideIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Spot)
got, err := g.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.EMPTYPAIR, order.Buy, "")
require.NoError(t, err)
@@ -146,27 +146,27 @@ func TestWebsocketSpotCancelAllOrdersByPair(t *testing.T) {
func TestWebsocketSpotAmendOrder(t *testing.T) {
t.Parallel()
_, err := g.WebsocketSpotAmendOrder(t.Context(), nil)
_, err := e.WebsocketSpotAmendOrder(t.Context(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
amend := &WebsocketAmendOrder{}
_, err = g.WebsocketSpotAmendOrder(t.Context(), amend)
_, err = e.WebsocketSpotAmendOrder(t.Context(), amend)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
amend.OrderID = "1337"
_, err = g.WebsocketSpotAmendOrder(t.Context(), amend)
_, err = e.WebsocketSpotAmendOrder(t.Context(), amend)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
amend.Pair = BTCUSDT
_, err = g.WebsocketSpotAmendOrder(t.Context(), amend)
_, err = e.WebsocketSpotAmendOrder(t.Context(), amend)
require.ErrorIs(t, err, errInvalidAmount)
amend.Amount = "0.0004"
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
g := newExchangeWithWebsocket(t, asset.Spot)
amend.OrderID = "645029162673"
got, err := g.WebsocketSpotAmendOrder(t.Context(), amend)
@@ -176,16 +176,16 @@ func TestWebsocketSpotAmendOrder(t *testing.T) {
func TestWebsocketSpotGetOrderStatus(t *testing.T) {
t.Parallel()
_, err := g.WebsocketSpotGetOrderStatus(t.Context(), "", currency.EMPTYPAIR, "")
_, err := e.WebsocketSpotGetOrderStatus(t.Context(), "", currency.EMPTYPAIR, "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = g.WebsocketSpotGetOrderStatus(t.Context(), "1337", currency.EMPTYPAIR, "")
_, err = e.WebsocketSpotGetOrderStatus(t.Context(), "1337", currency.EMPTYPAIR, "")
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
testexch.UpdatePairsOnce(t, g)
g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
testexch.UpdatePairsOnce(t, e)
g := newExchangeWithWebsocket(t, asset.Spot)
got, err := g.WebsocketSpotGetOrderStatus(t.Context(), "644999650452", BTCUSDT, "")
require.NoError(t, err)
@@ -194,28 +194,28 @@ func TestWebsocketSpotGetOrderStatus(t *testing.T) {
// getWebsocketInstance returns a websocket instance copy for testing.
// This restricts the pairs to a single pair per asset type to reduce test time.
func newExchangeWithWebsocket(t *testing.T, a asset.Item) *Gateio {
func newExchangeWithWebsocket(t *testing.T, a asset.Item) *Exchange {
t.Helper()
if apiKey == "" || apiSecret == "" {
t.Skip()
}
g := new(Gateio) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
require.NoError(t, testexch.Setup(g), "Test instance Setup must not error")
testexch.UpdatePairsOnce(t, g)
g.API.AuthenticatedSupport = true
g.API.AuthenticatedWebsocketSupport = true
g.SetCredentials(apiKey, apiSecret, "", "", "", "")
g.Websocket.SetCanUseAuthenticatedEndpoints(true)
e := new(Exchange) //nolint:govet // Intentional shadow
require.NoError(t, testexch.Setup(e), "Test instance Setup must not error")
testexch.UpdatePairsOnce(t, e)
e.API.AuthenticatedSupport = true
e.API.AuthenticatedWebsocketSupport = true
e.SetCredentials(apiKey, apiSecret, "", "", "", "")
e.Websocket.SetCanUseAuthenticatedEndpoints(true)
switch a {
case asset.Spot:
avail, err := g.GetAvailablePairs(a)
avail, err := e.GetAvailablePairs(a)
require.NoError(t, err)
if len(avail) > 1 { // reduce pairs to 1 to speed up tests
avail = avail[:1]
}
require.NoError(t, g.SetPairs(avail, a, true))
require.NoError(t, e.SetPairs(avail, a, true))
case asset.Futures:
avail, err := g.GetAvailablePairs(a)
avail, err := e.GetAvailablePairs(a)
require.NoError(t, err)
usdtPairs, err := avail.GetPairsByQuote(currency.USDT) // Get USDT margin pairs
require.NoError(t, err)
@@ -226,11 +226,11 @@ func newExchangeWithWebsocket(t *testing.T, a asset.Item) *Gateio {
avail[0] = usdtPairs[0]
avail[1] = btcPairs[0]
avail = avail[:2]
require.NoError(t, g.SetPairs(avail, a, true))
require.NoError(t, e.SetPairs(avail, a, true))
default:
require.NoError(t, g.CurrencyPairs.SetAssetEnabled(a, false))
require.NoError(t, e.CurrencyPairs.SetAssetEnabled(a, false))
}
require.NoError(t, g.Websocket.Connect())
return g
require.NoError(t, e.Websocket.Connect())
return e
}

File diff suppressed because it is too large Load Diff

View File

@@ -40,7 +40,7 @@ func newWsOBUpdateManager(snapshotSyncDelay time.Duration) *wsOBUpdateManager {
}
// ProcessOrderbookUpdate processes an orderbook update by syncing snapshot, caching updates and applying them
func (m *wsOBUpdateManager) ProcessOrderbookUpdate(ctx context.Context, g *Gateio, firstUpdateID int64, update *orderbook.Update) error {
func (m *wsOBUpdateManager) ProcessOrderbookUpdate(ctx context.Context, g *Exchange, firstUpdateID int64, update *orderbook.Update) error {
cache := m.LoadCache(update.Pair, update.Asset)
cache.mtx.Lock()
defer cache.mtx.Unlock()
@@ -97,7 +97,7 @@ func (m *wsOBUpdateManager) LoadCache(p currency.Pair, a asset.Item) *updateCach
// SyncOrderbook fetches and synchronises an orderbook snapshot to the limit size so that pending updates can be
// applied to the orderbook.
func (c *updateCache) SyncOrderbook(ctx context.Context, g *Gateio, pair currency.Pair, a asset.Item) error {
func (c *updateCache) SyncOrderbook(ctx context.Context, g *Exchange, pair currency.Pair, a asset.Item) error {
// TODO: When subscription config is added for all assets update limits to use sub.Levels
var limit uint64
switch a {
@@ -150,7 +150,7 @@ func (c *updateCache) SyncOrderbook(ctx context.Context, g *Gateio, pair currenc
}
// ApplyPendingUpdates applies all pending updates to the orderbook
func (c *updateCache) applyPendingUpdates(g *Gateio, a asset.Item) error {
func (c *updateCache) applyPendingUpdates(g *Exchange, a asset.Item) error {
for _, data := range c.updates {
lastUpdateID, err := g.Websocket.Orderbook.LastUpdateID(data.update.Pair, a)
if err != nil {
@@ -171,7 +171,7 @@ func (c *updateCache) applyPendingUpdates(g *Gateio, a asset.Item) error {
}
// applyOrderbookUpdate applies an orderbook update to the orderbook
func applyOrderbookUpdate(g *Gateio, update *orderbook.Update) error {
func applyOrderbookUpdate(g *Exchange, update *orderbook.Update) error {
if update.Asset != asset.Spot {
return g.Websocket.Orderbook.Update(update)
}

View File

@@ -18,12 +18,12 @@ func TestProcessOrderbookUpdate(t *testing.T) {
t.Parallel()
m := newWsOBUpdateManager(0)
err := m.ProcessOrderbookUpdate(t.Context(), g, 1337, &orderbook.Update{})
err := m.ProcessOrderbookUpdate(t.Context(), e, 1337, &orderbook.Update{})
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
pair := currency.NewPair(currency.BABY, currency.BABYDOGE)
err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Exchange: g.Name,
err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Exchange: e.Name,
Pair: pair,
Asset: asset.USDTMarginedFutures,
Bids: []orderbook.Level{{Price: 1, Amount: 1}},
@@ -34,7 +34,7 @@ func TestProcessOrderbookUpdate(t *testing.T) {
})
require.NoError(t, err)
err = m.ProcessOrderbookUpdate(t.Context(), g, 1337, &orderbook.Update{
err = m.ProcessOrderbookUpdate(t.Context(), e, 1337, &orderbook.Update{
UpdateID: 1338,
Pair: pair,
Asset: asset.USDTMarginedFutures,
@@ -44,7 +44,7 @@ func TestProcessOrderbookUpdate(t *testing.T) {
require.NoError(t, err)
// Test orderbook snapshot is behind update
err = m.ProcessOrderbookUpdate(t.Context(), g, 1340, &orderbook.Update{
err = m.ProcessOrderbookUpdate(t.Context(), e, 1340, &orderbook.Update{
UpdateID: 1341,
Pair: pair,
Asset: asset.USDTMarginedFutures,
@@ -61,7 +61,7 @@ func TestProcessOrderbookUpdate(t *testing.T) {
cache.mtx.Unlock()
// Test orderbook snapshot is behind update
err = m.ProcessOrderbookUpdate(t.Context(), g, 1342, &orderbook.Update{
err = m.ProcessOrderbookUpdate(t.Context(), e, 1342, &orderbook.Update{
UpdateID: 1343,
Pair: pair,
Asset: asset.USDTMarginedFutures,
@@ -100,25 +100,25 @@ func TestLoadCache(t *testing.T) {
func TestSyncOrderbook(t *testing.T) {
t.Parallel()
g := new(Gateio)
require.NoError(t, testexch.Setup(g), "Setup must not error")
require.NoError(t, g.UpdateTradablePairs(t.Context(), false))
e := new(Exchange)
require.NoError(t, testexch.Setup(e), "Setup must not error")
require.NoError(t, e.UpdateTradablePairs(t.Context(), false))
// Add dummy subscription so that it can be matched and a limit/level can be extracted for initial orderbook sync spot.
err := g.Websocket.AddSubscriptions(nil, &subscription.Subscription{Channel: subscription.OrderbookChannel, Interval: kline.HundredMilliseconds})
err := e.Websocket.AddSubscriptions(nil, &subscription.Subscription{Channel: subscription.OrderbookChannel, Interval: kline.HundredMilliseconds})
require.NoError(t, err)
m := newWsOBUpdateManager(defaultWSSnapshotSyncDelay)
for _, a := range []asset.Item{asset.Spot, asset.USDTMarginedFutures} {
pair := currency.NewPair(currency.ETH, currency.USDT)
err := g.CurrencyPairs.EnablePair(a, pair)
err := e.CurrencyPairs.EnablePair(a, pair)
require.NoError(t, err)
cache := m.LoadCache(pair, a)
cache.updates = []pendingUpdate{{update: &orderbook.Update{Pair: pair, Asset: a}}}
cache.updating = true
err = cache.SyncOrderbook(t.Context(), g, pair, a)
err = cache.SyncOrderbook(t.Context(), e, pair, a)
require.NoError(t, err)
require.False(t, cache.updating)
require.Empty(t, cache.updates)
@@ -128,7 +128,7 @@ func TestSyncOrderbook(t *testing.T) {
expectedLimit = 100
}
b, err := g.Websocket.Orderbook.GetOrderbook(pair, a)
b, err := e.Websocket.Orderbook.GetOrderbook(pair, a)
require.NoError(t, err)
require.Len(t, b.Bids, expectedLimit)
require.Len(t, b.Asks, expectedLimit)
@@ -138,14 +138,14 @@ func TestSyncOrderbook(t *testing.T) {
func TestApplyPendingUpdates(t *testing.T) {
t.Parallel()
g := new(Gateio)
require.NoError(t, testexch.Setup(g), "Setup must not error")
require.NoError(t, g.UpdateTradablePairs(t.Context(), false))
e := new(Exchange)
require.NoError(t, testexch.Setup(e), "Setup must not error")
require.NoError(t, e.UpdateTradablePairs(t.Context(), false))
m := newWsOBUpdateManager(defaultWSSnapshotSyncDelay)
pair := currency.NewPair(currency.LTC, currency.USDT)
err := g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Exchange: g.Name,
err := e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
Exchange: e.Name,
Pair: pair,
Asset: asset.USDTMarginedFutures,
Bids: []orderbook.Level{{Price: 1, Amount: 1}},
@@ -167,20 +167,20 @@ func TestApplyPendingUpdates(t *testing.T) {
}
cache.updates = []pendingUpdate{{update: update, firstUpdateID: 1337}}
err = cache.applyPendingUpdates(g, asset.USDTMarginedFutures)
err = cache.applyPendingUpdates(e, asset.USDTMarginedFutures)
require.ErrorIs(t, err, errOrderbookSnapshotOutdated)
cache.updates[0].firstUpdateID = 1336
err = cache.applyPendingUpdates(g, asset.USDTMarginedFutures)
err = cache.applyPendingUpdates(e, asset.USDTMarginedFutures)
require.NoError(t, err)
}
func TestApplyOrderbookUpdate(t *testing.T) {
t.Parallel()
g := new(Gateio)
require.NoError(t, testexch.Setup(g), "Setup must not error")
require.NoError(t, g.UpdateTradablePairs(t.Context(), false))
e := new(Exchange)
require.NoError(t, testexch.Setup(e), "Setup must not error")
require.NoError(t, e.UpdateTradablePairs(t.Context(), false))
pair := currency.NewBTCUSDT()
@@ -191,14 +191,14 @@ func TestApplyOrderbookUpdate(t *testing.T) {
UpdateTime: time.Now(),
}
err := applyOrderbookUpdate(g, update)
err := applyOrderbookUpdate(e, update)
require.ErrorIs(t, err, orderbook.ErrDepthNotFound)
update.Asset = asset.Spot
err = applyOrderbookUpdate(g, update)
err = applyOrderbookUpdate(e, update)
require.ErrorIs(t, err, orderbook.ErrDepthNotFound)
update.Pair = currency.NewPair(currency.BABY, currency.BABYDOGE)
err = applyOrderbookUpdate(g, update)
err = applyOrderbookUpdate(e, update)
require.NoError(t, err)
}