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: add linear conditional orders with tests #11

Merged
merged 7 commits into from
Aug 13, 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ go get -u github.com/cksidharthan/go-bybit
| SPOT | Wallet Data | :heavy_check_mark: | :heavy_check_mark: |
| SPOT | API Data | :heavy_check_mark: | :heavy_check_mark: |
| USDT Perpetual | Market Data | :heavy_check_mark: | :heavy_check_mark: |
| USDT Perpetual | Account Data | :x: | :x: |
| USDT Perpetual | Account Data | :heavy_check_mark: | :heavy_check_mark: |
| USDT Perpetual | Wallet Data | :x: | :x: |
| USDT Perpetual | API Data | :x: | :x: |
| Inverse Perpetual | Market Data | :x: | :x: |
Expand Down
6 changes: 6 additions & 0 deletions bybit/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ const (
PrivateLinearOrderCancelAllPath = "/private/linear/order/cancel-all"
PrivateLinearReplaceActiveOrderPath = "/private/linear/order/replace"
PrivateLinearQueryActiveOrderPath = "/private/linear/order/search"
PrivatePlaceConditionalOrderPath = "/private/linear/stop-order/create"
PrivateGetConditionalOrderPath = "/private/linear/stop-order/list"
PrivateCancelConditionalOrderPath = "/private/linear/stop-order/cancel"
PrivateCancelAllConditionalOrderPath = "/private/linear/stop-order/cancel-all"
PrivateReplaceConditionalOrderPath = "/private/linear/stop-order/replace"
PrivateQueryConditionalOrderPath = "/private/linear/stop-order/search"
PrivateLinearPositionListPath = "/private/linear/position/list"
PrivateLinearPositionSetLeveragePath = "/private/linear/position/set-leverage"
PrivateLinearTradeExecutionListPath = "/private/linear/trade/execution/list"
Expand Down
8 changes: 8 additions & 0 deletions rest/domain/linear/account_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@ type AccountInterface interface {
CancelAllActiveOrders(ctx context.Context, params *CancelAllActiveOrdersParams) (*CancelAllActiveOrdersResponse, error)
ReplaceActiveOrder(ctx context.Context, params *ReplaceActiveOrderParams) (*ReplaceActiveOrderResponse, error)
QueryActiveOrder(ctx context.Context, params *QueryActiveOrderParams) (*QueryActiveOrderResponse, error)

PlaceConditionalOrder(ctx context.Context, params *PlaceConditionalOrderParams) (*PlaceConditionalOrderResponse, error)
GetConditionalOrder(ctx context.Context, params *GetConditionalOrderParams) (*GetConditionalOrderResponse, error)
CancelConditionalOrder(ctx context.Context, params *CancelConditionalOrderParams) (*CancelConditionalOrderResponse, error)
CancelAllConditionalOrders(ctx context.Context, params *CancelAllConditionalOrdersParams) (*CancelAllConditionalOrdersResponse, error)
ReplaceConditionalOrder(ctx context.Context, params *ReplaceConditionalOrderParams) (*ReplaceConditionalOrderResponse, error)
QueryConditionalOrderBySymbol(ctx context.Context, params *QueryConditionalOrderBySymbolParams) (*QueryConditionalOrderBySymbolResponse, error)
QueryConditionalOrderWithIDs(ctx context.Context, params *QueryConditionalOrderWithIDsParams) (*QueryConditionalOrderWithIDsResponse, error)
}
206 changes: 206 additions & 0 deletions rest/domain/linear/account_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,209 @@ type QueryActiveOrderResult struct {
TpTriggerBy string `json:"tp_trigger_by"`
SlTriggerBy string `json:"sl_trigger_by"`
}

type PlaceConditionalOrderParams struct {
Side bybit.Side `url:"side" json:"side"`
Symbol string `url:"symbol" json:"symbol"`
OrderType bybit.OrderType `url:"order_type" json:"order_type"`
Qty float64 `url:"qty" json:"qty"`
Price float64 `url:"price,omitempty" json:"price,omitempty"`
BasePrice float64 `url:"base_price" json:"base_price"`
StopPx float64 `url:"stop_px" json:"stop_px"`
TimeInForce bybit.TimeInForce `url:"time_in_force" json:"time_in_force"`
TriggerBy string `url:"trigger_by" json:"trigger_by"`
ReduceOnly bool `url:"reduce_only" json:"reduce_only"`
CloseOnTrigger bool `url:"close_on_trigger" json:"close_on_trigger"`
OrderLinkID string `url:"order_link_id,omitempty" json:"order_link_id,omitempty"`
TakeProfit float64 `url:"take_profit,omitempty" json:"take_profit,omitempty"`
StopLoss float64 `url:"stop_loss,omitempty" json:"stop_loss,omitempty"`
TpTriggerBy string `url:"tp_trigger_by,omitempty" json:"tp_trigger_by,omitempty"`
SlTriggerBy string `url:"sl_trigger_by,omitempty" json:"sl_trigger_by,omitempty"`
PositionIdx int `url:"position_idx,omitempty" json:"position_idx,omitempty"`
}

type PlaceConditionalOrderResponse struct {
domain.LinearBaseResponse `json:",inline"`
Result PlaceConditionalOrderResult `json:"result"`
}

type PlaceConditionalOrderResult struct {
StopOrderID string `json:"stop_order_id"`
UserID string `json:"order_id"`
Symbol string `json:"symbol"`
Side string `json:"side"`
OrderType string `json:"order_type"`
Price float64 `json:"price"`
Qty float64 `json:"qty"`
TimeInForce string `json:"time_in_force"`
OrderStatus string `json:"order_status"`
TriggerPrice float64 `json:"trigger_price"`
OrderLinkID string `json:"order_link_id"`
CreatedTime string `json:"created_time"`
UpdatedTime string `json:"updated_time"`
BasePrice string `json:"base_price"`
TriggerBy string `json:"trigger_by"`
TpTriggerBy string `json:"tp_trigger_by"`
SlTriggerBy string `json:"sl_trigger_by"`
TakeProfit float64 `json:"take_profit"`
StopLoss float64 `json:"stop_loss"`
ReduceOnly bool `json:"reduce_only"`
CloseOnTrigger bool `json:"close_on_trigger"`
PositionIdx int `json:"position_idx"`
}

type GetConditionalOrderParams struct {
StopOrderID string `url:"stop_order_id,omitempty" json:"stop_order_id,omitempty"`
OrderLinkID string `url:"order_link_id,omitempty" json:"order_link_id,omitempty"`
Symbol string `url:"symbol,omitempty" json:"symbol,omitempty"`
StopOrderStatus string `url:"stop_order_status,omitempty" json:"stop_order_status,omitempty"`
Order string `url:"order_status,omitempty" json:"order_status,omitempty"`
Page int `url:"page,omitempty" json:"page,omitempty"`
Limit int `url:"limit,omitempty" json:"limit,omitempty"`
}

type GetConditionalOrderResponse struct {
domain.LinearBaseResponse `json:",inline"`
Result GetConditionalOrderResult `json:"result"`
}

type GetConditionalOrderResult struct {
CurrentPage int `json:"current_page"`
LastPage int `json:"last_page"`
Data []GetConditionalOrderResultData `json:"data"`
}

type GetConditionalOrderResultData struct {
StopOrderID string `json:"stop_order_id"`
UserID string `json:"order_id"`
Symbol string `json:"symbol"`
Side string `json:"side"`
OrderType string `json:"order_type"`
Price float64 `json:"price"`
Qty float64 `json:"qty"`
TimeInForce string `json:"time_in_force"`
OrderStatus string `json:"order_status"`
TriggerPrice float64 `json:"trigger_price"`
OrderLinkID string `json:"order_link_id"`
CreatedTime string `json:"created_time"`
UpdatedTime string `json:"updated_time"`
TakeProfit float64 `json:"take_profit"`
StopLoss float64 `json:"stop_loss"`
TriggerBy string `json:"trigger_by"`
BasePrice string `json:"base_price"`
TpTriggerBy string `json:"tp_trigger_by"`
SlTriggerBy string `json:"sl_trigger_by"`
ReduceOnly bool `json:"reduce_only"`
CloseOnTrigger bool `json:"close_on_trigger"`
}

type CancelConditionalOrderParams struct {
Symbol string `url:"symbol" json:"symbol"`
StopOrderID string `url:"stop_order_id,omitempty" json:"stop_order_id,omitempty"`
OrderLinkID string `url:"order_link_id,omitempty" json:"order_link_id,omitempty"`
}

type CancelConditionalOrderResponse struct {
domain.LinearBaseResponse `json:",inline"`
Result CancelConditionalOrderResult `json:"result"`
}

type CancelConditionalOrderResult struct {
StopOrderID string `json:"stop_order_id"`
}

type CancelAllConditionalOrdersParams struct {
Symbol string `url:"symbol" json:"symbol"`
}

type CancelAllConditionalOrdersResponse struct {
domain.LinearBaseResponse `json:",inline"`
Result []string `json:"result"`
}

type ReplaceConditionalOrderParams struct {
StopOrderID string `url:"stop_order_id,omitempty" json:"stop_order_id,omitempty"`
OrderLinkID string `url:"order_link_id,omitempty" json:"order_link_id,omitempty"`
Symbol string `url:"symbol,omitempty" json:"symbol,omitempty"`
PRQty float64 `url:"p_r_qty,omitempty" json:"p_r_qty,omitempty"`
PRPrice float64 `url:"p_r_price,omitempty" json:"p_r_price,omitempty"`
PRTriggerPrice float64 `url:"p_r_trigger_price,omitempty" json:"p_r_trigger_price,omitempty"`
TakeProfit float64 `url:"take_profit,omitempty" json:"take_profit,omitempty"`
StopLoss float64 `url:"stop_loss,omitempty" json:"stop_loss,omitempty"`
TpTriggerBy string `url:"tp_trigger_by,omitempty" json:"tp_trigger_by,omitempty"`
SlTriggerBy string `url:"sl_trigger_by,omitempty" json:"sl_trigger_by,omitempty"`
}

type ReplaceConditionalOrderResponse struct {
domain.LinearBaseResponse `json:",inline"`
Result ReplaceConditionalOrderResult `json:"result"`
}

type ReplaceConditionalOrderResult struct {
StopOrderID string `json:"stop_order_id"`
}

type QueryConditionalOrderBySymbolParams struct {
Symbol string `url:"symbol" json:"symbol"`
}

type QueryConditionalOrderBySymbolResponse struct {
domain.LinearBaseResponse `json:",inline"`
Result []QueryConditionalOrderBySymbolResult `json:"result"`
}

type QueryConditionalOrderBySymbolResult struct {
StopOrderID string `json:"stop_order_id"`
UserID int `json:"user_id"`
Symbol string `json:"symbol"`
Side string `json:"side"`
OrderType string `json:"order_type"`
Price float64 `json:"price"`
Qty float64 `json:"qty"`
TimeInForce string `json:"time_in_force"`
OrderStatus string `json:"order_status"`
TriggerPrice float64 `json:"trigger_price"`
OrderLinkID string `json:"order_link_id"`
CreatedTime string `json:"created_time"`
UpdatedTime string `json:"updated_time"`
TakeProfit float64 `json:"take_profit"`
StopLoss float64 `json:"stop_loss"`
TpTriggerBy string `json:"tp_trigger_by"`
SlTriggerBy string `json:"sl_trigger_by"`
TriggerBy string `json:"trigger_by"`
}

type QueryConditionalOrderWithIDsParams struct {
Symbol string `url:"symbol" json:"symbol"`
StopOrderID string `url:"stop_order_id,omitempty" json:"stop_order_id,omitempty"`
OrderLinkID string `url:"order_link_id,omitempty" json:"order_link_id,omitempty"`
}

type QueryConditionalOrderWithIDsResponse struct {
domain.LinearBaseResponse `json:",inline"`
Result QueryConditionalOrderWithIDsResult `json:"result"`
}

type QueryConditionalOrderWithIDsResult struct {
StopOrderID string `json:"stop_order_id"`
UserID int `json:"user_id"`
Symbol string `json:"symbol"`
Side string `json:"side"`
OrderType string `json:"order_type"`
Price float64 `json:"price"`
Qty float64 `json:"qty"`
TimeInForce string `json:"time_in_force"`
OrderStatus string `json:"order_status"`
TriggerPrice float64 `json:"trigger_price"`
BasePrice string `json:"base_price"`
OrderLinkID string `json:"order_link_id"`
CreatedTime string `json:"created_time"`
UpdatedTime string `json:"updated_time"`
TakeProfit float64 `json:"take_profit"`
StopLoss float64 `json:"stop_loss"`
TpTriggerBy string `json:"tp_trigger_by"`
SlTriggerBy string `json:"sl_trigger_by"`
TriggerBy string `json:"trigger_by"`
ReduceOnly bool `json:"reduce_only"`
CloseOnTrigger bool `json:"close_on_trigger"`
}
5 changes: 0 additions & 5 deletions rest/linear/account/active_orders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ func TestClient_Linear_Market(t *testing.T) {
if err != nil {
t.Fatalf("failed to get current BTC price: %v", err)
}
// Do we need an error here? since the currentBTC price is always float
preferredBTCBuyPrice, _ := bybit.GetPrecision(*currentBTCPrice - 1000.00)
fmt.Println("preferred BTC buy price:", preferredBTCBuyPrice)

t.Run("Place Active Order - LINEAR", func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -124,7 +121,6 @@ func TestClient_Linear_Market(t *testing.T) {
assert.NotNil(t, response)
}
})

}

