Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: inverse future cancel all order #44

Merged
merged 4 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ The following API endpoints have been implemented
- `/futures/private/order/create` Place Active Order
- `/futures/private/order/list` Get Active Order
- `/futures/private/order/cancel` Cancel Active Order
- `/futures/private/order/cancelAll` Cancel All Active Orders

##### Wallet Data Endpoints

Expand Down
49 changes: 49 additions & 0 deletions future_inverse_future.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type FutureInverseFutureServiceI interface {
CreateFuturesOrder(CreateFuturesOrderParam) (*CreateFuturesOrderResponse, error)
ListFuturesOrder(ListFuturesOrderParam) (*ListFuturesOrderResponse, error)
CancelFuturesOrder(CancelFuturesOrderParam) (*CancelFuturesOrderResponse, error)
CancelAllFuturesOrder(CancelAllFuturesOrderParam) (*CancelAllFuturesOrderResponse, error)

// Wallet Data Endpoints
Balance(Coin) (*BalanceResponse, error)
Expand Down Expand Up @@ -222,3 +223,51 @@ func (s *FutureInverseFutureService) CancelFuturesOrder(param CancelFuturesOrder

return &res, nil
}

// CancelAllFuturesOrderResponse :
type CancelAllFuturesOrderResponse struct {
CommonResponse `json:",inline"`
Result []CancelAllFuturesOrderResult `json:"result"`
}

// CancelAllFuturesOrderResult :
type CancelAllFuturesOrderResult struct {
ClOrdID string `json:"clOrdID"`
UserID int `json:"user_id"`
Symbol SymbolFuture `json:"symbol"`
Side Side `json:"side"`
OrderType OrderType `json:"order_type"`
Price string `json:"price"`
Qty float64 `json:"qty"`
TimeInForce TimeInForce `json:"time_in_force"`
CreateType string `json:"create_type"`
CancelType string `json:"cancel_type"`
OrderStatus OrderStatus `json:"order_status"`
LeavesQty float64 `json:"leaves_qty"`
LeavesValue string `json:"leaves_value"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
CrossStatus string `json:"cross_status"`
CrossSeq int `json:"cross_seq"`
}

// CancelAllFuturesOrderParam :
type CancelAllFuturesOrderParam struct {
Symbol SymbolFuture `json:"symbol"`
}

// CancelAllFuturesOrder :
func (s *FutureInverseFutureService) CancelAllFuturesOrder(param CancelAllFuturesOrderParam) (*CancelAllFuturesOrderResponse, error) {
var res CancelAllFuturesOrderResponse

body, err := json.Marshal(param)
if err != nil {
return nil, fmt.Errorf("json marshal for CancelAllFuturesOrderParam: %w", err)
}

if err := s.client.postJSON("/futures/private/order/cancelAll", body, &res); err != nil {
return nil, err
}

return &res, nil
}
97 changes: 97 additions & 0 deletions future_inverse_future_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,100 @@ func TestCancelFuturesOrder(t *testing.T) {
assert.Error(t, err)
})
}

func TestAllCancelFuturesOrder(t *testing.T) {
t.Run("success", func(t *testing.T) {
param := CancelAllFuturesOrderParam{
Symbol: SymbolFutureBTCUSD,
}

path := "/futures/private/order/cancelAll"
method := http.MethodPost
status := http.StatusOK
respBody := CancelAllFuturesOrderResponse{
Result: []CancelAllFuturesOrderResult{
{
ClOrdID: "4ad4e9c5-4aa0-40bd-8a4d-53c4b4ca49ef",
UserID: 146940,
Symbol: "BTCUSD",
Side: "Buy",
OrderType: "Limit",
Price: "10000",
Qty: 1,
TimeInForce: "GoodTillCancel",
CreateType: "CreateByUser",
CancelType: "CancelByUser",
OrderStatus: "",
LeavesQty: 1,
LeavesValue: "0",
CreatedAt: "2022-10-18T08:10:15.341270694Z",
UpdatedAt: "2022-10-18T08:10:15.426826461Z",
CrossStatus: "PendingCancel",
CrossSeq: 5554666653,
},
},
}
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.Future().InverseFuture().CancelAllFuturesOrder(param)
require.NoError(t, err)

require.NotNil(t, resp)
assert.Equal(t, respBody, *resp)
})
t.Run("authentication required", func(t *testing.T) {
param := CancelAllFuturesOrderParam{
Symbol: SymbolFutureBTCUSD,
}

path := "/futures/private/order/cancelAll"
method := http.MethodPost
status := http.StatusOK
respBody := CancelAllFuturesOrderResponse{
Result: []CancelAllFuturesOrderResult{
{
ClOrdID: "4ad4e9c5-4aa0-40bd-8a4d-53c4b4ca49ef",
UserID: 146940,
Symbol: "BTCUSD",
Side: "Buy",
OrderType: "Limit",
Price: "10000",
Qty: 1,
TimeInForce: "GoodTillCancel",
CreateType: "CreateByUser",
CancelType: "CancelByUser",
OrderStatus: "",
LeavesQty: 1,
LeavesValue: "0",
CreatedAt: "2022-10-18T08:10:15.341270694Z",
UpdatedAt: "2022-10-18T08:10:15.426826461Z",
CrossStatus: "PendingCancel",
CrossSeq: 5554666653,
},
},
}
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.Future().InverseFuture().CancelAllFuturesOrder(param)
assert.Error(t, err)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,41 @@ func TestCancelFuturesOrder(t *testing.T) {
require.Error(t, err)
})
}

func TestCancelAllFuturesOrder(t *testing.T) {
t.Run("ok", func(t *testing.T) {
client := bybit.NewTestClient().WithAuthFromEnv()
symbol := bybit.SymbolFutureBTCUSD
{
price := 10000.0
_, err := client.Future().InverseFuture().CreateFuturesOrder(bybit.CreateFuturesOrderParam{
Side: bybit.SideBuy,
Symbol: symbol,
OrderType: bybit.OrderTypeLimit,
Qty: 1,
TimeInForce: bybit.TimeInForceGoodTillCancel,
Price: &price,
})
require.NoError(t, err)
}
{
res, err := client.Future().InverseFuture().CancelAllFuturesOrder(bybit.CancelAllFuturesOrderParam{
Symbol: symbol,
})
require.NoError(t, err)
{
goldenFilename := "./testdata/futures-private-order-cancel-all.json"
testhelper.Compare(t, goldenFilename, testhelper.ConvertToJSON(res.Result))
testhelper.UpdateFile(t, goldenFilename, testhelper.ConvertToJSON(res.Result))
}
}
})

t.Run("auth error", func(t *testing.T) {
client := bybit.NewTestClient()
_, err := client.Future().InverseFuture().CancelAllFuturesOrder(bybit.CancelAllFuturesOrderParam{
Symbol: bybit.SymbolFutureBTCUSD,
})
require.Error(t, err)
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[
{
"clOrdID": "4ad4e9c5-4aa0-40bd-8a4d-53c4b4ca49ef",
"user_id": 146940,
"symbol": "BTCUSD",
"side": "Buy",
"order_type": "Limit",
"price": "10000",
"qty": 1,
"time_in_force": "GoodTillCancel",
"create_type": "CreateByUser",
"cancel_type": "CancelByUser",
"order_status": "",
"leaves_qty": 1,
"leaves_value": "0",
"created_at": "2022-10-18T08:10:15.341270694Z",
"updated_at": "2022-10-18T08:10:15.426826461Z",
"cross_status": "PendingCancel",
"cross_seq": 5554666653
}
]