cmd: add get-order cmd

This commit is contained in:
c9s 2022-03-03 00:06:44 +08:00
parent 127de0d81c
commit 688445d7e7
7 changed files with 104 additions and 61 deletions

View File

@ -100,32 +100,57 @@ func NewExchangeStandard(n types.ExchangeName, key, secret, passphrase, subAccou
}
```
## Testing order book stream
## Test Market Data Stream
### Test order book stream
```shell
godotenv -f .env.local -- go run ./cmd/bbgo orderbook --config config/bbgo.yaml --session kucoin --symbol BTCUSDT
```
## Testing user data stream
## Test User Data Stream
```shell
godotenv -f .env.local -- go run ./cmd/bbgo --config config/bbgo.yaml userdatastream --session kucoin
```
### Testing order submit
## Test Restful Endpoints
You can choose the session name to set-up for testing:
```shell
godotenv -f .env.local -- go run ./cmd/bbgo submit-order --session=kucoin --symbol=BTCUSDT --side=buy --price=18000 --quantity=0.001
export BBGO_SESSION=ftx
export BBGO_SESSION=kucoin
export BBGO_SESSION=binance
```
### Testing open orders query
### Test user account balance
```shell
godotenv -f .env.local -- go run ./cmd/bbgo list-orders --session kucoin --symbol=BTCUSDT open
godotenv -f .env.local -- go run ./cmd/bbgo list-orders --session kucoin --symbol=BTCUSDT closed
godotenv -f .env.local -- go run ./cmd/bbgo balances --session $BBGO_SESSION
```
### Testing order cancel
### Test order submit
```shell
godotenv -f .env.local -- go run ./cmd/bbgo submit-order --session $BBGO_SESSION --symbol=BTCUSDT --side=buy --price=18000 --quantity=0.001
```
### Test open orders query
```shell
godotenv -f .env.local -- go run ./cmd/bbgo list-orders --session $BBGO_SESSION --symbol=BTCUSDT open
godotenv -f .env.local -- go run ./cmd/bbgo list-orders --session $BBGO_SESSION --symbol=BTCUSDT closed
```
### Test order status
```shell
godotenv -f .env.local -- go run ./cmd/bbgo get-order --session $BBGO_SESSION --order-id ORDER_ID
```
### Test order cancel
```shell
godotenv -f .env.local -- go run ./cmd/bbgo cancel-order --session kucoin --order-uuid 61c745c44592c200014abdcf

View File

