mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
Merge pull request #1169 from c9s/feature/bitget
WIP: FEATURE: add bitget exchange support
This commit is contained in:
commit
10311f5c93
2
go.mod
2
go.mod
|
@ -78,6 +78,7 @@ require (
|
|||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.12.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dmarkham/enumer v1.5.8 // indirect
|
||||
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
|
@ -110,6 +111,7 @@ require (
|
|||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pascaldekloe/name v1.0.0 // indirect
|
||||
github.com/pelletier/go-toml v1.8.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -145,6 +145,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
|
|||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dmarkham/enumer v1.5.8 h1:fIF11F9l5jyD++YYvxcSH5WgHfeaSGPaN/T4kOQ4qEM=
|
||||
github.com/dmarkham/enumer v1.5.8/go.mod h1:d10o8R3t/gROm2p3BXqTkMt2+HMuxEmWCXzorAruYak=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
@ -532,6 +534,8 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl
|
|||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/name v1.0.0 h1:n7LKFgHixETzxpRv2R77YgPUFo85QHGZKrdaYm7eY5U=
|
||||
github.com/pascaldekloe/name v1.0.0/go.mod h1:Z//MfYJnH4jVpQ9wkclwu2I2MkHmXTlT9wR5UZScttM=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
|
|
|
@ -228,12 +228,16 @@ func (environ *Environment) ConfigureExchangeSessions(userConfig *Config) error
|
|||
func (environ *Environment) AddExchangesByViperKeys() error {
|
||||
for _, n := range types.SupportedExchanges {
|
||||
if viper.IsSet(string(n) + "-api-key") {
|
||||
ex, err := exchange.NewWithEnvVarPrefix(n, "")
|
||||
exMinimal, err := exchange.NewWithEnvVarPrefix(n, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ex, ok := exMinimal.(types.Exchange); ok {
|
||||
environ.AddExchange(n.String(), ex)
|
||||
} else {
|
||||
log.Errorf("exchange %T does not implement types.Exchange", exMinimal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -703,21 +703,39 @@ func (session *ExchangeSession) FindPossibleSymbols() (symbols []string, err err
|
|||
return symbols, nil
|
||||
}
|
||||
|
||||
// newBasicPrivateExchange allocates a basic exchange instance with the user private credentials
|
||||
func (session *ExchangeSession) newBasicPrivateExchange(exchangeName types.ExchangeName) (types.Exchange, error) {
|
||||
var err error
|
||||
var exMinimal types.ExchangeMinimal
|
||||
if session.Key != "" && session.Secret != "" {
|
||||
exMinimal, err = exchange2.New(exchangeName, session.Key, session.Secret, session.Passphrase)
|
||||
} else {
|
||||
exMinimal, err = exchange2.NewWithEnvVarPrefix(exchangeName, session.EnvVarPrefix)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ex, ok := exMinimal.(types.Exchange); ok {
|
||||
return ex, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("exchange %T does not implement types.Exchange", exMinimal)
|
||||
}
|
||||
|
||||
// InitExchange initialize the exchange instance and allocate memory for fields
|
||||
// In this stage, the session var could be loaded from the JSON config, so the pointer fields are still nil
|
||||
// The Init method will be called after this stage, environment.Init will call the session.Init method later.
|
||||
func (session *ExchangeSession) InitExchange(name string, ex types.Exchange) error {
|
||||
var err error
|
||||
var exchangeName = session.ExchangeName
|
||||
|
||||
if ex == nil {
|
||||
if session.PublicOnly {
|
||||
ex, err = exchange2.NewPublic(exchangeName)
|
||||
} else {
|
||||
if session.Key != "" && session.Secret != "" {
|
||||
ex, err = exchange2.NewStandard(exchangeName, session.Key, session.Secret, session.Passphrase, session.SubAccount)
|
||||
} else {
|
||||
ex, err = exchange2.NewWithEnvVarPrefix(exchangeName, session.EnvVarPrefix)
|
||||
}
|
||||
ex, err = session.newBasicPrivateExchange(exchangeName)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
63
pkg/cmd/exchangetest.go
Normal file
63
pkg/cmd/exchangetest.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
//go:build exchangetest
|
||||
// +build exchangetest
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/exchange"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
// go run ./cmd/bbgo kline --exchange=binance --symbol=BTCUSDT
|
||||
var exchangeTestCmd = &cobra.Command{
|
||||
Use: "exchange-test",
|
||||
Short: "test the exchange",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
exchangeNameStr, err := cmd.Flags().GetString("exchange")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exchangeName, err := types.ValidExchangeName(exchangeNameStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exMinimal, err := exchange.NewWithEnvVarPrefix(exchangeName, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("types.ExchangeMinimal: ✅")
|
||||
|
||||
if service, ok := exMinimal.(types.ExchangeAccountService); ok {
|
||||
log.Infof("types.ExchangeAccountService: ✅ (%T)", service)
|
||||
}
|
||||
|
||||
if service, ok := exMinimal.(types.ExchangeMarketDataService); ok {
|
||||
log.Infof("types.ExchangeMarketDataService: ✅ (%T)", service)
|
||||
}
|
||||
|
||||
if ex, ok := exMinimal.(types.Exchange); ok {
|
||||
log.Infof("types.Exchange: ✅ (%T)", ex)
|
||||
}
|
||||
|
||||
_ = ctx
|
||||
// cmdutil.WaitForSignal(ctx, syscall.SIGINT, syscall.SIGTERM)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
exchangeTestCmd.Flags().String("exchange", "", "session name")
|
||||
exchangeTestCmd.MarkFlagRequired("exchange")
|
||||
|
||||
RootCmd.AddCommand(exchangeTestCmd)
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
)
|
||||
|
||||
type CancelOrderBySymbolResponse string
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/trade/cancel-symbol-order" -type CancelOrderBySymbolRequest -responseDataType .CancelOrderBySymbolResponse
|
||||
type CancelOrderBySymbolRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
symbol string `param:"symbol"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewCancelOrderBySymbolRequest() *CancelOrderBySymbolRequest {
|
||||
return &CancelOrderBySymbolRequest{client: c}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/trade/cancel-symbol-order -type CancelOrderBySymbolRequest -responseDataType .CancelOrderBySymbolResponse"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (c *CancelOrderBySymbolRequest) Symbol(symbol string) *CancelOrderBySymbolRequest {
|
||||
c.symbol = symbol
|
||||
return c
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (c *CancelOrderBySymbolRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (c *CancelOrderBySymbolRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := c.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (c *CancelOrderBySymbolRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := c.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if c.isVarSlice(_v) {
|
||||
c.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (c *CancelOrderBySymbolRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := c.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (c *CancelOrderBySymbolRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (c *CancelOrderBySymbolRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (c *CancelOrderBySymbolRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CancelOrderBySymbolRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *CancelOrderBySymbolRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := c.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (c *CancelOrderBySymbolRequest) Do(ctx context.Context) (*CancelOrderBySymbolResponse, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
query, err := c.GetParametersQuery()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiURL := "/api/spot/v1/trade/cancel-symbol-order"
|
||||
|
||||
req, err := c.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := c.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data CancelOrderBySymbolResponse
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
25
pkg/exchange/bitget/bitgetapi/cancel_order_request.go
Normal file
25
pkg/exchange/bitget/bitgetapi/cancel_order_request.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
)
|
||||
|
||||
type CancelOrderResponse struct {
|
||||
OrderId string `json:"orderId"`
|
||||
ClientOrderId string `json:"clientOrderId"`
|
||||
}
|
||||
|
||||
//go:generate PostRequest -url "/api/spot/v1/trade/cancel-order-v2" -type CancelOrderRequest -responseDataType .CancelOrderResponse
|
||||
type CancelOrderRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
symbol string `param:"symbol"`
|
||||
orderId *string `param:"orderId"`
|
||||
clientOrderId *string `param:"clientOid"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewCancelOrderRequest() *CancelOrderRequest {
|
||||
return &CancelOrderRequest{client: c}
|
||||
}
|
177
pkg/exchange/bitget/bitgetapi/cancel_order_request_requestgen.go
Normal file
177
pkg/exchange/bitget/bitgetapi/cancel_order_request_requestgen.go
Normal file
|
@ -0,0 +1,177 @@
|
|||
// Code generated by "requestgen -method POST -responseType .APIResponse -responseDataField Data -url /api/spot/v1/trade/cancel-order-v2 -type CancelOrderRequest -responseDataType .CancelOrderResponse"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (c *CancelOrderRequest) Symbol(symbol string) *CancelOrderRequest {
|
||||
c.symbol = symbol
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CancelOrderRequest) OrderId(orderId string) *CancelOrderRequest {
|
||||
c.orderId = &orderId
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CancelOrderRequest) ClientOrderId(clientOrderId string) *CancelOrderRequest {
|
||||
c.clientOrderId = &clientOrderId
|
||||
return c
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (c *CancelOrderRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (c *CancelOrderRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := c.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
// check orderId field -> json key orderId
|
||||
if c.orderId != nil {
|
||||
orderId := *c.orderId
|
||||
|
||||
// assign parameter of orderId
|
||||
params["orderId"] = orderId
|
||||
} else {
|
||||
}
|
||||
// check clientOrderId field -> json key clientOid
|
||||
if c.clientOrderId != nil {
|
||||
clientOrderId := *c.clientOrderId
|
||||
|
||||
// assign parameter of clientOrderId
|
||||
params["clientOid"] = clientOrderId
|
||||
} else {
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (c *CancelOrderRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := c.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if c.isVarSlice(_v) {
|
||||
c.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (c *CancelOrderRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := c.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (c *CancelOrderRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (c *CancelOrderRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (c *CancelOrderRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CancelOrderRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *CancelOrderRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := c.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (c *CancelOrderRequest) Do(ctx context.Context) (*CancelOrderResponse, error) {
|
||||
|
||||
params, err := c.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/trade/cancel-order-v2"
|
||||
|
||||
req, err := c.client.NewAuthenticatedRequest(ctx, "POST", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := c.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data CancelOrderResponse
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
163
pkg/exchange/bitget/bitgetapi/client.go
Normal file
163
pkg/exchange/bitget/bitgetapi/client.go
Normal file
|
@ -0,0 +1,163 @@
|
|||
package bitgetapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/c9s/requestgen"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const defaultHTTPTimeout = time.Second * 15
|
||||
const RestBaseURL = "https://api.bitget.com"
|
||||
const PublicWebSocketURL = "wss://ws.bitget.com/spot/v1/stream"
|
||||
const PrivateWebSocketURL = "wss://ws.bitget.com/spot/v1/stream"
|
||||
|
||||
type RestClient struct {
|
||||
requestgen.BaseAPIClient
|
||||
|
||||
key, secret, passphrase string
|
||||
}
|
||||
|
||||
func NewClient() *RestClient {
|
||||
u, err := url.Parse(RestBaseURL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &RestClient{
|
||||
BaseAPIClient: requestgen.BaseAPIClient{
|
||||
BaseURL: u,
|
||||
HttpClient: &http.Client{
|
||||
Timeout: defaultHTTPTimeout,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RestClient) Auth(key, secret, passphrase string) {
|
||||
c.key = key
|
||||
c.secret = secret
|
||||
c.passphrase = passphrase
|
||||
}
|
||||
|
||||
// newAuthenticatedRequest creates new http request for authenticated routes.
|
||||
func (c *RestClient) NewAuthenticatedRequest(ctx context.Context, method, refURL string, params url.Values, payload interface{}) (*http.Request, error) {
|
||||
if len(c.key) == 0 {
|
||||
return nil, errors.New("empty api key")
|
||||
}
|
||||
|
||||
if len(c.secret) == 0 {
|
||||
return nil, errors.New("empty api secret")
|
||||
}
|
||||
|
||||
rel, err := url.Parse(refURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if params != nil {
|
||||
rel.RawQuery = params.Encode()
|
||||
}
|
||||
|
||||
pathURL := c.BaseURL.ResolveReference(rel)
|
||||
path := pathURL.Path
|
||||
if rel.RawQuery != "" {
|
||||
path += "?" + rel.RawQuery
|
||||
}
|
||||
|
||||
// See https://bitgetlimited.github.io/apidoc/en/spot/#signature
|
||||
// sign(
|
||||
// timestamp +
|
||||
// method.toUpperCase() +
|
||||
// requestPath + "?" + queryString +
|
||||
// body **string
|
||||
// )
|
||||
// (+ means string concat) encrypt by **HMAC SHA256 **algorithm, and encode the encrypted result through **BASE64.
|
||||
|
||||
// set location to UTC so that it outputs "2020-12-08T09:08:57.715Z"
|
||||
t := time.Now().In(time.UTC)
|
||||
timestamp := strconv.FormatInt(t.UnixMilli(), 10)
|
||||
|
||||
body, err := castPayload(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signKey := timestamp + strings.ToUpper(method) + path + string(body)
|
||||
signature := sign(signKey, c.secret)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, pathURL.String(), bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
req.Header.Add("Accept", "application/json")
|
||||
req.Header.Add("ACCESS-KEY", c.key)
|
||||
req.Header.Add("ACCESS-SIGN", signature)
|
||||
req.Header.Add("ACCESS-TIMESTAMP", timestamp)
|
||||
req.Header.Add("ACCESS-PASSPHRASE", c.passphrase)
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func sign(payload string, secret string) string {
|
||||
var sig = hmac.New(sha256.New, []byte(secret))
|
||||
_, err := sig.Write([]byte(payload))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(sig.Sum(nil))
|
||||
}
|
||||
|
||||
func castPayload(payload interface{}) ([]byte, error) {
|
||||
if payload == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch v := payload.(type) {
|
||||
case string:
|
||||
return []byte(v), nil
|
||||
|
||||
case []byte:
|
||||
return v, nil
|
||||
|
||||
}
|
||||
return json.Marshal(payload)
|
||||
}
|
||||
|
||||
/*
|
||||
sample:
|
||||
|
||||
{
|
||||
"code": "00000",
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"user_id": "714229403",
|
||||
"inviter_id": "682221498",
|
||||
"ips": "172.23.88.91",
|
||||
"authorities": [
|
||||
"trade",
|
||||
"readonly"
|
||||
],
|
||||
"parentId":"566624801",
|
||||
"trader":false
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
type APIResponse struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"msg"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
70
pkg/exchange/bitget/bitgetapi/client_test.go
Normal file
70
pkg/exchange/bitget/bitgetapi/client_test.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/testutil"
|
||||
)
|
||||
|
||||
func getTestClientOrSkip(t *testing.T) *RestClient {
|
||||
if b, _ := strconv.ParseBool(os.Getenv("CI")); b {
|
||||
t.Skip("skip test for CI")
|
||||
}
|
||||
|
||||
key, secret, ok := testutil.IntegrationTestConfigured(t, "BITGET")
|
||||
if !ok {
|
||||
t.Skip("BITGET_* env vars are not configured")
|
||||
return nil
|
||||
}
|
||||
|
||||
client := NewClient()
|
||||
client.Auth(key, secret, os.Getenv("BITGET_API_PASSPHRASE"))
|
||||
return client
|
||||
}
|
||||
|
||||
func TestClient(t *testing.T) {
|
||||
client := getTestClientOrSkip(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("GetAllTickersRequest", func(t *testing.T) {
|
||||
req := client.NewGetAllTickersRequest()
|
||||
tickers, err := req.Do(ctx)
|
||||
assert.NoError(t, err)
|
||||
t.Logf("tickers: %+v", tickers)
|
||||
})
|
||||
|
||||
t.Run("GetTickerRequest", func(t *testing.T) {
|
||||
req := client.NewGetTickerRequest()
|
||||
req.Symbol("BTCUSDT_SPBL")
|
||||
ticker, err := req.Do(ctx)
|
||||
assert.NoError(t, err)
|
||||
t.Logf("ticker: %+v", ticker)
|
||||
})
|
||||
|
||||
t.Run("GetDepthRequest", func(t *testing.T) {
|
||||
req := client.NewGetDepthRequest()
|
||||
req.Symbol("BTCUSDT_SPBL")
|
||||
depth, err := req.Do(ctx)
|
||||
assert.NoError(t, err)
|
||||
t.Logf("depth: %+v", depth)
|
||||
})
|
||||
|
||||
t.Run("GetServerTimeRequest", func(t *testing.T) {
|
||||
req := client.NewGetServerTimeRequest()
|
||||
serverTime, err := req.Do(ctx)
|
||||
assert.NoError(t, err)
|
||||
t.Logf("time: %+v", serverTime)
|
||||
})
|
||||
|
||||
t.Run("GetAccountAssetsRequest", func(t *testing.T) {
|
||||
req := client.NewGetAccountAssetsRequest()
|
||||
assets, err := req.Do(ctx)
|
||||
assert.NoError(t, err)
|
||||
t.Logf("assets: %+v", assets)
|
||||
})
|
||||
}
|
29
pkg/exchange/bitget/bitgetapi/get_account_assets_request.go
Normal file
29
pkg/exchange/bitget/bitgetapi/get_account_assets_request.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type AccountAsset struct {
|
||||
CoinId int64 `json:"coinId"`
|
||||
CoinName string `json:"coinName"`
|
||||
Available fixedpoint.Value `json:"available"`
|
||||
Frozen fixedpoint.Value `json:"frozen"`
|
||||
Lock fixedpoint.Value `json:"lock"`
|
||||
UTime types.MillisecondTimestamp `json:"uTime"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/account/assets" -type GetAccountAssetsRequest -responseDataType []AccountAsset
|
||||
type GetAccountAssetsRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetAccountAssetsRequest() *GetAccountAssetsRequest {
|
||||
return &GetAccountAssetsRequest{client: c}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/account/assets -type GetAccountAssetsRequest -responseDataType []AccountAsset"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetAccountAssetsRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetAccountAssetsRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetAccountAssetsRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetAccountAssetsRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetAccountAssetsRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetAccountAssetsRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetAccountAssetsRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetAccountAssetsRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetAccountAssetsRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetAccountAssetsRequest) Do(ctx context.Context) ([]AccountAsset, error) {
|
||||
|
||||
// no body params
|
||||
var params interface{}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/account/assets"
|
||||
|
||||
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data []AccountAsset
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
24
pkg/exchange/bitget/bitgetapi/get_account_request.go
Normal file
24
pkg/exchange/bitget/bitgetapi/get_account_request.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import "github.com/c9s/requestgen"
|
||||
|
||||
type Account struct {
|
||||
UserId string `json:"user_id"`
|
||||
InviterId string `json:"inviter_id"`
|
||||
Ips string `json:"ips"`
|
||||
Authorities []string `json:"authorities"`
|
||||
ParentId string `json:"parentId"`
|
||||
Trader bool `json:"trader"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/account/getInfo" -type GetAccountRequest -responseDataType .Account
|
||||
type GetAccountRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetAccountRequest() *GetAccountRequest {
|
||||
return &GetAccountRequest{client: c}
|
||||
}
|
139
pkg/exchange/bitget/bitgetapi/get_account_request_requestgen.go
Normal file
139
pkg/exchange/bitget/bitgetapi/get_account_request_requestgen.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/account/getInfo -type GetAccountRequest -responseDataType .Account"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetAccountRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetAccountRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetAccountRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetAccountRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetAccountRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetAccountRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetAccountRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetAccountRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetAccountRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetAccountRequest) Do(ctx context.Context) (*Account, error) {
|
||||
|
||||
// no body params
|
||||
var params interface{}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/account/getInfo"
|
||||
|
||||
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data Account
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
17
pkg/exchange/bitget/bitgetapi/get_all_tickers_request.go
Normal file
17
pkg/exchange/bitget/bitgetapi/get_all_tickers_request.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
)
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/market/tickers" -type GetAllTickersRequest -responseDataType []Ticker
|
||||
type GetAllTickersRequest struct {
|
||||
client requestgen.APIClient
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetAllTickersRequest() *GetAllTickersRequest {
|
||||
return &GetAllTickersRequest{client: c}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/market/tickers -type GetAllTickersRequest -responseDataType []Ticker"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetAllTickersRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetAllTickersRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetAllTickersRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetAllTickersRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetAllTickersRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetAllTickersRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetAllTickersRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetAllTickersRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetAllTickersRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetAllTickersRequest) Do(ctx context.Context) ([]Ticker, error) {
|
||||
|
||||
// no body params
|
||||
var params interface{}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/market/tickers"
|
||||
|
||||
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data []Ticker
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
31
pkg/exchange/bitget/bitgetapi/get_candles_request.go
Normal file
31
pkg/exchange/bitget/bitgetapi/get_candles_request.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type Candle struct {
|
||||
Open fixedpoint.Value `json:"open"`
|
||||
High fixedpoint.Value `json:"high"`
|
||||
Low fixedpoint.Value `json:"low"`
|
||||
Close fixedpoint.Value `json:"close"`
|
||||
QuoteVol fixedpoint.Value `json:"quoteVol"`
|
||||
BaseVol fixedpoint.Value `json:"baseVol"`
|
||||
UsdtVol fixedpoint.Value `json:"usdtVol"`
|
||||
Ts types.MillisecondTimestamp `json:"ts"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/market/candles" -type GetCandlesRequest -responseDataType []Candle
|
||||
type GetCandlesRequest struct {
|
||||
client requestgen.APIClient
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetCandlesRequest() *GetCandlesRequest {
|
||||
return &GetCandlesRequest{client: c}
|
||||
}
|
139
pkg/exchange/bitget/bitgetapi/get_candles_request_requestgen.go
Normal file
139
pkg/exchange/bitget/bitgetapi/get_candles_request_requestgen.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/market/candles -type GetCandlesRequest -responseDataType []Candle"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetCandlesRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetCandlesRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetCandlesRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetCandlesRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetCandlesRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetCandlesRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetCandlesRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetCandlesRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetCandlesRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetCandlesRequest) Do(ctx context.Context) ([]Candle, error) {
|
||||
|
||||
// no body params
|
||||
var params interface{}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/market/candles"
|
||||
|
||||
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data []Candle
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
30
pkg/exchange/bitget/bitgetapi/get_depth_request.go
Normal file
30
pkg/exchange/bitget/bitgetapi/get_depth_request.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type Depth struct {
|
||||
Asks [][]fixedpoint.Value `json:"asks"`
|
||||
Bids [][]fixedpoint.Value `json:"bids"`
|
||||
Timestamp types.MillisecondTimestamp `json:"timestamp"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/market/depth" -type GetDepthRequest -responseDataType .Depth
|
||||
type GetDepthRequest struct {
|
||||
client requestgen.APIClient
|
||||
|
||||
symbol string `param:"symbol"`
|
||||
stepType string `param:"type" default:"step0"`
|
||||
limit *int `param:"limit"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetDepthRequest() *GetDepthRequest {
|
||||
return &GetDepthRequest{client: c}
|
||||
}
|
175
pkg/exchange/bitget/bitgetapi/get_depth_request_requestgen.go
Normal file
175
pkg/exchange/bitget/bitgetapi/get_depth_request_requestgen.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/market/depth -type GetDepthRequest -responseDataType .Depth"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (g *GetDepthRequest) Symbol(symbol string) *GetDepthRequest {
|
||||
g.symbol = symbol
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetDepthRequest) StepType(stepType string) *GetDepthRequest {
|
||||
g.stepType = stepType
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetDepthRequest) Limit(limit int) *GetDepthRequest {
|
||||
g.limit = &limit
|
||||
return g
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetDepthRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetDepthRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := g.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
// check stepType field -> json key type
|
||||
stepType := g.stepType
|
||||
|
||||
// assign parameter of stepType
|
||||
params["type"] = stepType
|
||||
// check limit field -> json key limit
|
||||
if g.limit != nil {
|
||||
limit := *g.limit
|
||||
|
||||
// assign parameter of limit
|
||||
params["limit"] = limit
|
||||
} else {
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetDepthRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetDepthRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetDepthRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetDepthRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetDepthRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetDepthRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetDepthRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetDepthRequest) Do(ctx context.Context) (*Depth, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
query, err := g.GetParametersQuery()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiURL := "/api/spot/v1/market/depth"
|
||||
|
||||
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data Depth
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
43
pkg/exchange/bitget/bitgetapi/get_fills_request.go
Normal file
43
pkg/exchange/bitget/bitgetapi/get_fills_request.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type Fill struct {
|
||||
AccountId string `json:"accountId"`
|
||||
Symbol string `json:"symbol"`
|
||||
OrderId string `json:"orderId"`
|
||||
FillId string `json:"fillId"`
|
||||
OrderType OrderType `json:"orderType"`
|
||||
Side OrderSide `json:"side"`
|
||||
FillPrice fixedpoint.Value `json:"fillPrice"`
|
||||
FillQuantity fixedpoint.Value `json:"fillQuantity"`
|
||||
FillTotalAmount fixedpoint.Value `json:"fillTotalAmount"`
|
||||
CreationTime types.MillisecondTimestamp `json:"cTime"`
|
||||
FeeCurrency string `json:"feeCcy"`
|
||||
Fees fixedpoint.Value `json:"fees"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/trade/fills" -type GetFillsRequest -responseDataType .ServerTime
|
||||
type GetFillsRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
|
||||
// after - order id
|
||||
after *string `param:"after"`
|
||||
|
||||
// before - order id
|
||||
before *string `param:"before"`
|
||||
|
||||
limit *string `param:"limit"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetFillsRequest() *GetFillsRequest {
|
||||
return &GetFillsRequest{client: c}
|
||||
}
|
182
pkg/exchange/bitget/bitgetapi/get_fills_request_requestgen.go
Normal file
182
pkg/exchange/bitget/bitgetapi/get_fills_request_requestgen.go
Normal file
|
@ -0,0 +1,182 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/trade/fills -type GetFillsRequest -responseDataType .ServerTime"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (g *GetFillsRequest) After(after string) *GetFillsRequest {
|
||||
g.after = &after
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetFillsRequest) Before(before string) *GetFillsRequest {
|
||||
g.before = &before
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetFillsRequest) Limit(limit string) *GetFillsRequest {
|
||||
g.limit = &limit
|
||||
return g
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetFillsRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetFillsRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check after field -> json key after
|
||||
if g.after != nil {
|
||||
after := *g.after
|
||||
|
||||
// assign parameter of after
|
||||
params["after"] = after
|
||||
} else {
|
||||
}
|
||||
// check before field -> json key before
|
||||
if g.before != nil {
|
||||
before := *g.before
|
||||
|
||||
// assign parameter of before
|
||||
params["before"] = before
|
||||
} else {
|
||||
}
|
||||
// check limit field -> json key limit
|
||||
if g.limit != nil {
|
||||
limit := *g.limit
|
||||
|
||||
// assign parameter of limit
|
||||
params["limit"] = limit
|
||||
} else {
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetFillsRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetFillsRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetFillsRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetFillsRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetFillsRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetFillsRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetFillsRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetFillsRequest) Do(ctx context.Context) (*types.MillisecondTimestamp, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
query, err := g.GetParametersQuery()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiURL := "/api/spot/v1/trade/fills"
|
||||
|
||||
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data types.MillisecondTimestamp
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
19
pkg/exchange/bitget/bitgetapi/get_open_orders_request.go
Normal file
19
pkg/exchange/bitget/bitgetapi/get_open_orders_request.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
)
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/trade/open-orders" -type GetOpenOrdersRequest -responseDataType []OrderDetail
|
||||
type GetOpenOrdersRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
|
||||
symbol string `param:"symbol"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetOpenOrdersRequest() *GetOpenOrdersRequest {
|
||||
return &GetOpenOrdersRequest{client: c}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/trade/open-orders -type GetOpenOrdersRequest -responseDataType []OrderDetail"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (g *GetOpenOrdersRequest) Symbol(symbol string) *GetOpenOrdersRequest {
|
||||
g.symbol = symbol
|
||||
return g
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetOpenOrdersRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetOpenOrdersRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := g.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetOpenOrdersRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetOpenOrdersRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetOpenOrdersRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetOpenOrdersRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetOpenOrdersRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetOpenOrdersRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetOpenOrdersRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetOpenOrdersRequest) Do(ctx context.Context) ([]OrderDetail, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
query, err := g.GetParametersQuery()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiURL := "/api/spot/v1/trade/open-orders"
|
||||
|
||||
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data []OrderDetail
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
41
pkg/exchange/bitget/bitgetapi/get_order_detail_request.go
Normal file
41
pkg/exchange/bitget/bitgetapi/get_order_detail_request.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type OrderDetail struct {
|
||||
AccountId string `json:"accountId"`
|
||||
Symbol string `json:"symbol"`
|
||||
OrderId string `json:"orderId"`
|
||||
ClientOrderId string `json:"clientOrderId"`
|
||||
Price fixedpoint.Value `json:"price"`
|
||||
Quantity fixedpoint.Value `json:"quantity"`
|
||||
OrderType OrderType `json:"orderType"`
|
||||
Side OrderSide `json:"side"`
|
||||
Status OrderStatus `json:"status"`
|
||||
FillPrice fixedpoint.Value `json:"fillPrice"`
|
||||
FillQuantity fixedpoint.Value `json:"fillQuantity"`
|
||||
FillTotalAmount fixedpoint.Value `json:"fillTotalAmount"`
|
||||
EnterPointSource string `json:"enterPointSource"`
|
||||
CTime types.MillisecondTimestamp `json:"cTime"`
|
||||
}
|
||||
|
||||
//go:generate PostRequest -url "/api/spot/v1/trade/orderInfo" -type GetOrderDetailRequest -responseDataType []OrderDetail
|
||||
type GetOrderDetailRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
|
||||
symbol string `param:"symbol"`
|
||||
orderId *string `param:"orderId"`
|
||||
clientOrderId *string `param:"clientOid"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetOrderDetailRequest() *GetOrderDetailRequest {
|
||||
return &GetOrderDetailRequest{client: c}
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
// Code generated by "requestgen -method POST -responseType .APIResponse -responseDataField Data -url /api/spot/v1/trade/orderInfo -type GetOrderDetailRequest -responseDataType .OrderDetail"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (g *GetOrderDetailRequest) Symbol(symbol string) *GetOrderDetailRequest {
|
||||
g.symbol = symbol
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetOrderDetailRequest) OrderId(orderId string) *GetOrderDetailRequest {
|
||||
g.orderId = &orderId
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetOrderDetailRequest) ClientOrderId(clientOrderId string) *GetOrderDetailRequest {
|
||||
g.clientOrderId = &clientOrderId
|
||||
return g
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetOrderDetailRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetOrderDetailRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := g.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
// check orderId field -> json key orderId
|
||||
if g.orderId != nil {
|
||||
orderId := *g.orderId
|
||||
|
||||
// assign parameter of orderId
|
||||
params["orderId"] = orderId
|
||||
} else {
|
||||
}
|
||||
// check clientOrderId field -> json key clientOid
|
||||
if g.clientOrderId != nil {
|
||||
clientOrderId := *g.clientOrderId
|
||||
|
||||
// assign parameter of clientOrderId
|
||||
params["clientOid"] = clientOrderId
|
||||
} else {
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetOrderDetailRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetOrderDetailRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetOrderDetailRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetOrderDetailRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetOrderDetailRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetOrderDetailRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetOrderDetailRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetOrderDetailRequest) Do(ctx context.Context) (*OrderDetail, error) {
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/trade/orderInfo"
|
||||
|
||||
req, err := g.client.NewAuthenticatedRequest(ctx, "POST", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data OrderDetail
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
27
pkg/exchange/bitget/bitgetapi/get_order_history_request.go
Normal file
27
pkg/exchange/bitget/bitgetapi/get_order_history_request.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
)
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/trade/history" -type GetOrderHistoryRequest -responseDataType []OrderDetail
|
||||
type GetOrderHistoryRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
|
||||
symbol string `param:"symbol"`
|
||||
|
||||
// after - order id
|
||||
after *string `param:"after"`
|
||||
|
||||
// before - order id
|
||||
before *string `param:"before"`
|
||||
|
||||
limit *string `param:"limit"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetOrderHistoryRequest() *GetOrderHistoryRequest {
|
||||
return &GetOrderHistoryRequest{client: c}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/trade/history -type GetOrderHistoryRequest -responseDataType []OrderDetail"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (g *GetOrderHistoryRequest) Symbol(symbol string) *GetOrderHistoryRequest {
|
||||
g.symbol = symbol
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) After(after string) *GetOrderHistoryRequest {
|
||||
g.after = &after
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) Before(before string) *GetOrderHistoryRequest {
|
||||
g.before = &before
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) Limit(limit string) *GetOrderHistoryRequest {
|
||||
g.limit = &limit
|
||||
return g
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetOrderHistoryRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetOrderHistoryRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := g.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
// check after field -> json key after
|
||||
if g.after != nil {
|
||||
after := *g.after
|
||||
|
||||
// assign parameter of after
|
||||
params["after"] = after
|
||||
} else {
|
||||
}
|
||||
// check before field -> json key before
|
||||
if g.before != nil {
|
||||
before := *g.before
|
||||
|
||||
// assign parameter of before
|
||||
params["before"] = before
|
||||
} else {
|
||||
}
|
||||
// check limit field -> json key limit
|
||||
if g.limit != nil {
|
||||
limit := *g.limit
|
||||
|
||||
// assign parameter of limit
|
||||
params["limit"] = limit
|
||||
} else {
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetOrderHistoryRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetOrderHistoryRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetOrderHistoryRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) Do(ctx context.Context) ([]OrderDetail, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
query, err := g.GetParametersQuery()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiURL := "/api/spot/v1/trade/history"
|
||||
|
||||
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data []OrderDetail
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
21
pkg/exchange/bitget/bitgetapi/get_server_time_request.go
Normal file
21
pkg/exchange/bitget/bitgetapi/get_server_time_request.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type ServerTime = types.MillisecondTimestamp
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/public/time" -type GetServerTimeRequest -responseDataType .ServerTime
|
||||
type GetServerTimeRequest struct {
|
||||
client requestgen.APIClient
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetServerTimeRequest() *GetServerTimeRequest {
|
||||
return &GetServerTimeRequest{client: c}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/public/time -type GetServerTimeRequest -responseDataType .ServerTime"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetServerTimeRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetServerTimeRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetServerTimeRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetServerTimeRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetServerTimeRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetServerTimeRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetServerTimeRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetServerTimeRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetServerTimeRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetServerTimeRequest) Do(ctx context.Context) (*types.MillisecondTimestamp, error) {
|
||||
|
||||
// no body params
|
||||
var params interface{}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/public/time"
|
||||
|
||||
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data types.MillisecondTimestamp
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
36
pkg/exchange/bitget/bitgetapi/get_symbols_request.go
Normal file
36
pkg/exchange/bitget/bitgetapi/get_symbols_request.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
)
|
||||
|
||||
type Symbol struct {
|
||||
Symbol string `json:"symbol"`
|
||||
SymbolName string `json:"symbolName"`
|
||||
BaseCoin string `json:"baseCoin"`
|
||||
QuoteCoin string `json:"quoteCoin"`
|
||||
MinTradeAmount fixedpoint.Value `json:"minTradeAmount"`
|
||||
MaxTradeAmount fixedpoint.Value `json:"maxTradeAmount"`
|
||||
TakerFeeRate fixedpoint.Value `json:"takerFeeRate"`
|
||||
MakerFeeRate fixedpoint.Value `json:"makerFeeRate"`
|
||||
PriceScale fixedpoint.Value `json:"priceScale"`
|
||||
QuantityScale fixedpoint.Value `json:"quantityScale"`
|
||||
MinTradeUSDT fixedpoint.Value `json:"minTradeUSDT"`
|
||||
Status string `json:"status"`
|
||||
BuyLimitPriceRatio fixedpoint.Value `json:"buyLimitPriceRatio"`
|
||||
SellLimitPriceRatio fixedpoint.Value `json:"sellLimitPriceRatio"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/public/products" -type GetSymbolsRequest -responseDataType []Symbol
|
||||
type GetSymbolsRequest struct {
|
||||
client requestgen.APIClient
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetSymbolsRequest() *GetSymbolsRequest {
|
||||
return &GetSymbolsRequest{client: c}
|
||||
}
|
139
pkg/exchange/bitget/bitgetapi/get_symbols_request_requestgen.go
Normal file
139
pkg/exchange/bitget/bitgetapi/get_symbols_request_requestgen.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/public/products -type GetSymbolsRequest -responseDataType []Symbol"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetSymbolsRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetSymbolsRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetSymbolsRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetSymbolsRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetSymbolsRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetSymbolsRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetSymbolsRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetSymbolsRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetSymbolsRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetSymbolsRequest) Do(ctx context.Context) ([]Symbol, error) {
|
||||
|
||||
// no body params
|
||||
var params interface{}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/public/products"
|
||||
|
||||
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data []Symbol
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
40
pkg/exchange/bitget/bitgetapi/get_ticker_request.go
Normal file
40
pkg/exchange/bitget/bitgetapi/get_ticker_request.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type Ticker struct {
|
||||
Symbol string `json:"symbol"`
|
||||
High24H fixedpoint.Value `json:"high24h"`
|
||||
Low24H fixedpoint.Value `json:"low24h"`
|
||||
Close fixedpoint.Value `json:"close"`
|
||||
QuoteVol fixedpoint.Value `json:"quoteVol"`
|
||||
BaseVol fixedpoint.Value `json:"baseVol"`
|
||||
UsdtVol fixedpoint.Value `json:"usdtVol"`
|
||||
Ts types.MillisecondTimestamp `json:"ts"`
|
||||
BuyOne fixedpoint.Value `json:"buyOne"`
|
||||
SellOne fixedpoint.Value `json:"sellOne"`
|
||||
BidSz fixedpoint.Value `json:"bidSz"`
|
||||
AskSz fixedpoint.Value `json:"askSz"`
|
||||
OpenUtc0 fixedpoint.Value `json:"openUtc0"`
|
||||
ChangeUtc fixedpoint.Value `json:"changeUtc"`
|
||||
Change fixedpoint.Value `json:"change"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/spot/v1/market/ticker" -type GetTickerRequest -responseDataType .Ticker
|
||||
type GetTickerRequest struct {
|
||||
client requestgen.APIClient
|
||||
|
||||
symbol string `param:"symbol"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewGetTickerRequest() *GetTickerRequest {
|
||||
return &GetTickerRequest{client: c}
|
||||
}
|
152
pkg/exchange/bitget/bitgetapi/get_ticker_request_requestgen.go
Normal file
152
pkg/exchange/bitget/bitgetapi/get_ticker_request_requestgen.go
Normal file
|
@ -0,0 +1,152 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/spot/v1/market/ticker -type GetTickerRequest -responseDataType .Ticker"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (g *GetTickerRequest) Symbol(symbol string) *GetTickerRequest {
|
||||
g.symbol = symbol
|
||||
return g
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (g *GetTickerRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (g *GetTickerRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := g.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (g *GetTickerRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if g.isVarSlice(_v) {
|
||||
g.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (g *GetTickerRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := g.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (g *GetTickerRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (g *GetTickerRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (g *GetTickerRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GetTickerRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GetTickerRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := g.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetTickerRequest) Do(ctx context.Context) (*Ticker, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
query, err := g.GetParametersQuery()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiURL := "/api/spot/v1/market/ticker"
|
||||
|
||||
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := g.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data Ticker
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
29
pkg/exchange/bitget/bitgetapi/place_order_request.go
Normal file
29
pkg/exchange/bitget/bitgetapi/place_order_request.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package bitgetapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import (
|
||||
"github.com/c9s/requestgen"
|
||||
)
|
||||
|
||||
type OrderResponse struct {
|
||||
OrderId string `json:"orderId"`
|
||||
ClientOrderId string `json:"clientOrderId"`
|
||||
}
|
||||
|
||||
//go:generate PostRequest -url "/api/spot/v1/trade/orders" -type PlaceOrderRequest -responseDataType .OrderResponse
|
||||
type PlaceOrderRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
symbol string `param:"symbol"`
|
||||
orderType OrderType `param:"orderType"`
|
||||
side OrderSide `param:"side"`
|
||||
force OrderForce `param:"force"`
|
||||
price string `param:"price"`
|
||||
quantity string `param:"quantity"`
|
||||
clientOrderId *string `param:"clientOrderId"`
|
||||
}
|
||||
|
||||
func (c *RestClient) NewPlaceOrderRequest() *PlaceOrderRequest {
|
||||
return &PlaceOrderRequest{client: c}
|
||||
}
|
247
pkg/exchange/bitget/bitgetapi/place_order_request_requestgen.go
Normal file
247
pkg/exchange/bitget/bitgetapi/place_order_request_requestgen.go
Normal file
|
@ -0,0 +1,247 @@
|
|||
// Code generated by "requestgen -method POST -responseType .APIResponse -responseDataField Data -url /api/spot/v1/trade/orders -type PlaceOrderRequest -responseDataType .OrderResponse"; DO NOT EDIT.
|
||||
|
||||
package bitgetapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (p *PlaceOrderRequest) Symbol(symbol string) *PlaceOrderRequest {
|
||||
p.symbol = symbol
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) OrderType(orderType OrderType) *PlaceOrderRequest {
|
||||
p.orderType = orderType
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) Side(side OrderSide) *PlaceOrderRequest {
|
||||
p.side = side
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) Force(force OrderForce) *PlaceOrderRequest {
|
||||
p.force = force
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) Price(price string) *PlaceOrderRequest {
|
||||
p.price = price
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) Quantity(quantity string) *PlaceOrderRequest {
|
||||
p.quantity = quantity
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) ClientOrderId(clientOrderId string) *PlaceOrderRequest {
|
||||
p.clientOrderId = &clientOrderId
|
||||
return p
|
||||
}
|
||||
|
||||
// GetQueryParameters builds and checks the query parameters and returns url.Values
|
||||
func (p *PlaceOrderRequest) GetQueryParameters() (url.Values, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
query := url.Values{}
|
||||
for _k, _v := range params {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParameters builds and checks the parameters and return the result in a map object
|
||||
func (p *PlaceOrderRequest) GetParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
// check symbol field -> json key symbol
|
||||
symbol := p.symbol
|
||||
|
||||
// assign parameter of symbol
|
||||
params["symbol"] = symbol
|
||||
// check orderType field -> json key orderType
|
||||
orderType := p.orderType
|
||||
|
||||
// TEMPLATE check-valid-values
|
||||
switch orderType {
|
||||
case OrderTypeLimit, OrderTypeMarket:
|
||||
params["orderType"] = orderType
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("orderType value %v is invalid", orderType)
|
||||
|
||||
}
|
||||
// END TEMPLATE check-valid-values
|
||||
|
||||
// assign parameter of orderType
|
||||
params["orderType"] = orderType
|
||||
// check side field -> json key side
|
||||
side := p.side
|
||||
|
||||
// TEMPLATE check-valid-values
|
||||
switch side {
|
||||
case OrderSideBuy, OrderSideSell:
|
||||
params["side"] = side
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("side value %v is invalid", side)
|
||||
|
||||
}
|
||||
// END TEMPLATE check-valid-values
|
||||
|
||||
// assign parameter of side
|
||||
params["side"] = side
|
||||
// check force field -> json key force
|
||||
force := p.force
|
||||
|
||||
// TEMPLATE check-valid-values
|
||||
switch force {
|
||||
case OrderForceGTC, OrderForcePostOnly, OrderForceFOK, OrderForceIOC:
|
||||
params["force"] = force
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("force value %v is invalid", force)
|
||||
|
||||
}
|
||||
// END TEMPLATE check-valid-values
|
||||
|
||||
// assign parameter of force
|
||||
params["force"] = force
|
||||
// check price field -> json key price
|
||||
price := p.price
|
||||
|
||||
// assign parameter of price
|
||||
params["price"] = price
|
||||
// check quantity field -> json key quantity
|
||||
quantity := p.quantity
|
||||
|
||||
// assign parameter of quantity
|
||||
params["quantity"] = quantity
|
||||
// check clientOrderId field -> json key clientOrderId
|
||||
if p.clientOrderId != nil {
|
||||
clientOrderId := *p.clientOrderId
|
||||
|
||||
// assign parameter of clientOrderId
|
||||
params["clientOrderId"] = clientOrderId
|
||||
} else {
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
|
||||
func (p *PlaceOrderRequest) GetParametersQuery() (url.Values, error) {
|
||||
query := url.Values{}
|
||||
|
||||
params, err := p.GetParameters()
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
if p.isVarSlice(_v) {
|
||||
p.iterateSlice(_v, func(it interface{}) {
|
||||
query.Add(_k+"[]", fmt.Sprintf("%v", it))
|
||||
})
|
||||
} else {
|
||||
query.Add(_k, fmt.Sprintf("%v", _v))
|
||||
}
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GetParametersJSON converts the parameters from GetParameters into the JSON format
|
||||
func (p *PlaceOrderRequest) GetParametersJSON() ([]byte, error) {
|
||||
params, err := p.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(params)
|
||||
}
|
||||
|
||||
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
|
||||
func (p *PlaceOrderRequest) GetSlugParameters() (map[string]interface{}, error) {
|
||||
var params = map[string]interface{}{}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) applySlugsToUrl(url string, slugs map[string]string) string {
|
||||
for _k, _v := range slugs {
|
||||
needleRE := regexp.MustCompile(":" + _k + "\\b")
|
||||
url = needleRE.ReplaceAllString(url, _v)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
|
||||
sliceValue := reflect.ValueOf(slice)
|
||||
for _i := 0; _i < sliceValue.Len(); _i++ {
|
||||
it := sliceValue.Index(_i).Interface()
|
||||
_f(it)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) isVarSlice(_v interface{}) bool {
|
||||
rt := reflect.TypeOf(_v)
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) GetSlugsMap() (map[string]string, error) {
|
||||
slugs := map[string]string{}
|
||||
params, err := p.GetSlugParameters()
|
||||
if err != nil {
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
for _k, _v := range params {
|
||||
slugs[_k] = fmt.Sprintf("%v", _v)
|
||||
}
|
||||
|
||||
return slugs, nil
|
||||
}
|
||||
|
||||
func (p *PlaceOrderRequest) Do(ctx context.Context) (*OrderResponse, error) {
|
||||
|
||||
params, err := p.GetParameters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := url.Values{}
|
||||
|
||||
apiURL := "/api/spot/v1/trade/orders"
|
||||
|
||||
req, err := p.client.NewAuthenticatedRequest(ctx, "POST", apiURL, query, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := p.client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse APIResponse
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data OrderResponse
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
}
|
41
pkg/exchange/bitget/bitgetapi/types.go
Normal file
41
pkg/exchange/bitget/bitgetapi/types.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package bitgetapi
|
||||
|
||||
type SideType string
|
||||
|
||||
const (
|
||||
SideTypeBuy SideType = "buy"
|
||||
SideTypeSell SideType = "sell"
|
||||
)
|
||||
|
||||
type OrderType string
|
||||
|
||||
const (
|
||||
OrderTypeLimit OrderType = "limit"
|
||||
OrderTypeMarket OrderType = "market"
|
||||
)
|
||||
|
||||
type OrderSide string
|
||||
|
||||
const (
|
||||
OrderSideBuy OrderSide = "buy"
|
||||
OrderSideSell OrderSide = "sell"
|
||||
)
|
||||
|
||||
type OrderForce string
|
||||
|
||||
const (
|
||||
OrderForceGTC OrderForce = "normal"
|
||||
OrderForcePostOnly OrderForce = "post_only"
|
||||
OrderForceFOK OrderForce = "fok"
|
||||
OrderForceIOC OrderForce = "ioc"
|
||||
)
|
||||
|
||||
type OrderStatus string
|
||||
|
||||
const (
|
||||
OrderStatusInit OrderStatus = "init"
|
||||
OrderStatusNew OrderStatus = "new"
|
||||
OrderStatusPartialFill OrderStatus = "partial_fill"
|
||||
OrderStatusFullFill OrderStatus = "full_fill"
|
||||
OrderStatusCancelled OrderStatus = "cancelled"
|
||||
)
|
45
pkg/exchange/bitget/exchange.go
Normal file
45
pkg/exchange/bitget/exchange.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package bitget
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/exchange/bitget/bitgetapi"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
const ID = "bitget"
|
||||
|
||||
const PlatformToken = "BGB"
|
||||
|
||||
var log = logrus.WithFields(logrus.Fields{
|
||||
"exchange": ID,
|
||||
})
|
||||
|
||||
type Exchange struct {
|
||||
key, secret, passphrase string
|
||||
|
||||
client *bitgetapi.RestClient
|
||||
}
|
||||
|
||||
func New(key, secret, passphrase string) *Exchange {
|
||||
client := bitgetapi.NewClient()
|
||||
|
||||
if len(key) > 0 && len(secret) > 0 {
|
||||
client.Auth(key, secret, passphrase)
|
||||
}
|
||||
|
||||
return &Exchange{
|
||||
key: key,
|
||||
secret: secret,
|
||||
passphrase: passphrase,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Exchange) Name() types.ExchangeName {
|
||||
return types.ExchangeBitget
|
||||
}
|
||||
|
||||
func (e *Exchange) PlatformFeeCurrency() string {
|
||||
return PlatformToken
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/exchange/binance"
|
||||
"github.com/c9s/bbgo/pkg/exchange/bitget"
|
||||
"github.com/c9s/bbgo/pkg/exchange/kucoin"
|
||||
"github.com/c9s/bbgo/pkg/exchange/max"
|
||||
"github.com/c9s/bbgo/pkg/exchange/okex"
|
||||
|
@ -13,10 +14,19 @@ import (
|
|||
)
|
||||
|
||||
func NewPublic(exchangeName types.ExchangeName) (types.Exchange, error) {
|
||||
return NewStandard(exchangeName, "", "", "", "")
|
||||
exMinimal, err := New(exchangeName, "", "", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ex, ok := exMinimal.(types.Exchange); ok {
|
||||
return ex, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("exchange %T does not implement types.Exchange", exMinimal)
|
||||
}
|
||||
|
||||
func NewStandard(n types.ExchangeName, key, secret, passphrase, subAccount string) (types.Exchange, error) {
|
||||
func New(n types.ExchangeName, key, secret, passphrase string) (types.ExchangeMinimal, error) {
|
||||
switch n {
|
||||
|
||||
case types.ExchangeBinance:
|
||||
|
@ -31,13 +41,18 @@ func NewStandard(n types.ExchangeName, key, secret, passphrase, subAccount strin
|
|||
case types.ExchangeKucoin:
|
||||
return kucoin.New(key, secret, passphrase), nil
|
||||
|
||||
case types.ExchangeBitget:
|
||||
return bitget.New(key, secret, passphrase), nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported exchange: %v", n)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func NewWithEnvVarPrefix(n types.ExchangeName, varPrefix string) (types.Exchange, error) {
|
||||
// NewWithEnvVarPrefix allocate and initialize the exchange instance with the given environment variable prefix
|
||||
// When the varPrefix is a empty string, the default exchange name will be used as the prefix
|
||||
func NewWithEnvVarPrefix(n types.ExchangeName, varPrefix string) (types.ExchangeMinimal, error) {
|
||||
if len(varPrefix) == 0 {
|
||||
varPrefix = n.String()
|
||||
}
|
||||
|
@ -51,11 +66,5 @@ func NewWithEnvVarPrefix(n types.ExchangeName, varPrefix string) (types.Exchange
|
|||
}
|
||||
|
||||
passphrase := os.Getenv(varPrefix + "_API_PASSPHRASE")
|
||||
subAccount := os.Getenv(varPrefix + "_SUBACCOUNT")
|
||||
return NewStandard(n, key, secret, passphrase, subAccount)
|
||||
}
|
||||
|
||||
// New constructor exchange object from viper config.
|
||||
func New(n types.ExchangeName) (types.Exchange, error) {
|
||||
return NewWithEnvVarPrefix(n, "")
|
||||
return New(n, key, secret, passphrase)
|
||||
}
|
||||
|
|
|
@ -17,14 +17,6 @@ func (s *AccountService) NewListSubAccountsRequest() *ListSubAccountsRequest {
|
|||
return &ListSubAccountsRequest{client: s.client}
|
||||
}
|
||||
|
||||
func (s *AccountService) NewListAccountsRequest() *ListAccountsRequest {
|
||||
return &ListAccountsRequest{client: s.client}
|
||||
}
|
||||
|
||||
func (s *AccountService) NewGetAccountRequest(accountID string) *GetAccountRequest {
|
||||
return &GetAccountRequest{client: s.client, accountID: accountID}
|
||||
}
|
||||
|
||||
type SubAccount struct {
|
||||
UserID string `json:"userId"`
|
||||
Name string `json:"subName"`
|
||||
|
@ -45,14 +37,3 @@ type Account struct {
|
|||
Available fixedpoint.Value `json:"available"`
|
||||
Holds fixedpoint.Value `json:"holds"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/v1/accounts" -type ListAccountsRequest -responseDataType []Account
|
||||
type ListAccountsRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/v1/accounts/:accountID" -type GetAccountRequest -responseDataType .Account
|
||||
type GetAccountRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
accountID string `param:"accountID,slug"`
|
||||
}
|
||||
|
|
16
pkg/exchange/kucoin/kucoinapi/get_account_request.go
Normal file
16
pkg/exchange/kucoin/kucoinapi/get_account_request.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package kucoinapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import "github.com/c9s/requestgen"
|
||||
|
||||
//go:generate GetRequest -url "/api/v1/accounts/:accountID" -type GetAccountRequest -responseDataType .Account
|
||||
type GetAccountRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
accountID string `param:"accountID,slug"`
|
||||
}
|
||||
|
||||
func (s *AccountService) NewGetAccountRequest(accountID string) *GetAccountRequest {
|
||||
return &GetAccountRequest{client: s.client, accountID: accountID}
|
||||
}
|
15
pkg/exchange/kucoin/kucoinapi/list_accounts_request.go
Normal file
15
pkg/exchange/kucoin/kucoinapi/list_accounts_request.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package kucoinapi
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
import "github.com/c9s/requestgen"
|
||||
|
||||
//go:generate GetRequest -url "/api/v1/accounts" -type ListAccountsRequest -responseDataType []Account
|
||||
type ListAccountsRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
}
|
||||
|
||||
func (s *AccountService) NewListAccountsRequest() *ListAccountsRequest {
|
||||
return &ListAccountsRequest{client: s.client}
|
||||
}
|
|
@ -17,11 +17,13 @@ import (
|
|||
|
||||
var marketDataLimiter = rate.NewLimiter(rate.Every(time.Second/10), 1)
|
||||
|
||||
// OKB is the platform currency of OKEx, pre-allocate static string here
|
||||
const OKB = "OKB"
|
||||
const ID = "okex"
|
||||
|
||||
// PlatformToken is the platform currency of OKEx, pre-allocate static string here
|
||||
const PlatformToken = "OKB"
|
||||
|
||||
var log = logrus.WithFields(logrus.Fields{
|
||||
"exchange": "okex",
|
||||
"exchange": ID,
|
||||
})
|
||||
|
||||
type Exchange struct {
|
||||
|
@ -39,7 +41,6 @@ func New(key, secret, passphrase string) *Exchange {
|
|||
|
||||
return &Exchange{
|
||||
key: key,
|
||||
// pragma: allowlist nextline secret
|
||||
secret: secret,
|
||||
passphrase: passphrase,
|
||||
client: client,
|
||||
|
@ -131,7 +132,7 @@ func (e *Exchange) QueryTickers(ctx context.Context, symbols ...string) (map[str
|
|||
}
|
||||
|
||||
func (e *Exchange) PlatformFeeCurrency() string {
|
||||
return OKB
|
||||
return PlatformToken
|
||||
}
|
||||
|
||||
func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
|
||||
|
|
|
@ -44,6 +44,7 @@ const (
|
|||
ExchangeBinance ExchangeName = "binance"
|
||||
ExchangeOKEx ExchangeName = "okex"
|
||||
ExchangeKucoin ExchangeName = "kucoin"
|
||||
ExchangeBitget ExchangeName = "bitget"
|
||||
ExchangeBacktest ExchangeName = "backtest"
|
||||
)
|
||||
|
||||
|
@ -52,47 +53,52 @@ var SupportedExchanges = []ExchangeName{
|
|||
ExchangeBinance,
|
||||
ExchangeOKEx,
|
||||
ExchangeKucoin,
|
||||
ExchangeBitget,
|
||||
// note: we are not using "backtest"
|
||||
}
|
||||
|
||||
func ValidExchangeName(a string) (ExchangeName, error) {
|
||||
switch strings.ToLower(a) {
|
||||
case "max":
|
||||
return ExchangeMax, nil
|
||||
case "binance", "bn":
|
||||
return ExchangeBinance, nil
|
||||
case "okex":
|
||||
return ExchangeOKEx, nil
|
||||
case "kucoin":
|
||||
return ExchangeKucoin, nil
|
||||
aa := strings.ToLower(a)
|
||||
for _, n := range SupportedExchanges {
|
||||
if string(n) == aa {
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("invalid exchange name: %s", a)
|
||||
}
|
||||
|
||||
type ExchangeMinimal interface {
|
||||
Name() ExchangeName
|
||||
PlatformFeeCurrency() string
|
||||
}
|
||||
|
||||
//go:generate mockgen -destination=mocks/mock_exchange.go -package=mocks . Exchange
|
||||
type Exchange interface {
|
||||
Name() ExchangeName
|
||||
|
||||
PlatformFeeCurrency() string
|
||||
|
||||
ExchangeMinimal
|
||||
ExchangeMarketDataService
|
||||
|
||||
ExchangeAccountService
|
||||
ExchangeTradeService
|
||||
}
|
||||
|
||||
// ExchangeBasic is the new type for replacing the original Exchange interface
|
||||
type ExchangeBasic = Exchange
|
||||
|
||||
// ExchangeOrderQueryService provides an interface for querying the order status via order ID or client order ID
|
||||
//
|
||||
//go:generate mockgen -destination=mocks/mock_exchange_order_query.go -package=mocks . ExchangeOrderQueryService
|
||||
type ExchangeOrderQueryService interface {
|
||||
QueryOrder(ctx context.Context, q OrderQuery) (*Order, error)
|
||||
QueryOrderTrades(ctx context.Context, q OrderQuery) ([]Trade, error)
|
||||
}
|
||||
|
||||
type ExchangeTradeService interface {
|
||||
type ExchangeAccountService interface {
|
||||
QueryAccount(ctx context.Context) (*Account, error)
|
||||
|
||||
QueryAccountBalances(ctx context.Context) (BalanceMap, error)
|
||||
}
|
||||
|
||||
type ExchangeTradeService interface {
|
||||
SubmitOrder(ctx context.Context, order SubmitOrder) (createdOrder *Order, err error)
|
||||
|
||||
QueryOpenOrders(ctx context.Context, symbol string) (orders []Order, err error)
|
||||
|
|
Loading…
Reference in New Issue
Block a user