mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
binance: add SubmitFuturesOrder and related conversions
This commit is contained in:
parent
36c6d39612
commit
d3526b2c71
|
@ -161,6 +161,28 @@ func toLocalOrderType(orderType types.OrderType) (binance.OrderType, error) {
|
|||
return "", fmt.Errorf("can not convert to local order, order type %s not supported", orderType)
|
||||
}
|
||||
|
||||
func toLocalFuturesOrderType(orderType types.OrderType) (futures.OrderType, error) {
|
||||
switch orderType {
|
||||
|
||||
// case types.OrderTypeLimitMaker:
|
||||
// return futures.OrderTypeLimitMaker, nil //TODO
|
||||
|
||||
case types.OrderTypeLimit:
|
||||
return futures.OrderTypeLimit, nil
|
||||
|
||||
// case types.OrderTypeStopLimit:
|
||||
// return futures.OrderTypeStopLossLimit, nil //TODO
|
||||
|
||||
// case types.OrderTypeStopMarket:
|
||||
// return futures.OrderTypeStopLoss, nil //TODO
|
||||
|
||||
case types.OrderTypeMarket:
|
||||
return futures.OrderTypeMarket, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("can not convert to local order, order type %s not supported", orderType)
|
||||
}
|
||||
|
||||
func toGlobalOrders(binanceOrders []*binance.Order) (orders []types.Order, err error) {
|
||||
for _, binanceOrder := range binanceOrders {
|
||||
order, err := toGlobalOrder(binanceOrder, false)
|
||||
|
@ -174,6 +196,19 @@ func toGlobalOrders(binanceOrders []*binance.Order) (orders []types.Order, err e
|
|||
return orders, err
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrders(futuresOrders []*futures.Order) (orders []types.Order, err error) {
|
||||
for _, futuresOrder := range futuresOrders {
|
||||
order, err := toGlobalFuturesOrder(futuresOrder, false)
|
||||
if err != nil {
|
||||
return orders, err
|
||||
}
|
||||
|
||||
orders = append(orders, *order)
|
||||
}
|
||||
|
||||
return orders, err
|
||||
}
|
||||
|
||||
func toGlobalOrder(binanceOrder *binance.Order, isMargin bool) (*types.Order, error) {
|
||||
return &types.Order{
|
||||
SubmitOrder: types.SubmitOrder{
|
||||
|
@ -197,6 +232,31 @@ func toGlobalOrder(binanceOrder *binance.Order, isMargin bool) (*types.Order, er
|
|||
}, nil
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrder(futuresOrder *futures.Order, isMargin bool) (*types.Order, error) {
|
||||
return &types.Order{
|
||||
SubmitOrder: types.SubmitOrder{
|
||||
ClientOrderID: futuresOrder.ClientOrderID,
|
||||
Symbol: futuresOrder.Symbol,
|
||||
Side: toGlobalFuturesSideType(futuresOrder.Side),
|
||||
Type: toGlobalFuturesOrderType(futuresOrder.Type),
|
||||
ReduceOnly: futuresOrder.ReduceOnly,
|
||||
ClosePosition: futuresOrder.ClosePosition,
|
||||
Quantity: util.MustParseFloat(futuresOrder.OrigQuantity),
|
||||
Price: util.MustParseFloat(futuresOrder.Price),
|
||||
TimeInForce: string(futuresOrder.TimeInForce),
|
||||
},
|
||||
Exchange: types.ExchangeBinance,
|
||||
// IsWorking: futuresOrder.IsWorking,
|
||||
OrderID: uint64(futuresOrder.OrderID),
|
||||
Status: toGlobalFuturesOrderStatus(futuresOrder.Status),
|
||||
ExecutedQuantity: util.MustParseFloat(futuresOrder.ExecutedQuantity),
|
||||
CreationTime: types.Time(millisecondTime(futuresOrder.Time)),
|
||||
UpdateTime: types.Time(millisecondTime(futuresOrder.UpdateTime)),
|
||||
IsMargin: isMargin,
|
||||
// IsIsolated: futuresOrder.IsIsolated,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func millisecondTime(t int64) time.Time {
|
||||
return time.Unix(0, t*int64(time.Millisecond))
|
||||
}
|
||||
|
|
|
@ -600,6 +600,95 @@ func (e *Exchange) submitMarginOrder(ctx context.Context, order types.SubmitOrde
|
|||
return createdOrder, err
|
||||
}
|
||||
|
||||
func (e *Exchange) submitFuturesOrder(ctx context.Context, order types.SubmitOrder) (*types.Order, error) {
|
||||
orderType, err := toLocalFuturesOrderType(order.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := e.futuresClient.NewCreateOrderService().
|
||||
Symbol(order.Symbol).
|
||||
Type(orderType).
|
||||
Side(futures.SideType(order.Side))
|
||||
|
||||
clientOrderID := newSpotClientOrderID(order.ClientOrderID)
|
||||
if len(clientOrderID) > 0 {
|
||||
req.NewClientOrderID(clientOrderID)
|
||||
}
|
||||
|
||||
// use response result format
|
||||
req.NewOrderResponseType(futures.NewOrderRespTypeRESULT)
|
||||
// if e.IsIsolatedFutures {
|
||||
// req.IsIsolated(e.IsIsolatedFutures)
|
||||
// }
|
||||
|
||||
if len(order.QuantityString) > 0 {
|
||||
req.Quantity(order.QuantityString)
|
||||
} else if order.Market.Symbol != "" {
|
||||
req.Quantity(order.Market.FormatQuantity(order.Quantity))
|
||||
} else {
|
||||
req.Quantity(strconv.FormatFloat(order.Quantity, 'f', 8, 64))
|
||||
}
|
||||
|
||||
// set price field for limit orders
|
||||
switch order.Type {
|
||||
case types.OrderTypeStopLimit, types.OrderTypeLimit, types.OrderTypeLimitMaker:
|
||||
if len(order.PriceString) > 0 {
|
||||
req.Price(order.PriceString)
|
||||
} else if order.Market.Symbol != "" {
|
||||
req.Price(order.Market.FormatPrice(order.Price))
|
||||
}
|
||||
}
|
||||
|
||||
// set stop price
|
||||
switch order.Type {
|
||||
|
||||
case types.OrderTypeStopLimit, types.OrderTypeStopMarket:
|
||||
if len(order.StopPriceString) == 0 {
|
||||
return nil, fmt.Errorf("stop price string can not be empty")
|
||||
}
|
||||
|
||||
req.StopPrice(order.StopPriceString)
|
||||
}
|
||||
|
||||
// could be IOC or FOK
|
||||
if len(order.TimeInForce) > 0 {
|
||||
// TODO: check the TimeInForce value
|
||||
req.TimeInForce(futures.TimeInForceType(order.TimeInForce))
|
||||
} else {
|
||||
switch order.Type {
|
||||
case types.OrderTypeLimit, types.OrderTypeStopLimit:
|
||||
req.TimeInForce(futures.TimeInForceTypeGTC)
|
||||
}
|
||||
}
|
||||
|
||||
response, err := req.Do(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Infof("futures order creation response: %+v", response)
|
||||
|
||||
createdOrder, err := toGlobalFuturesOrder(&futures.Order{
|
||||
Symbol: response.Symbol,
|
||||
OrderID: response.OrderID,
|
||||
ClientOrderID: response.ClientOrderID,
|
||||
Price: response.Price,
|
||||
OrigQuantity: response.OrigQuantity,
|
||||
ExecutedQuantity: response.ExecutedQuantity,
|
||||
// CummulativeQuoteQuantity: response.CummulativeQuoteQuantity,
|
||||
Status: response.Status,
|
||||
TimeInForce: response.TimeInForce,
|
||||
Type: response.Type,
|
||||
Side: response.Side,
|
||||
// UpdateTime: response.TransactTime,
|
||||
// Time: response.TransactTime,
|
||||
// IsIsolated: response.IsIsolated,
|
||||
}, true)
|
||||
|
||||
return createdOrder, err
|
||||
}
|
||||
|
||||
// BBGO is a broker on Binance
|
||||
const spotBrokerID = "NSUYEBKM"
|
||||
|
||||
|
@ -725,6 +814,8 @@ func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder
|
|||
var createdOrder *types.Order
|
||||
if e.IsMargin {
|
||||
createdOrder, err = e.submitMarginOrder(ctx, order)
|
||||
} else if e.IsFutures {
|
||||
createdOrder, err = e.submitFuturesOrder(ctx, order)
|
||||
} else {
|
||||
createdOrder, err = e.submitSpotOrder(ctx, order)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user