From 5486ffc2e809be964269ec12a124680e391d9b3a Mon Sep 17 00:00:00 2001 From: wuhewuhe Date: Sun, 5 Nov 2023 23:42:17 +0100 Subject: [PATCH] position endpoints --- bybit_api_client.go | 20 +-- examples/position/position_list.go | 22 +++ examples/position/position_mode.go | 22 +++ models/positionResponse.go | 135 ++++++++++++++ position.go | 276 +++++++++++++++++++++++++++++ trade.go | 24 +-- 6 files changed, 477 insertions(+), 22 deletions(-) create mode 100644 examples/position/position_list.go create mode 100644 examples/position/position_mode.go diff --git a/bybit_api_client.go b/bybit_api_client.go index b672b51..b9cb64b 100644 --- a/bybit_api_client.go +++ b/bybit_api_client.go @@ -53,14 +53,6 @@ func WithBaseURL(baseURL string) ClientOption { } } -type ServerResponse struct { - RetCode int `json:"retCode"` - RetMsg string `json:"retMsg"` - Result interface{} `json:"result"` - RetExtInfo struct{} `json:"retExtInfo"` - Time int64 `json:"time"` -} - func PrettyPrint(i interface{}) string { s, _ := json.MarshalIndent(i, "", "\t") return string(s) @@ -242,9 +234,17 @@ func (c *Client) NewPlaceOrderService(category, symbol, side, orderType, qty str } } -func (c *Client) NewTradeService(params map[string]interface{}) *Trade { - return &Trade{ +func (c *Client) NewTradeService(params map[string]interface{}) *TradeClient { + return &TradeClient{ c: c, params: params, } } + +func (c *Client) NewPositionService(params map[string]interface{}) *PositionClient { + return &PositionClient{ + c: c, + params: params, + } + +} diff --git a/examples/position/position_list.go b/examples/position/position_list.go new file mode 100644 index 0000000..e3f1dc5 --- /dev/null +++ b/examples/position/position_list.go @@ -0,0 +1,22 @@ +package main + +import ( + "context" + "fmt" + bybit "github.com/wuhewuhe/bybit.go.api" +) + +func main() { + PlaceTrade() +} + +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()) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(bybit.PrettyPrint(orderResult)) +} diff --git a/examples/position/position_mode.go b/examples/position/position_mode.go new file mode 100644 index 0000000..26bfe7a --- /dev/null +++ b/examples/position/position_mode.go @@ -0,0 +1,22 @@ +package main + +import ( + "context" + "fmt" + bybit "github.com/wuhewuhe/bybit.go.api" +) + +func main() { + SwitchPositionMode() +} + +func SwitchPositionMode() { + client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) + params := map[string]interface{}{"category": "linear", "coin": "USDT", "mode": 3} + orderResult, err := client.NewPositionService(params).SwitchPositionMode(context.Background()) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(bybit.PrettyPrint(orderResult)) +} diff --git a/models/positionResponse.go b/models/positionResponse.go index 2640e7f..1a62c19 100644 --- a/models/positionResponse.go +++ b/models/positionResponse.go @@ -1 +1,136 @@ package models + +type PositionListInfo struct { + Category string `json:"category"` + List []struct { + PositionIdx int `json:"positionIdx"` + RiskId int `json:"riskId"` + RiskLimitValue string `json:"riskLimitValue"` + Symbol string `json:"symbol"` + Side string `json:"side"` + Size string `json:"size"` + AvgPrice string `json:"avgPrice"` + PositionValue string `json:"positionValue"` + TradeMode int `json:"tradeMode"` + AutoAddMargin int `json:"autoAddMargin"` + PositionStatus string `json:"positionStatus"` + Leverage string `json:"leverage"` + MarkPrice string `json:"markPrice"` + LiqPrice string `json:"liqPrice"` + BustPrice string `json:"bustPrice"` + PositionIM string `json:"positionIM"` + PositionMM string `json:"positionMM"` + PositionBalance string `json:"positionBalance"` + TpslMode string `json:"tpslMode"` + TakeProfit string `json:"takeProfit"` + StopLoss string `json:"stopLoss"` + TrailingStop string `json:"trailingStop"` + UnrealisedPnl string `json:"unrealisedPnl"` + CumRealisedPnl string `json:"cumRealisedPnl"` + AdlRankIndicator int `json:"adlRankIndicator"` + IsReduceOnly bool `json:"isReduceOnly"` + MmrSysUpdatedTime string `json:"mmrSysUpdatedTime"` + LeverageSysUpdatedTime string `json:"leverageSysUpdatedTime"` + CreatedTime string `json:"createdTime"` + UpdatedTime string `json:"updatedTime"` + Seq int64 `json:"seq"` + } `json:"list"` + NextPageCursor string `json:"nextPageCursor"` +} + +type PositionTpslMode struct { + TpSlMode string `json:"tpSlMode"` +} + +type PositionRiskInfo struct { + Category string `json:"category"` + RiskId int64 `json:"riskId"` + RiskLimitValue string `json:"riskLimitValue"` +} + +type PositionUpdateMargin struct { + Category string `json:"category"` + Symbol string `json:"symbol"` + PositionIdx int `json:"positionIdx"` + RiskId int `json:"riskId"` + RiskLimitValue string `json:"riskLimitValue"` + Size string `json:"size"` + AvgPrice string `json:"avgPrice"` + LiqPrice string `json:"liqPrice"` + BustPrice string `json:"bustPrice"` + MarkPrice string `json:"markPrice"` + PositionValue string `json:"positionValue"` + Leverage string `json:"leverage"` + AutoAddMargin int `json:"autoAddMargin"` + PositionStatus string `json:"positionStatus"` + PositionIM string `json:"positionIM"` + PositionMM string `json:"positionMM"` + TakeProfit string `json:"takeProfit"` + StopLoss string `json:"stopLoss"` + TrailingStop string `json:"trailingStop"` + UnrealisedPnl string `json:"unrealisedPnl"` + CumRealisedPnl string `json:"cumRealisedPnl"` + CreatedTime string `json:"createdTime"` + UpdatedTime string `json:"updatedTime"` +} + +type PositionExecutionInfo struct { + Category string `json:"category"` + List []PositionExecutionEntry `json:"list"` +} + +type PositionExecutionEntry struct { + Symbol string `json:"symbol"` + OrderID string `json:"orderId"` + OrderLinkId string `json:"orderLinkId"` + Side string `json:"side"` + OrderPrice string `json:"orderPrice"` + OrderQty string `json:"orderQty"` + LeavesQty string `json:"leavesQty"` + OrderType string `json:"orderType"` + StopOrderType string `json:"stopOrderType"` + ExecFee string `json:"execFee"` + ExecId string `json:"execId"` + ExecPrice string `json:"execPrice"` + ExecQty string `json:"execQty"` + ExecType string `json:"execType"` + ExecValue string `json:"execValue"` + ExecTime string `json:"execTime"` + IsMaker bool `json:"isMaker"` + FeeRate string `json:"feeRate"` + TradeIv string `json:"tradeIv"` + MarkIv string `json:"markIv"` + MarkPrice string `json:"markPrice"` + IndexPrice string `json:"indexPrice"` + UnderlyingPrice string `json:"underlyingPrice"` + BlockTradeId string `json:"blockTradeId"` + ClosedSize string `json:"closedSize"` + Seq int64 `json:"seq"` + NextPageCursor string `json:"nextPageCursor"` +} + +type PositionClosedPnlInfo struct { + Category string `json:"category"` + List []ClosedPnlInfoEntry `json:"list"` + NextPageCursor string `json:"nextPageCursor"` +} + +type ClosedPnlInfoEntry struct { + Symbol string `json:"symbol"` + OrderID string `json:"orderId"` + Side string `json:"side"` + Qty string `json:"qty"` + OrderPrice string `json:"orderPrice"` + OrderType string `json:"orderType"` + ExecType string `json:"execType"` + ClosedSize string `json:"closedSize"` + CumEntryValue string `json:"cumEntryValue"` + AvgEntryPrice string `json:"avgEntryPrice"` + CumExitValue string `json:"cumExitValue"` + AvgExitPrice string `json:"avgExitPrice"` + ClosedPnl string `json:"closedPnl"` + FillCount string `json:"fillCount"` + Leverage string `json:"leverage"` + CreatedTime string `json:"createdTime"` + UpdatedTime string `json:"updatedTime"` +} diff --git a/position.go b/position.go index 06c9e41..15fbe46 100644 --- a/position.go +++ b/position.go @@ -1 +1,277 @@ package bybit_connector + +import ( + "context" + "encoding/json" + "github.com/wuhewuhe/bybit.go.api/handlers" + "net/http" +) + +type PositionClient struct { + c *Client + params map[string]interface{} +} + +func (s *PositionClient) GetPositionList(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/position/list", + 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 *PositionClient) SetPositionLeverage(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/set-leverage", + 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 *PositionClient) SwitchPositionMargin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/switch-isolated", + 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 *PositionClient) SetPositionTpslMode(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/set-tpsl-mode", + 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 *PositionClient) SwitchPositionMode(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/switch-mode", + 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 *PositionClient) SetPositionRiskLimit(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/set-risk-limit", + 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 *PositionClient) SetPositionTradingStop(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/trading-stop", + 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 *PositionClient) SetPositionAutoMargin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/set-auto-add-margin", + 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 *PositionClient) UpdatePositionMargin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/add-margin", + 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 *PositionClient) ConfirmPositionRiskLimit(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/confirm-pending-mmr", + 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 *PositionClient) GetExecutionList(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/execution/list", + 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 *PositionClient) GetClosePnl(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/position/closed-pnl", + 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 +} diff --git a/trade.go b/trade.go index f2b1535..494b2a9 100644 --- a/trade.go +++ b/trade.go @@ -8,12 +8,12 @@ import ( "net/http" ) -type Trade struct { +type TradeClient struct { c *Client params map[string]interface{} } -func (s *Trade) PlaceOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) PlaceOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -35,7 +35,7 @@ func (s *Trade) PlaceOrder(ctx context.Context, opts ...RequestOption) (res *Ser return res, nil } -func (s *Trade) AmendOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) AmendOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -57,7 +57,7 @@ func (s *Trade) AmendOrder(ctx context.Context, opts ...RequestOption) (res *Ser return res, nil } -func (s *Trade) CancelOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) CancelOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -79,7 +79,7 @@ func (s *Trade) CancelOrder(ctx context.Context, opts ...RequestOption) (res *Se return res, nil } -func (s *Trade) GetOpenOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) GetOpenOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -101,7 +101,7 @@ func (s *Trade) GetOpenOrders(ctx context.Context, opts ...RequestOption) (res * return res, nil } -func (s *Trade) GetOrderHistory(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) GetOrderHistory(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -123,7 +123,7 @@ func (s *Trade) GetOrderHistory(ctx context.Context, opts ...RequestOption) (res return res, nil } -func (s *Trade) GetSpotBorrowQuota(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) GetSpotBorrowQuota(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -145,7 +145,7 @@ func (s *Trade) GetSpotBorrowQuota(ctx context.Context, opts ...RequestOption) ( return res, nil } -func (s *Trade) CancelAllOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) CancelAllOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -167,7 +167,7 @@ func (s *Trade) CancelAllOrders(ctx context.Context, opts ...RequestOption) (res return res, nil } -func (s *Trade) SetDisconnectCancelAll(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *TradeClient) SetDisconnectCancelAll(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -189,7 +189,7 @@ func (s *Trade) SetDisconnectCancelAll(ctx context.Context, opts ...RequestOptio return res, nil } -func (s *Trade) PlaceBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { +func (s *TradeClient) PlaceBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -211,7 +211,7 @@ func (s *Trade) PlaceBatchOrder(ctx context.Context, opts ...RequestOption) (res return res, nil } -func (s *Trade) AmendBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { +func (s *TradeClient) AmendBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -233,7 +233,7 @@ func (s *Trade) AmendBatchOrder(ctx context.Context, opts ...RequestOption) (res return res, nil } -func (s *Trade) CancelBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { +func (s *TradeClient) CancelBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err }