mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
ftx: implement query open orders
This commit is contained in:
parent
3676450e4b
commit
6599f276db
65
pkg/cmd/orders.go
Normal file
65
pkg/cmd/orders.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
// go run ./cmd/bbgo orders [open|closed] --session=ftx --symbol=BTC/USDT
|
||||
var ordersCmd = &cobra.Command{
|
||||
Use: "orders [status]",
|
||||
Args: cobra.OnlyValidArgs,
|
||||
// default is open which means we query open orders if you haven't provided args.
|
||||
ValidArgs: []string{"", "open", "closed"},
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
ctx := context.Background()
|
||||
session, err := cmd.Flags().GetString("session")
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get session from flags: %w", err)
|
||||
}
|
||||
ex, err := newExchange(session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
symbol, err := cmd.Flags().GetString("symbol")
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get the symbol from flags: %w", err)
|
||||
}
|
||||
if symbol == "" {
|
||||
return fmt.Errorf("symbol is not found")
|
||||
}
|
||||
|
||||
status := "open"
|
||||
if len(args) != 0 {
|
||||
status = args[0]
|
||||
}
|
||||
|
||||
var os []types.Order
|
||||
switch status {
|
||||
case "open":
|
||||
os, err = ex.QueryOpenOrders(ctx, symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "closed":
|
||||
default:
|
||||
return fmt.Errorf("invalid status %s", status)
|
||||
}
|
||||
log.Infof("%s orders: %+v", status, os)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
ordersCmd.Flags().String("session", "", "the exchange session name for sync")
|
||||
ordersCmd.Flags().String("symbol", "", "the trading pair, like btcusdt")
|
||||
|
||||
RootCmd.AddCommand(ordersCmd)
|
||||
}
|
|
@ -102,7 +102,21 @@ func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder
|
|||
}
|
||||
|
||||
func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error) {
|
||||
panic("implement me")
|
||||
resp, err := e.rest.OpenOrders(ctx, symbol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !resp.Success {
|
||||
return nil, fmt.Errorf("ftx returns querying open orders failure")
|
||||
}
|
||||
for _, r := range resp.Result {
|
||||
o, err := toGlobalOrderFromOpenOrder(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orders = append(orders, o)
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since, until time.Time, lastOrderID uint64) (orders []types.Order, err error) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
|
||||
type restRequest struct {
|
||||
*balanceRequest
|
||||
*orderRequest
|
||||
|
||||
key, secret string
|
||||
// Optional sub-account name
|
||||
|
@ -42,6 +43,7 @@ func newRestRequest(c *http.Client, baseURL *url.URL) *restRequest {
|
|||
}
|
||||
|
||||
r.balanceRequest = &balanceRequest{restRequest: r}
|
||||
r.orderRequest = &orderRequest{restRequest: r}
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -75,6 +77,7 @@ func (r *restRequest) buildURL() (*url.URL, error) {
|
|||
}
|
||||
|
||||
func (r *restRequest) Payloads(payloads map[string]interface{}) *restRequest {
|
||||
r.p = make(map[string]interface{})
|
||||
for k, v := range payloads {
|
||||
r.p[k] = v
|
||||
}
|
||||
|
|
30
pkg/exchange/ftx/rest_order_request.go
Normal file
30
pkg/exchange/ftx/rest_order_request.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package ftx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type orderRequest struct {
|
||||
*restRequest
|
||||
}
|
||||
|
||||
func (r *orderRequest) OpenOrders(ctx context.Context, market string) (orders, error) {
|
||||
resp, err := r.
|
||||
Method("GET").
|
||||
ReferenceURL("api/orders").
|
||||
Payloads(map[string]interface{}{"market": market}).
|
||||
DoAuthenticatedRequest(ctx)
|
||||
|
||||
if err != nil {
|
||||
return orders{}, err
|
||||
}
|
||||
|
||||
var o orders
|
||||
if err := json.Unmarshal(resp.Body, &o); err != nil {
|
||||
return orders{}, fmt.Errorf("failed to unmarshal open orders response body to json: %w", err)
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package ftx
|
||||
|
||||
import "time"
|
||||
|
||||
type balances struct {
|
||||
Success bool `json:"Success"`
|
||||
|
||||
|
@ -9,3 +11,29 @@ type balances struct {
|
|||
Total float64 `json:"total"`
|
||||
} `json:"result"`
|
||||
}
|
||||
|
||||
type orders struct {
|
||||
Success bool `json:"Success"`
|
||||
|
||||
Result []order `json:"result"`
|
||||
}
|
||||
|
||||
type order struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
FilledSize float64 `json:"filledSize"`
|
||||
// Future field is not defined in the response format table but in the response example.
|
||||
Future string `json:"future"`
|
||||
ID int64 `json:"id"`
|
||||
Market string `json:"market"`
|
||||
Price float64 `json:"price"`
|
||||
AvgFillPrice float64 `json:"avgFillPrice"`
|
||||
RemainingSize float64 `json:"remainingSize"`
|
||||
Side string `json:"side"`
|
||||
Size float64 `json:"size"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
Ioc bool `json:"ioc"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
ClientId string `json:"clientId"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user