func getLinearBTCBuyPriceForTest(client linearRest.Interface) (*float64, error) {
Expand All @@ -142,6 +138,5 @@ func getLinearBTCBuyPriceForTest(client linearRest.Interface) (*float64, error)
if err != nil {
return nil, fmt.Errorf("failed to get current BTC price: %v", err)
}
fmt.Println("current BTC price:", currentBTCPrice)
return &currentBTCPrice, nil
}
64 changes: 64 additions & 0 deletions rest/linear/account/conditional_orders.go
Original file line number Diff line number Diff line change
@@ -1 +1,65 @@
package account

import (
"context"
"net/http"

"github.com/cksidharthan/go-bybit/bybit"
"github.com/cksidharthan/go-bybit/rest/domain/linear"
)

func (c *LinearAccountClient) PlaceConditionalOrder(ctx context.Context, params *linear.PlaceConditionalOrderParams) (res *linear.PlaceConditionalOrderResponse, err error) {
err = c.transporter.SignedRequest(ctx, http.MethodPost, bybit.PrivatePlaceConditionalOrderPath, params, &res)
if err != nil {
return
}
return
}

func (c *LinearAccountClient) GetConditionalOrder(ctx context.Context, params *linear.GetConditionalOrderParams) (res *linear.GetConditionalOrderResponse, err error) {
err = c.transporter.SignedRequest(ctx, http.MethodGet, bybit.PrivateGetConditionalOrderPath, params, &res)
if err != nil {
return
}
return
}

