mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-14 11:03:53 +00:00
pkg/exchange: add marketunit for submit order
This commit is contained in:
parent
d48fa7c202
commit
6f7e02daef
|
@ -12,7 +12,7 @@ type PlaceOrderResponse struct {
|
|||
OrderLinkId string `json:"orderLinkId"`
|
||||
}
|
||||
|
||||
//go:generate PostRequest -url "/v5/order/create" -type PlaceOrderRequest -responseDataType .PlaceOrderResponse
|
||||
//go:generate PostRequest -url "/v5/order/create" -type PlaceOrderRequest -responseDataType .PlaceOrderResponse -rateLimiter 5+15/1s
|
||||
type PlaceOrderRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
|
||||
|
@ -23,6 +23,8 @@ type PlaceOrderRequest struct {
|
|||
qty string `param:"qty"`
|
||||
orderLinkId string `param:"orderLinkId"`
|
||||
timeInForce TimeInForce `param:"timeInForce"`
|
||||
// Select the unit for qty when create Spot market orders for UTA account
|
||||
marketUnit *MarketUnit `param:"marketUnit"`
|
||||
|
||||
isLeverage *bool `param:"isLeverage"`
|
||||
price *string `param:"price"`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "requestgen -method POST -responseType .APIResponse -responseDataField Result -url /v5/order/create -type PlaceOrderRequest -responseDataType .PlaceOrderResponse"; DO NOT EDIT.
|
||||
// Code generated by "requestgen -method POST -responseType .APIResponse -responseDataField Result -url /v5/order/create -type PlaceOrderRequest -responseDataType .PlaceOrderResponse -rateLimiter 5+15/1s"; DO NOT EDIT.
|
||||
|
||||
package bybitapi
|
||||
|
||||
|
@ -6,11 +6,14 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"golang.org/x/time/rate"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var PlaceOrderRequestLimiter = rate.NewLimiter(15.000000150000002, 5)
|
||||
|
||||
func (p *PlaceOrderRequest) Category(category Category) *PlaceOrderRequest {
|
||||
p.category = category
|
||||
return p
|
||||
|
@ -46,6 +49,11 @@ func (p *PlaceOrderRequest) TimeInForce(timeInForce TimeInForce) *PlaceOrderRequ
|
|||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) MarketUnit(marketUnit MarketUnit) *PlaceOrderRequest {
|
||||
p.marketUnit = &marketUnit
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) IsLeverage(isLeverage bool) *PlaceOrderRequest {
|
||||
p.isLeverage = &isLeverage
|
||||
return p
|
||||
|
@ -245,6 +253,25 @@ func (p *PlaceOrderRequest) GetParameters() (map[string]interface{}, error) {
|
|||
|
||||
// assign parameter of timeInForce
|
||||
params["timeInForce"] = timeInForce
|
||||
// check marketUnit field -> json key marketUnit
|
||||
if p.marketUnit != nil {
|
||||
marketUnit := *p.marketUnit
|
||||
|
||||
// TEMPLATE check-valid-values
|
||||
switch marketUnit {
|
||||
case MarketUnitBase, MarketUnitQuote:
|
||||
params["marketUnit"] = marketUnit
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("marketUnit value %v is invalid", marketUnit)
|
||||
|
||||
}
|
||||
// END TEMPLATE check-valid-values
|
||||
|
||||
// assign parameter of marketUnit
|
||||
params["marketUnit"] = marketUnit
|
||||
} else {
|
||||
}
|
||||
// check isLeverage field -> json key isLeverage
|
||||
if p.isLeverage != nil {
|
||||
isLeverage := *p.isLeverage
|
||||
|
@ -503,6 +530,9 @@ func (p *PlaceOrderRequest) GetPath() string {
|
|||
|
||||
// Do generates the request object and send the request object to the API endpoint
|
||||
func (p *PlaceOrderRequest) Do(ctx context.Context) (*PlaceOrderResponse, error) {
|
||||
if err := PlaceOrderRequestLimiter.Wait(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
params, err := p.GetParameters()
|
||||
if err != nil {
|
||||
|
@ -525,15 +555,29 @@ func (p *PlaceOrderRequest) Do(ctx context.Context) (*PlaceOrderResponse, error)
|
|||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
|
||||
type responseUnmarshaler interface {
|
||||
Unmarshal(data []byte) error
|
||||
}
|
||||
|
||||
if unmarshaler, ok := interface{}(&apiResponse).(responseUnmarshaler); ok {
|
||||
if err := unmarshaler.Unmarshal(response.Body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// The line below checks the content type, however, some API server might not send the correct content type header,
|
||||
// Hence, this is commented for backward compatibility
|
||||
// response.IsJSON()
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
type responseValidator interface {
|
||||
Validate() error
|
||||
}
|
||||
validator, ok := interface{}(apiResponse).(responseValidator)
|
||||
if ok {
|
||||
|
||||
if validator, ok := interface{}(&apiResponse).(responseValidator); ok {
|
||||
if err := validator.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -128,3 +128,10 @@ const (
|
|||
type AccountType string
|
||||
|
||||
const AccountTypeSpot AccountType = "SPOT"
|
||||
|
||||
type MarketUnit string
|
||||
|
||||
const (
|
||||
MarketUnitBase MarketUnit = "baseCoin"
|
||||
MarketUnitQuote MarketUnit = "quoteCoin"
|
||||
)
|
||||
|
|
|
@ -272,23 +272,18 @@ func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (*t
|
|||
return nil, err
|
||||
}
|
||||
req.Side(side)
|
||||
req.Qty(order.Market.FormatQuantity(order.Quantity))
|
||||
|
||||
// set quantity
|
||||
orderQty := order.Quantity
|
||||
// if the order is market buy, the quantity is quote coin, instead of base coin. so we need to convert it.
|
||||
if order.Type == types.OrderTypeMarket && order.Side == types.SideTypeBuy {
|
||||
ticker, err := e.QueryTicker(ctx, order.Market.Symbol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderQty = order.Quantity.Mul(ticker.Buy)
|
||||
}
|
||||
req.Qty(order.Market.FormatQuantity(orderQty))
|
||||
|
||||
// set price
|
||||
switch order.Type {
|
||||
case types.OrderTypeLimit:
|
||||
case types.OrderTypeStopLimit, types.OrderTypeLimit, types.OrderTypeLimitMaker:
|
||||
req.Price(order.Market.FormatPrice(order.Price))
|
||||
case types.OrderTypeMarket:
|
||||
// Because our order.Quantity unit is base coin, so we indicate the target currency to Base.
|
||||
if order.Side == types.SideTypeBuy {
|
||||
req.MarketUnit(bybitapi.MarketUnitBase)
|
||||
} else {
|
||||
req.MarketUnit(bybitapi.MarketUnitQuote)
|
||||
}
|
||||
}
|
||||
|
||||
// set timeInForce
|
||||
|
@ -309,9 +304,6 @@ func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (*t
|
|||
req.OrderLinkId(order.ClientOrderID)
|
||||
}
|
||||
|
||||
if err := orderRateLimiter.Wait(ctx); err != nil {
|
||||
return nil, fmt.Errorf("place order rate limiter wait error: %w", err)
|
||||
}
|
||||
timeNow := time.Now()
|
||||
res, err := req.Do(ctx)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue
Block a user