From fc1d4be64d4715a3f326877cda694f565d5a734e Mon Sep 17 00:00:00 2001 From: hirokisan Date: Fri, 11 Aug 2023 15:37:33 +0900 Subject: [PATCH] feat: v5 set risk limit (#137) * feat: implement * test: integration * test: unit * docs: update --- README.md | 1 + integrationtest/v5/position/position_test.go | 16 +++++ .../testdata/v5-position-set-risk-limit.json | 5 ++ v5_position_service.go | 39 +++++++++++ v5_position_service_test.go | 69 +++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 integrationtest/v5/position/testdata/v5-position-set-risk-limit.json diff --git a/README.md b/README.md index a4d2518..9ed2b9c 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ The following API endpoints have been implemented - [`/v5/position/switch-mode` Switch Position Mode](https://bybit-exchange.github.io/docs/v5/position/position-mode) - [`/v5/position/set-tpsl-mode` Set TP/SL Mode](https://bybit-exchange.github.io/docs/v5/position/tpsl-mode) - [`/v5/position/closed-pnl` Get Closed PnL](https://bybit-exchange.github.io/docs/v5/position/close-pnl) +- [`/v5/position/set-risk-limit` Set Risk Limit](https://bybit-exchange.github.io/docs/v5/position/set-risk-limit) #### Order diff --git a/integrationtest/v5/position/position_test.go b/integrationtest/v5/position/position_test.go index 60b270d..e87ee5b 100644 --- a/integrationtest/v5/position/position_test.go +++ b/integrationtest/v5/position/position_test.go @@ -168,3 +168,19 @@ func TestSwitchPositionMarginMode(t *testing.T) { testhelper.UpdateFile(t, goldenFilename, testhelper.ConvertToJSON(res.Result)) } } + +func TestSetRiskLimit(t *testing.T) { + client := bybit.NewTestClient().WithAuthFromEnv() + + res, err := client.V5().Position().SetRiskLimit(bybit.V5SetRiskLimitParam{ + Category: bybit.CategoryV5Linear, + Symbol: bybit.SymbolV5BTCUSDT, + RiskID: 3, + }) + require.NoError(t, err) + { + goldenFilename := "./testdata/v5-position-set-risk-limit.json" + testhelper.Compare(t, goldenFilename, testhelper.ConvertToJSON(res.Result)) + testhelper.UpdateFile(t, goldenFilename, testhelper.ConvertToJSON(res.Result)) + } +} diff --git a/integrationtest/v5/position/testdata/v5-position-set-risk-limit.json b/integrationtest/v5/position/testdata/v5-position-set-risk-limit.json new file mode 100644 index 0000000..b685465 --- /dev/null +++ b/integrationtest/v5/position/testdata/v5-position-set-risk-limit.json @@ -0,0 +1,5 @@ +{ + "category": "linear", + "riskId": 3, + "riskLimitValue": "6000000" +} \ No newline at end of file diff --git a/v5_position_service.go b/v5_position_service.go index 1fc21a0..206fa1a 100644 --- a/v5_position_service.go +++ b/v5_position_service.go @@ -16,6 +16,7 @@ type V5PositionServiceI interface { SwitchPositionMode(V5SwitchPositionModeParam) (*V5SwitchPositionModeResponse, error) GetClosedPnL(V5GetClosedPnLParam) (*V5GetClosedPnLResponse, error) SwitchPositionMarginMode(V5SwitchPositionMarginModeParam) (*V5SwitchPositionMarginModeResponse, error) + SetRiskLimit(V5SetRiskLimitParam) (*V5SetRiskLimitResponse, error) } // V5PositionService : @@ -380,3 +381,41 @@ func (s *V5PositionService) SwitchPositionMarginMode(param V5SwitchPositionMargi return &res, nil } + +// V5SetRiskLimitParam : +type V5SetRiskLimitParam struct { + Category CategoryV5 `json:"category"` + Symbol SymbolV5 `json:"symbol"` + RiskID int64 `json:"riskId"` + + PositionIdx *PositionIdx `json:"positionIdx,omitempty"` +} + +// V5SetRiskLimitResponse : +type V5SetRiskLimitResponse struct { + CommonV5Response `json:",inline"` + Result V5SetRiskLimitResult `json:"result"` +} + +// V5SetRiskLimitResult : +type V5SetRiskLimitResult struct { + Category CategoryV5 `json:"category"` + RiskID int64 `json:"riskId"` + RiskLimitValue string `json:"riskLimitValue"` +} + +// SetRiskLimit : +func (s *V5PositionService) SetRiskLimit(param V5SetRiskLimitParam) (*V5SetRiskLimitResponse, error) { + var res V5SetRiskLimitResponse + + body, err := json.Marshal(param) + if err != nil { + return &res, fmt.Errorf("json marshal: %w", err) + } + + if err := s.client.postV5JSON("/v5/position/set-risk-limit", body, &res); err != nil { + return &res, err + } + + return &res, nil +} diff --git a/v5_position_service_test.go b/v5_position_service_test.go index 7282841..387616d 100644 --- a/v5_position_service_test.go +++ b/v5_position_service_test.go @@ -558,3 +558,72 @@ func TestV5Position_SwitchPositionMarginMode(t *testing.T) { assert.Error(t, err) }) } + +func TestV5Position_SetRiskLimit(t *testing.T) { + t.Run("success", func(t *testing.T) { + param := V5SetRiskLimitParam{ + Category: CategoryV5Linear, + Symbol: SymbolV5BTCUSDT, + RiskID: 3, + } + + path := "/v5/position/set-risk-limit" + method := http.MethodPost + status := http.StatusOK + respBody := map[string]interface{}{ + "result": map[string]interface{}{ + "category": "linear", + "riskId": 3, + "riskLimitValue": "6000000", + }, + } + bytesBody, err := json.Marshal(respBody) + require.NoError(t, err) + + server, teardown := testhelper.NewServer( + testhelper.WithHandlerOption(path, method, status, bytesBody), + ) + defer teardown() + + client := NewTestClient(). + WithBaseURL(server.URL). + WithAuth("test", "test") + + resp, err := client.V5().Position().SetRiskLimit(param) + require.NoError(t, err) + + require.NotNil(t, resp) + testhelper.Compare(t, respBody["result"], resp.Result) + }) + t.Run("authentication required", func(t *testing.T) { + param := V5SetRiskLimitParam{ + Category: CategoryV5Linear, + Symbol: SymbolV5BTCUSDT, + RiskID: 3, + } + + path := "/v5/position/set-risk-limit" + method := http.MethodPost + status := http.StatusOK + respBody := map[string]interface{}{ + "result": map[string]interface{}{ + "category": "linear", + "riskId": 3, + "riskLimitValue": "6000000", + }, + } + bytesBody, err := json.Marshal(respBody) + require.NoError(t, err) + + server, teardown := testhelper.NewServer( + testhelper.WithHandlerOption(path, method, status, bytesBody), + ) + defer teardown() + + client := NewTestClient(). + WithBaseURL(server.URL) + + _, err = client.V5().Position().SetRiskLimit(param) + assert.Error(t, err) + }) +}