From 058bfbdf50eea577fa432238a0f37177d464cf9d Mon Sep 17 00:00:00 2001 From: wuhewuhe Date: Mon, 6 Nov 2023 00:16:08 +0100 Subject: [PATCH] account endpoints --- account.go | 271 ++++++++++++++++++++++++++++ bybit_api_client.go | 13 ++ examples/account/transaction_log.go | 6 +- models/accountResponse.go | 143 +++++++++++++++ position.go | 4 +- 5 files changed, 432 insertions(+), 5 deletions(-) create mode 100644 account.go diff --git a/account.go b/account.go new file mode 100644 index 0000000..a131bc8 --- /dev/null +++ b/account.go @@ -0,0 +1,271 @@ +package bybit_connector + +import ( + "context" + "encoding/json" + "github.com/wuhewuhe/bybit.go.api/handlers" + "net/http" +) + +type AccountClient struct { + c *Client + params map[string]interface{} +} + +func (s *AccountClient) GetTransactionLog(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/account/transaction-log", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) GetFeeRates(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/account/fee-rate", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) GetAccountWallet(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/account/wallet-balance", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) GetBorrowHistory(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/account/borrow-history", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) GetCoinGreeks(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/asset/coin-greeks", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) GetCollateralInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/account/collateral-info", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) GetAccountInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodGet, + endpoint: "/v5/account/upgrade-to-uta", + secType: secTypeSigned, + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) GetMMPState(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodGet, + endpoint: "/v5/account/mmp-state", + secType: secTypeSigned, + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) UpgradeToUTA(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodPost, + endpoint: "/v5/account/upgrade-to-uta", + secType: secTypeSigned, + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) SetCollateralCoin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodPost, + endpoint: "/v5/account/set-collateral-switch", + secType: secTypeSigned, + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) SetMarginMode(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodPost, + endpoint: "/v5/account/set-margin-mode", + secType: secTypeSigned, + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) SetMarketMakerProtection(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodPost, + endpoint: "/v5/account/mmp-modify", + secType: secTypeSigned, + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *AccountClient) ResetMarketMakerProtection(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodPost, + endpoint: "/v5/account/mmp-reset", + secType: secTypeSigned, + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/bybit_api_client.go b/bybit_api_client.go index 7702c99..b33bdc3 100644 --- a/bybit_api_client.go +++ b/bybit_api_client.go @@ -255,3 +255,16 @@ func (c *Client) NewPreUpgradeService(params map[string]interface{}) *PreUpgrade params: params, } } + +func (c *Client) NewAccountService(params map[string]interface{}) *AccountClient { + return &AccountClient{ + c: c, + params: params, + } +} + +func (c *Client) NewAccountServiceNoParams() *AccountClient { + return &AccountClient{ + c: c, + } +} diff --git a/examples/account/transaction_log.go b/examples/account/transaction_log.go index e3f1dc5..b36271c 100644 --- a/examples/account/transaction_log.go +++ b/examples/account/transaction_log.go @@ -12,11 +12,11 @@ func main() { func PlaceTrade() { client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) - params := map[string]interface{}{"category": "linear", "settleCoin": "USDT", "limit": 10} - orderResult, err := client.NewPositionService(params).GetPositionList(context.Background()) + params := map[string]interface{}{"accountType": "UNIFIED", "category": "linear"} + accountResult, err := client.NewAccountService(params).GetTransactionLog(context.Background()) if err != nil { fmt.Println(err) return } - fmt.Println(bybit.PrettyPrint(orderResult)) + fmt.Println(bybit.PrettyPrint(accountResult)) } diff --git a/models/accountResponse.go b/models/accountResponse.go index 03c3533..7aa2208 100644 --- a/models/accountResponse.go +++ b/models/accountResponse.go @@ -26,3 +26,146 @@ type TransactionLogEntry struct { OrderID string `json:"orderId"` OrderLinkId string `json:"orderLinkId"` } + +type UpgradeUtaInfo struct { + UnifiedUpdateStatus string `json:"unifiedUpdateStatus"` + UnifiedUpdateMsg *UnifiedUpdateMsg `json:"unifiedUpdateMsg,omitempty"` +} + +type UnifiedUpdateMsg struct { + Msg []string `json:"msg"` +} + +type WalletBalanceInfo struct { + List []AccountInfo `json:"list"` +} + +type WalletAccountInfo struct { + AccountType string `json:"accountType"` + AccountLTV string `json:"accountLTV"` + AccountIMRate string `json:"accountIMRate"` + AccountMMRate string `json:"accountMMRate"` + TotalEquity string `json:"totalEquity"` + TotalWalletBalance string `json:"totalWalletBalance"` + TotalMarginBalance string `json:"totalMarginBalance"` + TotalAvailableBalance string `json:"totalAvailableBalance"` + TotalPerpUPL string `json:"totalPerpUPL"` + TotalInitialMargin string `json:"totalInitialMargin"` + TotalMaintenanceMargin string `json:"totalMaintenanceMargin"` + Coins []CoinInfo `json:"coin"` +} + +type CoinInfo struct { + Coin string `json:"coin"` + Equity string `json:"equity"` + UsdValue string `json:"usdValue"` + WalletBalance string `json:"walletBalance"` + Free string `json:"free"` + Locked string `json:"locked"` + BorrowAmount string `json:"borrowAmount"` + AvailableToBorrow string `json:"availableToBorrow"` + AvailableToWithdraw string `json:"availableToWithdraw"` + AccruedInterest string `json:"accruedInterest"` + TotalOrderIM string `json:"totalOrderIM"` + TotalPositionIM string `json:"totalPositionIM"` + TotalPositionMM string `json:"totalPositionMM"` + UnrealisedPnl string `json:"unrealisedPnl"` + CumRealisedPnl string `json:"cumRealisedPnl"` + Bonus string `json:"bonus"` + CollateralSwitch bool `json:"collateralSwitch"` + MarginCollateral bool `json:"marginCollateral"` +} + +type CoinGreeks struct { + CoinGreeks []CoinGreekInfo `json:"coin"` +} + +type CoinGreekInfo struct { + BaseCoin string `json:"baseCoin"` + TotalDelta string `json:"totalDelta"` + TotalGamma string `json:"totalGamma"` + TotalVega string `json:"totalVega"` + TotalTheta string `json:"totalTheta"` +} + +type CollateralInfo struct { + List []CollateralItem `json:"list"` +} + +type CollateralItem struct { + Currency string `json:"currency"` + HourlyBorrowRate string `json:"hourlyBorrowRate"` + MaxBorrowingAmount string `json:"maxBorrowingAmount"` + FreeBorrowingLimit string `json:"freeBorrowingLimit"` + FreeBorrowAmount string `json:"freeBorrowAmount"` + BorrowAmount string `json:"borrowAmount"` + AvailableToBorrow string `json:"availableToBorrow"` + Borrowable bool `json:"borrowable"` + BorrowUsageRate string `json:"borrowUsageRate"` + MarginCollateral bool `json:"marginCollateral"` + CollateralSwitch bool `json:"collateralSwitch"` + CollateralRatio string `json:"collateralRatio"` +} + +type BorrowHistory struct { + List []BorrowHistoryItem `json:"list"` + NextPageCursor string `json:"nextPageCursor"` +} + +type BorrowHistoryItem struct { + Currency string `json:"currency"` + CreatedTime int64 `json:"createdTime"` // Using int64 for milliseconds timestamp + BorrowCost string `json:"borrowCost"` + HourlyBorrowRate string `json:"hourlyBorrowRate"` + InterestBearingBorrowSize string `json:"InterestBearingBorrowSize"` + CostExemption string `json:"costExemption"` + BorrowAmount string `json:"borrowAmount"` + UnrealisedLoss string `json:"unrealisedLoss"` + FreeBorrowedAmount string `json:"freeBorrowedAmount"` +} + +type FeeRatesInfo struct { + Category string `json:"category"` + List []FeeRateItem `json:"list"` +} + +type FeeRateItem struct { + Symbol string `json:"symbol"` + BaseCoin string `json:"baseCoin"` + TakerFeeRate string `json:"takerFeeRate"` + MakerFeeRate string `json:"makerFeeRate"` +} + +type AccountInfo struct { + UnifiedMarginStatus int `json:"unifiedMarginStatus"` + MarginMode string `json:"marginMode"` + DcpStatus string `json:"dcpStatus"` + TimeWindow int `json:"timeWindow"` + SmpGroup int `json:"smpGroup"` + IsMasterTrader bool `json:"isMasterTrader"` + UpdatedTime string `json:"updatedTime"` +} + +type MMPStateInfo struct { + Result []MMPStateItem `json:"result"` +} + +type MMPStateItem struct { + BaseCoin string `json:"baseCoin"` + MmpEnabled bool `json:"mmpEnabled"` + Window string `json:"window"` + FrozenPeriod string `json:"frozenPeriod"` + QtyLimit string `json:"qtyLimit"` + DeltaLimit string `json:"deltaLimit"` +} + +type MarginMode struct { + Reasons []ReasonItem `json:"reasons"` + MmpFrozenUntil string `json:"mmpFrozenUntil"` + MmpFrozen bool `json:"mmpFrozen"` +} + +type ReasonItem struct { + ReasonCode string `json:"reasonCode"` + ReasonMsg string `json:"reasonMsg"` +} diff --git a/position.go b/position.go index 15fbe46..ef8658f 100644 --- a/position.go +++ b/position.go @@ -237,7 +237,7 @@ func (s *PositionClient) GetExecutionList(ctx context.Context, opts ...RequestOp return nil, err } r := &request{ - method: http.MethodPost, + method: http.MethodGet, endpoint: "/v5/execution/list", secType: secTypeSigned, } @@ -259,7 +259,7 @@ func (s *PositionClient) GetClosePnl(ctx context.Context, opts ...RequestOption) return nil, err } r := &request{ - method: http.MethodPost, + method: http.MethodGet, endpoint: "/v5/position/closed-pnl", secType: secTypeSigned, }