okex: fix okex order cancellation

This commit is contained in:
c9s 2021-05-28 03:05:59 +08:00
parent 29304d14ba
commit b430128ba1
6 changed files with 80 additions and 27 deletions

View File

@ -278,7 +278,7 @@ const stateKey = "state-v1"
var log = logrus.WithField("strategy", ID)
func init() {
bbgo.RegisterStrategy(ID, &Strategy{})
bbgo.RegisterStrategy(ID, &Strategy{})
}
```
@ -288,12 +288,12 @@ Implement the strategy methods:
package newstrategy
func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: "2m"})
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: "2m"})
}
func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
// ....
return nil
// ....
return nil
}
```
@ -370,6 +370,23 @@ Or you can build your own wrapper binary via:
bbgo build --config config/bbgo.yaml
```
## Command Usages
### Submitting Orders to a specific exchagne session
```shell
bbgo submit-order --session=okex --symbol=OKBUSDT --side=buy --price=10.0 --quantity=1
```
### Listing Open Orders of a specific exchange session
```sh
bbgo list-orders open --session=okex --symbol=OKBUSDT
bbgo list-orders open --session=ftx --symbol=FTTUSDT
bbgo list-orders open --session=max --symbol=MAXUSDT
bbgo list-orders open --session=binance --symbol=BNBUSDT
```
## Dynamic Injection
In order to minimize the strategy code, bbgo supports dynamic dependency injection.

View File

@ -19,15 +19,16 @@ type advancedOrderCancelApi interface {
}
func init() {
CancelCmd.Flags().String("session", "", "session to execute cancel orders")
CancelCmd.Flags().String("symbol", "", "symbol to cancel orders")
CancelCmd.Flags().Int64("group-id", 0, "groupID to cancel orders")
CancelCmd.Flags().Bool("all", false, "cancel all orders")
RootCmd.AddCommand(CancelCmd)
cancelOrderCmd.Flags().String("session", "", "session to execute cancel orders")
cancelOrderCmd.Flags().String("symbol", "", "symbol to cancel orders")
cancelOrderCmd.Flags().Int64("group-id", 0, "group ID to cancel orders")
cancelOrderCmd.Flags().Uint64("order-id", 0, "order ID to cancel orders")
cancelOrderCmd.Flags().Bool("all", false, "cancel all orders")
RootCmd.AddCommand(cancelOrderCmd)
}
var CancelCmd = &cobra.Command{
Use: "cancel",
var cancelOrderCmd = &cobra.Command{
Use: "cancel-order",
Short: "cancel orders",
Long: "this command can cancel orders from exchange",
@ -48,6 +49,11 @@ var CancelCmd = &cobra.Command{
return err
}
orderID, err := cmd.Flags().GetUint64("order-id")
if err != nil {
return err
}
all, err := cmd.Flags().GetBool("all")
if err != nil {
return err
@ -84,13 +90,32 @@ var CancelCmd = &cobra.Command{
var sessions = environ.Sessions()
if n, err := cmd.Flags().GetString("session"); err == nil && len(n) > 0 {
ses, ok := sessions[n]
sessionName, err := cmd.Flags().GetString("session")
if err != nil {
return err
}
if len(sessionName) > 0 {
ses, ok := sessions[sessionName]
if !ok {
return fmt.Errorf("session %s not found", n)
return fmt.Errorf("session %s not found", sessionName)
}
sessions = map[string]*bbgo.ExchangeSession{n: ses}
if orderID > 0 {
logrus.Infof("canceling order by the given order id %d", orderID)
err := ses.Exchange.CancelOrders(ctx, types.Order{
SubmitOrder: types.SubmitOrder{
Symbol: symbol,
},
OrderID: orderID,
})
if err != nil {
return err
}
return nil
}
sessions = map[string]*bbgo.ExchangeSession{sessionName: ses}
}
for sessionID, session := range sessions {

View File

@ -20,9 +20,9 @@ import (
"github.com/c9s/bbgo/pkg/util"
)
// go run ./cmd/bbgo listorders [open|closed] --session=ftx --symbol=BTC/USDT
// go run ./cmd/bbgo list-orders [open|closed] --session=ftx --symbol=BTCUSDT
var listOrdersCmd = &cobra.Command{
Use: "listorders [status]",
Use: "list-orders [status]",
Args: cobra.OnlyValidArgs,
// default is open which means we query open orders if you haven't provided args.
ValidArgs: []string{"", "open", "closed"},
@ -260,7 +260,7 @@ var executeOrderCmd = &cobra.Command{
},
}
// go run ./cmd/bbgo submit-order --session=ftx --symbol=BTC/USDT --side=buy --price=<price> --quantity=<quantity>
// go run ./cmd/bbgo submit-order --session=ftx --symbol=BTCUSDT --side=buy --price=<price> --quantity=<quantity>
var submitOrderCmd = &cobra.Command{
Use: "submit-order",
SilenceUsage: true,
@ -313,6 +313,11 @@ var submitOrderCmd = &cobra.Command{
return fmt.Errorf("session %s not found", sessionName)
}
market, ok := session.Market(symbol)
if !ok {
return fmt.Errorf("market definition %s not found", symbol)
}
so := types.SubmitOrder{
ClientOrderID: uuid.New().String(),
Symbol: symbol,
@ -322,9 +327,10 @@ var submitOrderCmd = &cobra.Command{
QuantityString: quantity,
Price: util.MustParseFloat(price),
PriceString: price,
Market: types.Market{Symbol: symbol},
Market: market,
TimeInForce: "GTC",
}
co, err := session.Exchange.SubmitOrders(ctx, so)
if err != nil {
return err

View File

@ -9,6 +9,7 @@ import (
"github.com/c9s/bbgo/pkg/exchange/okex/okexapi"
"github.com/c9s/bbgo/pkg/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@ -241,9 +242,17 @@ func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders [
func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) error {
var reqs []*okexapi.CancelOrderRequest
for _, order := range orders {
if len(order.Symbol) == 0 {
return errors.New("symbol is required for canceling an okex order")
}
req := e.client.TradeService.NewCancelOrderRequest()
req.InstrumentID(toLocalSymbol(order.Symbol))
req.OrderID(strconv.FormatUint(order.OrderID, 10))
req.ClientOrderID(order.ClientOrderID)
if len(order.ClientOrderID) > 0 {
req.ClientOrderID(order.ClientOrderID)
}
reqs = append(reqs, req)
}

View File

@ -261,7 +261,7 @@ func (r *BatchCancelOrderRequest) Add(reqs ...*CancelOrderRequest) *BatchCancelO
return r
}
func (r *BatchCancelOrderRequest) Do(ctx context.Context) (*OrderResponse, error) {
func (r *BatchCancelOrderRequest) Do(ctx context.Context) ([]OrderResponse, error) {
var parameterList []map[string]interface{}
for _, req := range r.reqs {
@ -288,11 +288,7 @@ func (r *BatchCancelOrderRequest) Do(ctx context.Context) (*OrderResponse, error
return nil, err
}
if len(orderResponse.Data) == 0 {
return nil, errors.New("order create error")
}
return &orderResponse.Data[0], nil
return orderResponse.Data, nil
}
type BatchPlaceOrderRequest struct {

View File

@ -169,7 +169,7 @@ func (o Order) Backup() SubmitOrder {
}
func (o Order) String() string {
return fmt.Sprintf("ORDER %s %s %s %f/%f @ %f -> %s", o.Exchange.String(), o.Symbol, o.Side, o.ExecutedQuantity, o.Quantity, o.Price, o.Status)
return fmt.Sprintf("ORDER %s %d %s %s %f/%f @ %f -> %s", o.Exchange.String(), o.OrderID, o.Symbol, o.Side, o.ExecutedQuantity, o.Quantity, o.Price, o.Status)
}
// PlainText is used for telegram-styled messages