func (c *LinearAccountClient) CancelConditionalOrder(ctx context.Context, params *linear.CancelConditionalOrderParams) (res *linear.CancelConditionalOrderResponse, err error) {
err = c.transporter.SignedRequest(ctx, http.MethodPost, bybit.PrivateCancelConditionalOrderPath, params, &res)
if err != nil {
return
}
return
}

func (c *LinearAccountClient) CancelAllConditionalOrders(ctx context.Context, params *linear.CancelAllConditionalOrdersParams) (res *linear.CancelAllConditionalOrdersResponse, err error) {
err = c.transporter.SignedRequest(ctx, http.MethodPost, bybit.PrivateCancelAllConditionalOrderPath, params, &res)
if err != nil {
return
}
return
}

func (c *LinearAccountClient) ReplaceConditionalOrder(ctx context.Context, params *linear.ReplaceConditionalOrderParams) (res *linear.ReplaceConditionalOrderResponse, err error) {
err = c.transporter.SignedRequest(ctx, http.MethodPost, bybit.PrivateReplaceConditionalOrderPath, params, &res)
if err != nil {
return
}
return
}

func (c *LinearAccountClient) QueryConditionalOrderBySymbol(ctx context.Context, params *linear.QueryConditionalOrderBySymbolParams) (res *linear.QueryConditionalOrderBySymbolResponse, err error) {
err = c.transporter.SignedRequest(ctx, http.MethodGet, bybit.PrivateQueryConditionalOrderPath, params, &res)
if err != nil {
return
}
return
}

func (c *LinearAccountClient) QueryConditionalOrderWithIDs(ctx context.Context, params *linear.QueryConditionalOrderWithIDsParams) (res *linear.QueryConditionalOrderWithIDsResponse, err error) {
err = c.transporter.SignedRequest(ctx, http.MethodGet, bybit.PrivateQueryConditionalOrderPath, params, &res)
if err != nil {
return
}
return
}
Loading