@ -3,9 +3,7 @@ package cmd
import (
"context"
"fmt"
"os"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@ -19,41 +17,19 @@ func init() {
// go run ./cmd/bbgo balances --session=ftx
var balancesCmd = &cobra.Command{
Use: "balances",
Use: "balances --session SESSION",
Short: "Show user account balances",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
configFile, err := cmd.Flags().GetString("config")
if err != nil {
return err
}
if len(configFile) == 0 {
return errors.New("--config option is required")
}
sessionName, err := cmd.Flags().GetString("session")
if err != nil {
return err
}
// if config file exists, use the config loaded from the config file.
// otherwise, use a empty config object
var userConfig *bbgo.Config
if _, err := os.Stat(configFile); err == nil {
// load successfully
userConfig, err = bbgo.Load(configFile, false)
if err != nil {
return err
}
} else if os.IsNotExist(err) {
// config file doesn't exist
userConfig = &bbgo.Config{}
} else {
// other error
return err
if userConfig == nil {
return fmt.Errorf("user config is not loaded")
}
environ := bbgo.NewEnvironment()

View File

@ -19,11 +19,60 @@ import (
"github.com/c9s/bbgo/pkg/types"
)
var getOrderCmd = &cobra.Command{
Use: "get-order --session SESSION --order-id ORDER_ID",
Short: "Get order status",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
if userConfig == nil {
return errors.New("config file is required")
}
environ := bbgo.NewEnvironment()
if err := environ.ConfigureExchangeSessions(userConfig); err != nil {
return err
}
sessionName, err := cmd.Flags().GetString("session")
if err != nil {
return err
}
session, ok := environ.Session(sessionName)
if !ok {
return fmt.Errorf("session %s not found", sessionName)
}
orderID, err := cmd.Flags().GetString("order-id")
if err != nil {
return fmt.Errorf("can't get the symbol from flags: %w", err)
}
service, ok := session.Exchange.(types.ExchangeOrderQueryService)
if !ok {
return fmt.Errorf("query order status is not supported for exchange %T, interface types.ExchangeOrderQueryService is not implemented", session.Exchange)
}
order, err := service.QueryOrder(ctx, types.OrderQuery{
OrderID: orderID,
})
if err != nil {
return err
}
log.Infof("%+v", order)
return nil
},
}
// go run ./cmd/bbgo list-orders [open|closed] --session=ftx --symbol=BTCUSDT
var listOrdersCmd = &cobra.Command{
Use: "list-orders open|closed [--session session]",
Use: "list-orders open|closed --session SESSION --symbol SYMBOL",
Short: "list user's open orders in exchange of a specific trading pair",
Args: cobra.OnlyValidArgs,
Args: cobra.OnlyValidArgs,
// default is open which means we query open orders if you haven't provided args.
ValidArgs: []string{"", "open", "closed"},
SilenceUsage: true,
@ -39,22 +88,10 @@ var listOrdersCmd = &cobra.Command{
return fmt.Errorf("--config option is required")
}
// if config file exists, use the config loaded from the config file.
// otherwise, use a empty config object
var userConfig *bbgo.Config
if _, err := os.Stat(configFile); err == nil {
// load successfully
userConfig, err = bbgo.Load(configFile, false)
if err != nil {
return err
}
} else if os.IsNotExist(err) {
// config file doesn't exist
userConfig = &bbgo.Config{}
} else {
// other error
return err
if userConfig == nil {
return errors.New("config file is required")
}
environ := bbgo.NewEnvironment()
if err := environ.ConfigureExchangeSessions(userConfig); err != nil {
@ -345,6 +382,10 @@ func init() {
listOrdersCmd.Flags().String("session", "", "the exchange session name for sync")
listOrdersCmd.Flags().String("symbol", "", "the trading pair, like btcusdt")
getOrderCmd.Flags().String("session", "", "the exchange session name for sync")
getOrderCmd.Flags().String("symbol", "", "the trading pair, like btcusdt")
getOrderCmd.Flags().String("order-id", "", "order id")
submitOrderCmd.Flags().String("session", "", "the exchange session name for sync")
submitOrderCmd.Flags().String("symbol", "", "the trading pair, like btcusdt")
submitOrderCmd.Flags().String("side", "", "the trading side: buy or sell")
@ -362,6 +403,7 @@ func init() {
executeOrderCmd.Flags().Int("price-ticks", 0, "the number of price tick for the jump spread, default to 0")
RootCmd.AddCommand(listOrdersCmd)
RootCmd.AddCommand(getOrderCmd)
RootCmd.AddCommand(submitOrderCmd)
RootCmd.AddCommand(executeOrderCmd)
}

View File

@ -44,7 +44,7 @@ type Account struct {
Positions []Position `json:"positions"`
}
//go:generate GetRequest -url "api/account" -type GetAccountRequest -responseDataType .Account
//go:generate GetRequest -url "/api/account" -type GetAccountRequest -responseDataType .Account
type GetAccountRequest struct {
client requestgen.AuthenticatedAPIClient
}
@ -55,7 +55,7 @@ func (c *RestClient) NewGetAccountRequest() *GetAccountRequest {
}
}
//go:generate GetRequest -url "api/positions" -type GetPositionsRequest -responseDataType []Position
//go:generate GetRequest -url "/api/positions" -type GetPositionsRequest -responseDataType []Position
type GetPositionsRequest struct {
client requestgen.AuthenticatedAPIClient
}
@ -76,7 +76,7 @@ type Balance struct {
AvailableWithoutBorrow fixedpoint.Value `json:"availableWithoutBorrow"`
}
//go:generate GetRequest -url "api/balances" -type GetBalancesRequest -responseDataType []Balance
//go:generate GetRequest -url "/api/wallet/balances" -type GetBalancesRequest -responseDataType []Balance
type GetBalancesRequest struct {
client requestgen.AuthenticatedAPIClient
}

View File

@ -1,4 +1,4 @@
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Result -url api/account -type GetAccountRequest -responseDataType .Account"; DO NOT EDIT.
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Result -url /api/account -type GetAccountRequest -responseDataType .Account"; DO NOT EDIT.
package ftxapi
@ -91,7 +91,7 @@ func (g *GetAccountRequest) Do(ctx context.Context) (*Account, error) {
var params interface{}
query := url.Values{}
apiURL := "api/account"
apiURL := "/api/account"
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
if err != nil {

View File

@ -1,4 +1,4 @@
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Result -url api/balances -type GetBalancesRequest -responseDataType []Balance"; DO NOT EDIT.
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Result -url /api/wallet/balances -type GetBalancesRequest -responseDataType []Balance"; DO NOT EDIT.
package ftxapi
@ -91,7 +91,7 @@ func (g *GetBalancesRequest) Do(ctx context.Context) ([]Balance, error) {
var params interface{}
query := url.Values{}
apiURL := "api/balances"
apiURL := "/api/wallet/balances"
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
if err != nil {

View File

@ -1,4 +1,4 @@
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Result -url api/positions -type GetPositionsRequest -responseDataType []Position"; DO NOT EDIT.
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Result -url /api/positions -type GetPositionsRequest -responseDataType []Position"; DO NOT EDIT.
package ftxapi
@ -91,7 +91,7 @@ func (g *GetPositionsRequest) Do(ctx context.Context) ([]Position, error) {
var params interface{}
query := url.Values{}
apiURL := "api/positions"
apiURL := "/api/positions"
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
if err != nil {