mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-08 23:16:54 +00:00
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:
File diff suppressed because it is too large
Load Diff
@@ -13,33 +13,33 @@ import (
|
||||
)
|
||||
|
||||
// WsInverseConnect connects to inverse websocket feed
|
||||
func (by *Bybit) WsInverseConnect() error {
|
||||
func (e *Exchange) WsInverseConnect() error {
|
||||
ctx := context.TODO()
|
||||
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.CoinMarginedFutures) {
|
||||
if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.CoinMarginedFutures) {
|
||||
return websocket.ErrWebsocketNotEnabled
|
||||
}
|
||||
by.Websocket.Conn.SetURL(inversePublic)
|
||||
e.Websocket.Conn.SetURL(inversePublic)
|
||||
var dialer gws.Dialer
|
||||
err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
MessageType: gws.TextMessage,
|
||||
Message: []byte(`{"op": "ping"}`),
|
||||
Delay: bybitWebsocketTimer,
|
||||
})
|
||||
|
||||
by.Websocket.Wg.Add(1)
|
||||
go by.wsReadData(ctx, asset.CoinMarginedFutures, by.Websocket.Conn)
|
||||
e.Websocket.Wg.Add(1)
|
||||
go e.wsReadData(ctx, asset.CoinMarginedFutures, e.Websocket.Conn)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateInverseDefaultSubscriptions generates default subscription
|
||||
func (by *Bybit) GenerateInverseDefaultSubscriptions() (subscription.List, error) {
|
||||
func (e *Exchange) GenerateInverseDefaultSubscriptions() (subscription.List, error) {
|
||||
var subscriptions subscription.List
|
||||
channels := []string{chanOrderbook, chanPublicTrade, chanPublicTicker}
|
||||
pairs, err := by.GetEnabledPairs(asset.CoinMarginedFutures)
|
||||
pairs, err := e.GetEnabledPairs(asset.CoinMarginedFutures)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -57,26 +57,26 @@ func (by *Bybit) GenerateInverseDefaultSubscriptions() (subscription.List, error
|
||||
}
|
||||
|
||||
// InverseSubscribe sends a subscription message to linear public channels.
|
||||
func (by *Bybit) InverseSubscribe(channelSubscriptions subscription.List) error {
|
||||
func (e *Exchange) InverseSubscribe(channelSubscriptions subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleInversePayloadSubscription(ctx, "subscribe", channelSubscriptions)
|
||||
return e.handleInversePayloadSubscription(ctx, "subscribe", channelSubscriptions)
|
||||
}
|
||||
|
||||
// InverseUnsubscribe sends an unsubscription messages through linear public channels.
|
||||
func (by *Bybit) InverseUnsubscribe(channelSubscriptions subscription.List) error {
|
||||
func (e *Exchange) InverseUnsubscribe(channelSubscriptions subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleInversePayloadSubscription(ctx, "unsubscribe", channelSubscriptions)
|
||||
return e.handleInversePayloadSubscription(ctx, "unsubscribe", channelSubscriptions)
|
||||
}
|
||||
|
||||
func (by *Bybit) handleInversePayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error {
|
||||
payloads, err := by.handleSubscriptions(operation, channelSubscriptions)
|
||||
func (e *Exchange) handleInversePayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error {
|
||||
payloads, err := e.handleSubscriptions(operation, channelSubscriptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for a := range payloads {
|
||||
// The options connection does not send the subscription request id back with the subscription notification payload
|
||||
// therefore the code doesn't wait for the response to check whether the subscription is successful or not.
|
||||
err = by.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a])
|
||||
err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -13,47 +13,47 @@ import (
|
||||
)
|
||||
|
||||
// WsLinearConnect connects to linear a websocket feed
|
||||
func (by *Bybit) WsLinearConnect() error {
|
||||
func (e *Exchange) WsLinearConnect() error {
|
||||
ctx := context.TODO()
|
||||
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.LinearContract) {
|
||||
if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.LinearContract) {
|
||||
return websocket.ErrWebsocketNotEnabled
|
||||
}
|
||||
by.Websocket.Conn.SetURL(linearPublic)
|
||||
e.Websocket.Conn.SetURL(linearPublic)
|
||||
var dialer gws.Dialer
|
||||
err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
MessageType: gws.TextMessage,
|
||||
Message: []byte(`{"op": "ping"}`),
|
||||
Delay: bybitWebsocketTimer,
|
||||
})
|
||||
|
||||
by.Websocket.Wg.Add(1)
|
||||
go by.wsReadData(ctx, asset.LinearContract, by.Websocket.Conn)
|
||||
if by.IsWebsocketAuthenticationSupported() {
|
||||
err = by.WsAuth(ctx)
|
||||
e.Websocket.Wg.Add(1)
|
||||
go e.wsReadData(ctx, asset.LinearContract, e.Websocket.Conn)
|
||||
if e.IsWebsocketAuthenticationSupported() {
|
||||
err = e.WsAuth(ctx)
|
||||
if err != nil {
|
||||
by.Websocket.DataHandler <- err
|
||||
by.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
e.Websocket.DataHandler <- err
|
||||
e.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateLinearDefaultSubscriptions generates default subscription
|
||||
func (by *Bybit) GenerateLinearDefaultSubscriptions() (subscription.List, error) {
|
||||
func (e *Exchange) GenerateLinearDefaultSubscriptions() (subscription.List, error) {
|
||||
var subscriptions subscription.List
|
||||
channels := []string{chanOrderbook, chanPublicTrade, chanPublicTicker}
|
||||
pairs, err := by.GetEnabledPairs(asset.USDTMarginedFutures)
|
||||
pairs, err := e.GetEnabledPairs(asset.USDTMarginedFutures)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
linearPairMap := map[asset.Item]currency.Pairs{
|
||||
asset.USDTMarginedFutures: pairs,
|
||||
}
|
||||
usdcPairs, err := by.GetEnabledPairs(asset.USDCMarginedFutures)
|
||||
usdcPairs, err := e.GetEnabledPairs(asset.USDCMarginedFutures)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -75,26 +75,26 @@ func (by *Bybit) GenerateLinearDefaultSubscriptions() (subscription.List, error)
|
||||
}
|
||||
|
||||
// LinearSubscribe sends a subscription message to linear public channels.
|
||||
func (by *Bybit) LinearSubscribe(channelSubscriptions subscription.List) error {
|
||||
func (e *Exchange) LinearSubscribe(channelSubscriptions subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleLinearPayloadSubscription(ctx, "subscribe", channelSubscriptions)
|
||||
return e.handleLinearPayloadSubscription(ctx, "subscribe", channelSubscriptions)
|
||||
}
|
||||
|
||||
// LinearUnsubscribe sends an unsubscription messages through linear public channels.
|
||||
func (by *Bybit) LinearUnsubscribe(channelSubscriptions subscription.List) error {
|
||||
func (e *Exchange) LinearUnsubscribe(channelSubscriptions subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleLinearPayloadSubscription(ctx, "unsubscribe", channelSubscriptions)
|
||||
return e.handleLinearPayloadSubscription(ctx, "unsubscribe", channelSubscriptions)
|
||||
}
|
||||
|
||||
func (by *Bybit) handleLinearPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error {
|
||||
payloads, err := by.handleSubscriptions(operation, channelSubscriptions)
|
||||
func (e *Exchange) handleLinearPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error {
|
||||
payloads, err := e.handleSubscriptions(operation, channelSubscriptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for a := range payloads {
|
||||
// The options connection does not send the subscription request id back with the subscription notification payload
|
||||
// therefore the code doesn't wait for the response to check whether the subscription is successful or not.
|
||||
err = by.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a])
|
||||
err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -18,21 +18,21 @@ import (
|
||||
var mockTests = false
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
b = new(Bybit)
|
||||
if err := testexch.Setup(b); err != nil {
|
||||
e = new(Exchange)
|
||||
if err := testexch.Setup(e); err != nil {
|
||||
log.Fatalf("Bybit Setup error: %s", err)
|
||||
}
|
||||
|
||||
if apiKey != "" && apiSecret != "" {
|
||||
b.API.AuthenticatedSupport = true
|
||||
b.API.AuthenticatedWebsocketSupport = true
|
||||
b.SetCredentials(apiKey, apiSecret, "", "", "", "")
|
||||
b.Websocket.SetCanUseAuthenticatedEndpoints(true)
|
||||
e.API.AuthenticatedSupport = true
|
||||
e.API.AuthenticatedWebsocketSupport = true
|
||||
e.SetCredentials(apiKey, apiSecret, "", "", "", "")
|
||||
e.Websocket.SetCanUseAuthenticatedEndpoints(true)
|
||||
}
|
||||
|
||||
if b.API.AuthenticatedSupport {
|
||||
if _, err := b.FetchAccountType(context.Background()); err != nil {
|
||||
log.Printf("%s unable to FetchAccountType: %v", b.Name, err)
|
||||
if e.API.AuthenticatedSupport {
|
||||
if _, err := e.FetchAccountType(context.Background()); err != nil {
|
||||
log.Printf("%s unable to FetchAccountType: %v", e.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,14 +48,14 @@ func instantiateTradablePairs() {
|
||||
}
|
||||
}
|
||||
|
||||
err := b.UpdateTradablePairs(context.Background(), true)
|
||||
err := e.UpdateTradablePairs(context.Background(), true)
|
||||
handleError("unable to UpdateTradablePairs", err)
|
||||
|
||||
setTradablePair := func(assetType asset.Item, p *currency.Pair) {
|
||||
tradables, err := b.GetEnabledPairs(assetType)
|
||||
tradables, err := e.GetEnabledPairs(assetType)
|
||||
handleError("unable to GetEnabledPairs", err)
|
||||
|
||||
format, err := b.GetPairFormat(assetType, true)
|
||||
format, err := e.GetPairFormat(assetType, true)
|
||||
handleError("unable to GetPairFormat", err)
|
||||
|
||||
*p = tradables[0].Format(format)
|
||||
|
||||
@@ -18,25 +18,25 @@ import (
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
b = new(Bybit)
|
||||
if err := testexch.Setup(b); err != nil {
|
||||
e = new(Exchange)
|
||||
if err := testexch.Setup(e); err != nil {
|
||||
log.Fatalf("Bybit Setup error: %s", err)
|
||||
}
|
||||
|
||||
b.SetCredentials("mock", "tester", "", "", "", "") // Hack for UpdateAccountInfo test
|
||||
e.SetCredentials("mock", "tester", "", "", "", "") // Hack for UpdateAccountInfo test
|
||||
|
||||
if err := testexch.MockHTTPInstance(b); err != nil {
|
||||
if err := testexch.MockHTTPInstance(e); err != nil {
|
||||
log.Fatalf("Bybit MockHTTPInstance error: %s", err)
|
||||
}
|
||||
|
||||
if err := b.UpdateTradablePairs(context.Background(), true); err != nil {
|
||||
if err := e.UpdateTradablePairs(context.Background(), true); err != nil {
|
||||
log.Fatalf("Bybit unable to UpdateTradablePairs: %s", err)
|
||||
}
|
||||
|
||||
setEnabledPair := func(assetType asset.Item, pair currency.Pair) {
|
||||
okay, err := b.IsPairEnabled(pair, assetType)
|
||||
okay, err := e.IsPairEnabled(pair, assetType)
|
||||
if !okay || err != nil {
|
||||
err = b.CurrencyPairs.EnablePair(assetType, pair)
|
||||
err = e.CurrencyPairs.EnablePair(assetType, pair)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -15,38 +15,38 @@ import (
|
||||
)
|
||||
|
||||
// WsOptionsConnect connects to options a websocket feed
|
||||
func (by *Bybit) WsOptionsConnect() error {
|
||||
func (e *Exchange) WsOptionsConnect() error {
|
||||
ctx := context.TODO()
|
||||
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.Options) {
|
||||
if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.Options) {
|
||||
return websocket.ErrWebsocketNotEnabled
|
||||
}
|
||||
by.Websocket.Conn.SetURL(optionPublic)
|
||||
e.Websocket.Conn.SetURL(optionPublic)
|
||||
var dialer gws.Dialer
|
||||
err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pingMessage := PingMessage{Operation: "ping", RequestID: strconv.FormatInt(by.Websocket.Conn.GenerateMessageID(false), 10)}
|
||||
pingMessage := PingMessage{Operation: "ping", RequestID: strconv.FormatInt(e.Websocket.Conn.GenerateMessageID(false), 10)}
|
||||
pingData, err := json.Marshal(pingMessage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
MessageType: gws.TextMessage,
|
||||
Message: pingData,
|
||||
Delay: bybitWebsocketTimer,
|
||||
})
|
||||
|
||||
by.Websocket.Wg.Add(1)
|
||||
go by.wsReadData(ctx, asset.Options, by.Websocket.Conn)
|
||||
e.Websocket.Wg.Add(1)
|
||||
go e.wsReadData(ctx, asset.Options, e.Websocket.Conn)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateOptionsDefaultSubscriptions generates default subscription
|
||||
func (by *Bybit) GenerateOptionsDefaultSubscriptions() (subscription.List, error) {
|
||||
func (e *Exchange) GenerateOptionsDefaultSubscriptions() (subscription.List, error) {
|
||||
var subscriptions subscription.List
|
||||
channels := []string{chanOrderbook, chanPublicTrade, chanPublicTicker}
|
||||
pairs, err := by.GetEnabledPairs(asset.Options)
|
||||
pairs, err := e.GetEnabledPairs(asset.Options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -64,26 +64,26 @@ func (by *Bybit) GenerateOptionsDefaultSubscriptions() (subscription.List, error
|
||||
}
|
||||
|
||||
// OptionSubscribe sends a subscription message to options public channels.
|
||||
func (by *Bybit) OptionSubscribe(channelSubscriptions subscription.List) error {
|
||||
func (e *Exchange) OptionSubscribe(channelSubscriptions subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleOptionsPayloadSubscription(ctx, "subscribe", channelSubscriptions)
|
||||
return e.handleOptionsPayloadSubscription(ctx, "subscribe", channelSubscriptions)
|
||||
}
|
||||
|
||||
// OptionUnsubscribe sends an unsubscription messages through options public channels.
|
||||
func (by *Bybit) OptionUnsubscribe(channelSubscriptions subscription.List) error {
|
||||
func (e *Exchange) OptionUnsubscribe(channelSubscriptions subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleOptionsPayloadSubscription(ctx, "unsubscribe", channelSubscriptions)
|
||||
return e.handleOptionsPayloadSubscription(ctx, "unsubscribe", channelSubscriptions)
|
||||
}
|
||||
|
||||
func (by *Bybit) handleOptionsPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error {
|
||||
payloads, err := by.handleSubscriptions(operation, channelSubscriptions)
|
||||
func (e *Exchange) handleOptionsPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error {
|
||||
payloads, err := e.handleSubscriptions(operation, channelSubscriptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for a := range payloads {
|
||||
// The options connection does not send the subscription request id back with the subscription notification payload
|
||||
// therefore the code doesn't wait for the response to check whether the subscription is successful or not.
|
||||
err = by.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a])
|
||||
err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -79,54 +79,54 @@ var subscriptionNames = map[string]string{
|
||||
}
|
||||
|
||||
// WsConnect connects to a websocket feed
|
||||
func (by *Bybit) WsConnect() error {
|
||||
func (e *Exchange) WsConnect() error {
|
||||
ctx := context.TODO()
|
||||
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.Spot) {
|
||||
if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.Spot) {
|
||||
return websocket.ErrWebsocketNotEnabled
|
||||
}
|
||||
var dialer gws.Dialer
|
||||
err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
MessageType: gws.TextMessage,
|
||||
Message: []byte(`{"op": "ping"}`),
|
||||
Delay: bybitWebsocketTimer,
|
||||
})
|
||||
|
||||
by.Websocket.Wg.Add(1)
|
||||
go by.wsReadData(ctx, asset.Spot, by.Websocket.Conn)
|
||||
if by.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
err = by.WsAuth(ctx)
|
||||
e.Websocket.Wg.Add(1)
|
||||
go e.wsReadData(ctx, asset.Spot, e.Websocket.Conn)
|
||||
if e.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
err = e.WsAuth(ctx)
|
||||
if err != nil {
|
||||
by.Websocket.DataHandler <- err
|
||||
by.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
e.Websocket.DataHandler <- err
|
||||
e.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WsAuth sends an authentication message to receive auth data
|
||||
func (by *Bybit) WsAuth(ctx context.Context) error {
|
||||
creds, err := by.GetCredentials(ctx)
|
||||
func (e *Exchange) WsAuth(ctx context.Context) error {
|
||||
creds, err := e.GetCredentials(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var dialer gws.Dialer
|
||||
if err := by.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}); err != nil {
|
||||
if err := e.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
by.Websocket.AuthConn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
e.Websocket.AuthConn.SetupPingHandler(request.Unset, websocket.PingHandler{
|
||||
MessageType: gws.TextMessage,
|
||||
Message: []byte(`{"op":"ping"}`),
|
||||
Delay: bybitWebsocketTimer,
|
||||
})
|
||||
|
||||
by.Websocket.Wg.Add(1)
|
||||
go by.wsReadData(ctx, asset.Spot, by.Websocket.AuthConn)
|
||||
e.Websocket.Wg.Add(1)
|
||||
go e.wsReadData(ctx, asset.Spot, e.Websocket.AuthConn)
|
||||
|
||||
intNonce := time.Now().Add(time.Hour * 6).UnixMilli()
|
||||
strNonce := strconv.FormatInt(intNonce, 10)
|
||||
@@ -140,11 +140,11 @@ func (by *Bybit) WsAuth(ctx context.Context) error {
|
||||
}
|
||||
sign := hex.EncodeToString(hmac)
|
||||
req := Authenticate{
|
||||
RequestID: strconv.FormatInt(by.Websocket.AuthConn.GenerateMessageID(false), 10),
|
||||
RequestID: strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10),
|
||||
Operation: "auth",
|
||||
Args: []any{creds.Key, intNonce, sign},
|
||||
}
|
||||
resp, err := by.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, req.RequestID, req)
|
||||
resp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, req.RequestID, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -160,13 +160,13 @@ func (by *Bybit) WsAuth(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// Subscribe sends a websocket message to receive data from the channel
|
||||
func (by *Bybit) Subscribe(channelsToSubscribe subscription.List) error {
|
||||
func (e *Exchange) Subscribe(channelsToSubscribe subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleSpotSubscription(ctx, "subscribe", channelsToSubscribe)
|
||||
return e.handleSpotSubscription(ctx, "subscribe", channelsToSubscribe)
|
||||
}
|
||||
|
||||
func (by *Bybit) handleSubscriptions(operation string, subs subscription.List) (args []SubscriptionArgument, err error) {
|
||||
subs, err = subs.ExpandTemplates(by)
|
||||
func (e *Exchange) handleSubscriptions(operation string, subs subscription.List) (args []SubscriptionArgument, err error) {
|
||||
subs, err = subs.ExpandTemplates(e)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -176,7 +176,7 @@ func (by *Bybit) handleSubscriptions(operation string, subs subscription.List) (
|
||||
args = append(args, SubscriptionArgument{
|
||||
auth: b[0].Authenticated,
|
||||
Operation: operation,
|
||||
RequestID: strconv.FormatInt(by.Websocket.Conn.GenerateMessageID(false), 10),
|
||||
RequestID: strconv.FormatInt(e.Websocket.Conn.GenerateMessageID(false), 10),
|
||||
Arguments: b.QualifiedChannels(),
|
||||
associatedSubs: b,
|
||||
})
|
||||
@@ -187,25 +187,25 @@ func (by *Bybit) handleSubscriptions(operation string, subs subscription.List) (
|
||||
}
|
||||
|
||||
// Unsubscribe sends a websocket message to stop receiving data from the channel
|
||||
func (by *Bybit) Unsubscribe(channelsToUnsubscribe subscription.List) error {
|
||||
func (e *Exchange) Unsubscribe(channelsToUnsubscribe subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
return by.handleSpotSubscription(ctx, "unsubscribe", channelsToUnsubscribe)
|
||||
return e.handleSpotSubscription(ctx, "unsubscribe", channelsToUnsubscribe)
|
||||
}
|
||||
|
||||
func (by *Bybit) handleSpotSubscription(ctx context.Context, operation string, channelsToSubscribe subscription.List) error {
|
||||
payloads, err := by.handleSubscriptions(operation, channelsToSubscribe)
|
||||
func (e *Exchange) handleSpotSubscription(ctx context.Context, operation string, channelsToSubscribe subscription.List) error {
|
||||
payloads, err := e.handleSubscriptions(operation, channelsToSubscribe)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for a := range payloads {
|
||||
var response []byte
|
||||
if payloads[a].auth {
|
||||
response, err = by.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a])
|
||||
response, err = e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
response, err = by.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a])
|
||||
response, err = e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -221,15 +221,15 @@ func (by *Bybit) handleSpotSubscription(ctx context.Context, operation string, c
|
||||
|
||||
var conn websocket.Connection
|
||||
if payloads[a].auth {
|
||||
conn = by.Websocket.AuthConn
|
||||
conn = e.Websocket.AuthConn
|
||||
} else {
|
||||
conn = by.Websocket.Conn
|
||||
conn = e.Websocket.Conn
|
||||
}
|
||||
|
||||
if operation == "unsubscribe" {
|
||||
err = by.Websocket.RemoveSubscriptions(conn, payloads[a].associatedSubs...)
|
||||
err = e.Websocket.RemoveSubscriptions(conn, payloads[a].associatedSubs...)
|
||||
} else {
|
||||
err = by.Websocket.AddSubscriptions(conn, payloads[a].associatedSubs...)
|
||||
err = e.Websocket.AddSubscriptions(conn, payloads[a].associatedSubs...)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -239,12 +239,12 @@ func (by *Bybit) handleSpotSubscription(ctx context.Context, operation string, c
|
||||
}
|
||||
|
||||
// generateSubscriptions generates default subscription
|
||||
func (by *Bybit) generateSubscriptions() (subscription.List, error) {
|
||||
return by.Features.Subscriptions.ExpandTemplates(by)
|
||||
func (e *Exchange) generateSubscriptions() (subscription.List, error) {
|
||||
return e.Features.Subscriptions.ExpandTemplates(e)
|
||||
}
|
||||
|
||||
// GetSubscriptionTemplate returns a subscription channel template
|
||||
func (by *Bybit) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) {
|
||||
func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) {
|
||||
return template.New("master.tmpl").Funcs(template.FuncMap{
|
||||
"channelName": channelName,
|
||||
"isSymbolChannel": isSymbolChannel,
|
||||
@@ -255,26 +255,26 @@ func (by *Bybit) GetSubscriptionTemplate(_ *subscription.Subscription) (*templat
|
||||
}
|
||||
|
||||
// wsReadData receives and passes on websocket messages for processing
|
||||
func (by *Bybit) wsReadData(ctx context.Context, assetType asset.Item, ws websocket.Connection) {
|
||||
defer by.Websocket.Wg.Done()
|
||||
func (e *Exchange) wsReadData(ctx context.Context, assetType asset.Item, ws websocket.Connection) {
|
||||
defer e.Websocket.Wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-by.Websocket.ShutdownC:
|
||||
case <-e.Websocket.ShutdownC:
|
||||
return
|
||||
default:
|
||||
resp := ws.ReadMessage()
|
||||
if resp.Raw == nil {
|
||||
return
|
||||
}
|
||||
err := by.wsHandleData(ctx, assetType, resp.Raw)
|
||||
err := e.wsHandleData(ctx, assetType, resp.Raw)
|
||||
if err != nil {
|
||||
by.Websocket.DataHandler <- err
|
||||
e.Websocket.DataHandler <- err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (by *Bybit) wsHandleData(ctx context.Context, assetType asset.Item, respRaw []byte) error {
|
||||
func (e *Exchange) wsHandleData(ctx context.Context, assetType asset.Item, respRaw []byte) error {
|
||||
var result WebsocketResponse
|
||||
err := json.Unmarshal(respRaw, &result)
|
||||
if err != nil {
|
||||
@@ -284,13 +284,13 @@ func (by *Bybit) wsHandleData(ctx context.Context, assetType asset.Item, respRaw
|
||||
switch result.Operation {
|
||||
case "subscribe", "unsubscribe", "auth":
|
||||
if result.RequestID != "" {
|
||||
if !by.Websocket.Match.IncomingWithData(result.RequestID, respRaw) {
|
||||
if !e.Websocket.Match.IncomingWithData(result.RequestID, respRaw) {
|
||||
return fmt.Errorf("could not match subscription with id %s data %s", result.RequestID, respRaw)
|
||||
}
|
||||
}
|
||||
case "ping", "pong":
|
||||
default:
|
||||
by.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
|
||||
e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
|
||||
Message: string(respRaw),
|
||||
}
|
||||
return nil
|
||||
@@ -303,54 +303,54 @@ func (by *Bybit) wsHandleData(ctx context.Context, assetType asset.Item, respRaw
|
||||
}
|
||||
switch topicSplit[0] {
|
||||
case chanOrderbook:
|
||||
return by.wsProcessOrderbook(assetType, &result)
|
||||
return e.wsProcessOrderbook(assetType, &result)
|
||||
case chanPublicTrade:
|
||||
return by.wsProcessPublicTrade(assetType, &result)
|
||||
return e.wsProcessPublicTrade(assetType, &result)
|
||||
case chanPublicTicker:
|
||||
return by.wsProcessPublicTicker(assetType, &result)
|
||||
return e.wsProcessPublicTicker(assetType, &result)
|
||||
case chanKline:
|
||||
return by.wsProcessKline(assetType, &result, topicSplit)
|
||||
return e.wsProcessKline(assetType, &result, topicSplit)
|
||||
case chanLiquidation:
|
||||
return by.wsProcessLiquidation(&result)
|
||||
return e.wsProcessLiquidation(&result)
|
||||
case chanLeverageTokenKline:
|
||||
return by.wsProcessLeverageTokenKline(assetType, &result, topicSplit)
|
||||
return e.wsProcessLeverageTokenKline(assetType, &result, topicSplit)
|
||||
case chanLeverageTokenTicker:
|
||||
return by.wsProcessLeverageTokenTicker(assetType, &result)
|
||||
return e.wsProcessLeverageTokenTicker(assetType, &result)
|
||||
case chanLeverageTokenNav:
|
||||
return by.wsLeverageTokenNav(&result)
|
||||
return e.wsLeverageTokenNav(&result)
|
||||
case chanPositions:
|
||||
return by.wsProcessPosition(&result)
|
||||
return e.wsProcessPosition(&result)
|
||||
case chanExecution:
|
||||
return by.wsProcessExecution(asset.Spot, &result)
|
||||
return e.wsProcessExecution(asset.Spot, &result)
|
||||
case chanOrder:
|
||||
return by.wsProcessOrder(asset.Spot, &result)
|
||||
return e.wsProcessOrder(asset.Spot, &result)
|
||||
case chanWallet:
|
||||
return by.wsProcessWalletPushData(ctx, asset.Spot, respRaw)
|
||||
return e.wsProcessWalletPushData(ctx, asset.Spot, respRaw)
|
||||
case chanGreeks:
|
||||
return by.wsProcessGreeks(respRaw)
|
||||
return e.wsProcessGreeks(respRaw)
|
||||
case chanDCP:
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unhandled stream data %s", string(respRaw))
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessGreeks(resp []byte) error {
|
||||
func (e *Exchange) wsProcessGreeks(resp []byte) error {
|
||||
var result GreeksResponse
|
||||
err := json.Unmarshal(resp, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.DataHandler <- &result
|
||||
e.Websocket.DataHandler <- &result
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessWalletPushData(ctx context.Context, assetType asset.Item, resp []byte) error {
|
||||
func (e *Exchange) wsProcessWalletPushData(ctx context.Context, assetType asset.Item, resp []byte) error {
|
||||
var result WebsocketWallet
|
||||
err := json.Unmarshal(resp, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
creds, err := by.GetCredentials(ctx)
|
||||
creds, err := e.GetCredentials(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -368,12 +368,12 @@ func (by *Bybit) wsProcessWalletPushData(ctx context.Context, assetType asset.It
|
||||
})
|
||||
}
|
||||
}
|
||||
by.Websocket.DataHandler <- changes
|
||||
return account.ProcessChange(by.Name, changes, creds)
|
||||
e.Websocket.DataHandler <- changes
|
||||
return account.ProcessChange(e.Name, changes, creds)
|
||||
}
|
||||
|
||||
// wsProcessOrder the order stream to see changes to your orders in real-time.
|
||||
func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
var result WsOrders
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
@@ -381,7 +381,7 @@ func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) e
|
||||
}
|
||||
execution := make([]order.Detail, len(result))
|
||||
for x := range result {
|
||||
cp, err := by.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
cp, err := e.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -395,7 +395,7 @@ func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) e
|
||||
}
|
||||
execution[x] = order.Detail{
|
||||
Amount: result[x].Qty.Float64(),
|
||||
Exchange: by.Name,
|
||||
Exchange: e.Name,
|
||||
OrderID: result[x].OrderID,
|
||||
ClientOrderID: result[x].OrderLinkID,
|
||||
Side: side,
|
||||
@@ -410,11 +410,11 @@ func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) e
|
||||
LastUpdated: result[x].UpdatedTime.Time(),
|
||||
}
|
||||
}
|
||||
by.Websocket.DataHandler <- execution
|
||||
e.Websocket.DataHandler <- execution
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessExecution(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
var result WsExecutions
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
@@ -422,7 +422,7 @@ func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketRespons
|
||||
}
|
||||
executions := make([]fill.Data, len(result))
|
||||
for x := range result {
|
||||
cp, err := by.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
cp, err := e.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -433,7 +433,7 @@ func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketRespons
|
||||
executions[x] = fill.Data{
|
||||
ID: result[x].ExecID,
|
||||
Timestamp: result[x].ExecTime.Time(),
|
||||
Exchange: by.Name,
|
||||
Exchange: e.Name,
|
||||
AssetType: assetType,
|
||||
CurrencyPair: cp,
|
||||
Side: side,
|
||||
@@ -443,59 +443,59 @@ func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketRespons
|
||||
Amount: result[x].ExecQty.Float64(),
|
||||
}
|
||||
}
|
||||
by.Websocket.DataHandler <- executions
|
||||
e.Websocket.DataHandler <- executions
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessPosition(resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessPosition(resp *WebsocketResponse) error {
|
||||
var result WsPositions
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.DataHandler <- result
|
||||
e.Websocket.DataHandler <- result
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsLeverageTokenNav(resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsLeverageTokenNav(resp *WebsocketResponse) error {
|
||||
var result LTNav
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.DataHandler <- result
|
||||
e.Websocket.DataHandler <- result
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessLeverageTokenTicker(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessLeverageTokenTicker(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
var result TickerItem
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cp, err := by.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
cp, err := e.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.DataHandler <- &ticker.Price{
|
||||
e.Websocket.DataHandler <- &ticker.Price{
|
||||
Last: result.LastPrice.Float64(),
|
||||
High: result.HighPrice24H.Float64(),
|
||||
Low: result.LowPrice24H.Float64(),
|
||||
Pair: cp,
|
||||
ExchangeName: by.Name,
|
||||
ExchangeName: e.Name,
|
||||
AssetType: assetType,
|
||||
LastUpdated: resp.PushTimestamp.Time(),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessLeverageTokenKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error {
|
||||
func (e *Exchange) wsProcessLeverageTokenKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error {
|
||||
var result LTKlines
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cp, err := by.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType))
|
||||
cp, err := e.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -509,7 +509,7 @@ func (by *Bybit) wsProcessLeverageTokenKline(assetType asset.Item, resp *Websock
|
||||
Timestamp: result[x].Timestamp.Time(),
|
||||
Pair: cp,
|
||||
AssetType: assetType,
|
||||
Exchange: by.Name,
|
||||
Exchange: e.Name,
|
||||
StartTime: result[x].Start.Time(),
|
||||
CloseTime: result[x].End.Time(),
|
||||
Interval: interval.String(),
|
||||
@@ -519,27 +519,27 @@ func (by *Bybit) wsProcessLeverageTokenKline(assetType asset.Item, resp *Websock
|
||||
LowPrice: result[x].Low.Float64(),
|
||||
}
|
||||
}
|
||||
by.Websocket.DataHandler <- result
|
||||
e.Websocket.DataHandler <- result
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessLiquidation(resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessLiquidation(resp *WebsocketResponse) error {
|
||||
var result WebsocketLiquidation
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
by.Websocket.DataHandler <- result
|
||||
e.Websocket.DataHandler <- result
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error {
|
||||
func (e *Exchange) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error {
|
||||
var result WsKlines
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cp, err := by.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType))
|
||||
cp, err := e.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -553,7 +553,7 @@ func (by *Bybit) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, t
|
||||
Timestamp: result[x].Timestamp.Time(),
|
||||
Pair: cp,
|
||||
AssetType: assetType,
|
||||
Exchange: by.Name,
|
||||
Exchange: e.Name,
|
||||
StartTime: result[x].Start.Time(),
|
||||
CloseTime: result[x].End.Time(),
|
||||
Interval: interval.String(),
|
||||
@@ -564,21 +564,21 @@ func (by *Bybit) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, t
|
||||
Volume: result[x].Volume.Float64(),
|
||||
}
|
||||
}
|
||||
by.Websocket.DataHandler <- spotCandlesticks
|
||||
e.Websocket.DataHandler <- spotCandlesticks
|
||||
return nil
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
tickResp := new(TickerItem)
|
||||
if err := json.Unmarshal(resp.Data, tickResp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p, err := by.MatchSymbolWithAvailablePairs(tickResp.Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
p, err := e.MatchSymbolWithAvailablePairs(tickResp.Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pFmt, err := by.GetPairFormat(assetType, false)
|
||||
pFmt, err := e.GetPairFormat(assetType, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -588,12 +588,12 @@ func (by *Bybit) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResp
|
||||
if resp.Type == "snapshot" {
|
||||
tick = &ticker.Price{
|
||||
Pair: p,
|
||||
ExchangeName: by.Name,
|
||||
ExchangeName: e.Name,
|
||||
AssetType: assetType,
|
||||
}
|
||||
} else {
|
||||
// ticker updates may be partial, so we need to update the current ticker
|
||||
tick, err = ticker.GetTicker(by.Name, p, assetType)
|
||||
tick, err = ticker.GetTicker(e.Name, p, assetType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -603,7 +603,7 @@ func (by *Bybit) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResp
|
||||
tick.LastUpdated = resp.PushTimestamp.Time()
|
||||
|
||||
if err = ticker.ProcessTicker(tick); err == nil {
|
||||
by.Websocket.DataHandler <- tick
|
||||
e.Websocket.DataHandler <- tick
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -667,7 +667,7 @@ func updateTicker(tick *ticker.Price, resp *TickerItem) {
|
||||
}
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
var result WebsocketPublicTrades
|
||||
err := json.Unmarshal(resp.Data, &result)
|
||||
if err != nil {
|
||||
@@ -675,7 +675,7 @@ func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketRespo
|
||||
}
|
||||
tradeDatas := make([]trade.Data, len(result))
|
||||
for x := range result {
|
||||
cp, err := by.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
cp, err := e.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -687,7 +687,7 @@ func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketRespo
|
||||
Timestamp: result[x].OrderFillTimestamp.Time(),
|
||||
CurrencyPair: cp,
|
||||
AssetType: assetType,
|
||||
Exchange: by.Name,
|
||||
Exchange: e.Name,
|
||||
Price: result[x].Price.Float64(),
|
||||
Amount: result[x].Size.Float64(),
|
||||
Side: side,
|
||||
@@ -697,7 +697,7 @@ func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketRespo
|
||||
return trade.AddTradesToBuffer(tradeDatas...)
|
||||
}
|
||||
|
||||
func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
func (e *Exchange) wsProcessOrderbook(assetType asset.Item, resp *WebsocketResponse) error {
|
||||
var result WsOrderbookDetail
|
||||
if err := json.Unmarshal(resp.Data, &result); err != nil {
|
||||
return err
|
||||
@@ -706,7 +706,7 @@ func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketRespons
|
||||
return nil
|
||||
}
|
||||
|
||||
cp, err := by.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
cp, err := e.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -722,9 +722,9 @@ func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketRespons
|
||||
}
|
||||
|
||||
if resp.Type == "snapshot" {
|
||||
return by.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
|
||||
return e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{
|
||||
Pair: cp,
|
||||
Exchange: by.Name,
|
||||
Exchange: e.Name,
|
||||
Asset: assetType,
|
||||
LastUpdated: resp.OrderbookLastUpdated.Time(),
|
||||
LastUpdateID: result.UpdateID,
|
||||
@@ -733,7 +733,7 @@ func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketRespons
|
||||
Bids: bids,
|
||||
})
|
||||
}
|
||||
return by.Websocket.Orderbook.Update(&orderbook.Update{
|
||||
return e.Websocket.Orderbook.Update(&orderbook.Update{
|
||||
Pair: cp,
|
||||
Asks: asks,
|
||||
Bids: bids,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user