diff --git a/htx/usdm/accountws/client_test.go b/htx/usdm/accountws/client_test.go index 0e5f543..5b9d05b 100644 --- a/htx/usdm/accountws/client_test.go +++ b/htx/usdm/accountws/client_test.go @@ -65,3 +65,27 @@ func TestSubscribeAccountUpdate(t *testing.T) { select {} } + +func TestSubscribeUnifyAccountUpdate(t *testing.T) { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + cli := testNewAccountWsClient(ctx, t, GlobalOrderWsBaseURL) + + topic, err := cli.GetUnifyAccountUpdateTopic() + assert.Nil(t, err) + + cli.AddListener(topic, func(e any) { + acc, ok := e.(*types.UnifyAccount) + if !ok { + return + } + + fmt.Printf("Topic: %s, Data: %+v\n", + topic, acc.Data) + }) + + cli.Subscribe(topic) + + select {} +} diff --git a/htx/usdm/accountws/subscriptions.go b/htx/usdm/accountws/subscriptions.go index 403731c..a3f43f0 100644 --- a/htx/usdm/accountws/subscriptions.go +++ b/htx/usdm/accountws/subscriptions.go @@ -53,6 +53,18 @@ func (m *AccountWsClient) handle(msg *Message) error { return err } m.GetListeners(msg.Topic, &data) + case strings.HasPrefix(msg.Topic, "accounts_unify"): + var data types.UnifyAccount + err := json.Unmarshal(msg.Raw, &data) + if err != nil { + return err + } + // since the topic in sub is different from the topic returned in ws channel + topic, err := m.GetUnifyAccountUpdateTopic() + if err != nil { + return err + } + m.GetListeners(topic, &data) default: return fmt.Errorf("unknown message, topic: %s", msg.Topic) } diff --git a/htx/usdm/accountws/topics.go b/htx/usdm/accountws/topics.go index 60633c5..67e5497 100644 --- a/htx/usdm/accountws/topics.go +++ b/htx/usdm/accountws/topics.go @@ -36,3 +36,7 @@ func (m *AccountWsClient) GetCrossAccountUpdateTopic(marginAccount string) (stri return fmt.Sprintf("accounts_cross.%s", marginAccount), nil } + +func (m *AccountWsClient) GetUnifyAccountUpdateTopic() (string, error) { + return "accounts_unify.USDT", nil +} diff --git a/htx/usdm/accountws/types/messages.go b/htx/usdm/accountws/types/messages.go index 6d0e3ab..46f0069 100644 --- a/htx/usdm/accountws/types/messages.go +++ b/htx/usdm/accountws/types/messages.go @@ -102,3 +102,58 @@ type CrossData struct { ContractDetail []ContractDetail `json:"contract_detail,omitempty"` FuturesContractDetail []FuturesContractDetail `json:"futures_contract_detail,omitempty"` } + +type UnifyAccount struct { + Op string `json:"op,omitempty"` + Topic string `json:"topic,omitempty"` + Ts int64 `json:"ts,omitempty"` + Event string `json:"event,omitempty"` + Data []UnifyAccountData `json:"data,omitempty"` + UID string `json:"uid,omitempty"` +} + +type CrossSwap struct { + Symbol string `json:"symbol,omitempty"` + ContractCode string `json:"contract_code,omitempty"` + MarginMode string `json:"margin_mode,omitempty"` + MarginAvailable float64 `json:"margin_available,omitempty"` + LeverRate float64 `json:"lever_rate,omitempty"` + ContractType string `json:"contract_type,omitempty"` + BusinessType string `json:"business_type,omitempty"` + CrossMaxAvailable float64 `json:"cross_max_available,omitempty"` +} + +type CrossFuture struct { + Symbol string `json:"symbol,omitempty"` + ContractCode string `json:"contract_code,omitempty"` + MarginMode string `json:"margin_mode,omitempty"` + MarginAvailable float64 `json:"margin_available,omitempty"` + LeverRate float64 `json:"lever_rate,omitempty"` + ContractType string `json:"contract_type,omitempty"` + BusinessType string `json:"business_type,omitempty"` + CrossMaxAvailable float64 `json:"cross_max_available,omitempty"` +} + +type IsolatedSwap struct { + Symbol string `json:"symbol,omitempty"` + ContractCode string `json:"contract_code,omitempty"` + MarginMode string `json:"margin_mode,omitempty"` + MarginAvailable float64 `json:"margin_available,omitempty"` + WithdrawAvailable float64 `json:"withdraw_available,omitempty"` + LeverRate int `json:"lever_rate,omitempty"` + PositionMode string `json:"position_mode,omitempty"` +} + +type UnifyAccountData struct { + MarginAsset string `json:"margin_asset,omitempty"` + MarginStatic float64 `json:"margin_static,omitempty"` + CrossMarginStatic float64 `json:"cross_margin_static,omitempty"` + MarginBalance float64 `json:"margin_balance,omitempty"` + CrossProfitUnreal float64 `json:"cross_profit_unreal,omitempty"` + MarginFrozen float64 `json:"margin_frozen,omitempty"` + WithdrawAvailable float64 `json:"withdraw_available,omitempty"` + CrossRiskRate float64 `json:"cross_risk_rate,omitempty"` + CrossSwap []CrossSwap `json:"cross_swap,omitempty"` + CrossFuture []CrossFuture `json:"cross_future,omitempty"` + IsolatedSwap []IsolatedSwap `json:"isolated_swap,omitempty"` +}