max: use v3/withdrawals apis

This commit is contained in:
c9s 2024-08-02 15:20:28 +08:00
parent 089e69a221
commit 97336912e5
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
9 changed files with 213 additions and 42 deletions

View File

@ -201,14 +201,14 @@ type Withdraw struct {
Notes string `json:"notes"` Notes string `json:"notes"`
} }
//go:generate GetRequest -url "v2/withdrawals" -type GetWithdrawHistoryRequest -responseType []Withdraw //go:generate GetRequest -url "v3/withdrawals" -type GetWithdrawHistoryRequest -responseType []Withdraw
type GetWithdrawHistoryRequest struct { type GetWithdrawHistoryRequest struct {
client requestgen.AuthenticatedAPIClient client requestgen.AuthenticatedAPIClient
currency string `param:"currency"` currency *string `param:"currency"`
state *string `param:"state"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
from *time.Time `param:"from,seconds"` // seconds from *time.Time `param:"from,seconds"` // seconds
to *time.Time `param:"to,seconds"` // seconds to *time.Time `param:"to,seconds"` // seconds
state *string `param:"state"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
limit *int `param:"limit"` limit *int `param:"limit"`
} }

View File

@ -119,13 +119,21 @@ func (g *GetAccountRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil return slugs, nil
} }
// GetPath returns the request path of the API
func (g *GetAccountRequest) GetPath() string {
return "v2/members/accounts/:currency"
}
// Do generates the request object and send the request object to the API endpoint
func (g *GetAccountRequest) Do(ctx context.Context) (*Account, error) { func (g *GetAccountRequest) Do(ctx context.Context) (*Account, error) {
// no body params // no body params
var params interface{} var params interface{}
query := url.Values{} query := url.Values{}
apiURL := "v2/members/accounts/:currency" var apiURL string
apiURL = g.GetPath()
slugs, err := g.GetSlugsMap() slugs, err := g.GetSlugsMap()
if err != nil { if err != nil {
return nil, err return nil, err
@ -144,8 +152,32 @@ func (g *GetAccountRequest) Do(ctx context.Context) (*Account, error) {
} }
var apiResponse Account var apiResponse Account
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err type responseUnmarshaler interface {
Unmarshal(data []byte) error
}
if unmarshaler, ok := interface{}(&apiResponse).(responseUnmarshaler); ok {
if err := unmarshaler.Unmarshal(response.Body); err != nil {
return nil, err
}
} else {
// The line below checks the content type, however, some API server might not send the correct content type header,
// Hence, this is commented for backward compatibility
// response.IsJSON()
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
}
type responseValidator interface {
Validate() error
}
if validator, ok := interface{}(&apiResponse).(responseValidator); ok {
if err := validator.Validate(); err != nil {
return nil, err
}
} }
return &apiResponse, nil return &apiResponse, nil
} }

View File

@ -109,13 +109,21 @@ func (g *GetAccountsRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil return slugs, nil
} }
// GetPath returns the request path of the API
func (g *GetAccountsRequest) GetPath() string {
return "v2/members/accounts"
}
// Do generates the request object and send the request object to the API endpoint
func (g *GetAccountsRequest) Do(ctx context.Context) ([]Account, error) { func (g *GetAccountsRequest) Do(ctx context.Context) ([]Account, error) {
// no body params // no body params
var params interface{} var params interface{}
query := url.Values{} query := url.Values{}
apiURL := "v2/members/accounts" var apiURL string
apiURL = g.GetPath()
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params) req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
if err != nil { if err != nil {
@ -128,8 +136,32 @@ func (g *GetAccountsRequest) Do(ctx context.Context) ([]Account, error) {
} }
var apiResponse []Account var apiResponse []Account
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err type responseUnmarshaler interface {
Unmarshal(data []byte) error
}
if unmarshaler, ok := interface{}(&apiResponse).(responseUnmarshaler); ok {
if err := unmarshaler.Unmarshal(response.Body); err != nil {
return nil, err
}
} else {
// The line below checks the content type, however, some API server might not send the correct content type header,
// Hence, this is commented for backward compatibility
// response.IsJSON()
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
}
type responseValidator interface {
Validate() error
}
if validator, ok := interface{}(&apiResponse).(responseValidator); ok {
if err := validator.Validate(); err != nil {
return nil, err
}
} }
return apiResponse, nil return apiResponse, nil
} }

View File

@ -178,6 +178,12 @@ func (g *GetDepositHistoryRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil return slugs, nil
} }
// GetPath returns the request path of the API
func (g *GetDepositHistoryRequest) GetPath() string {
return "v2/deposits"
}
// Do generates the request object and send the request object to the API endpoint
func (g *GetDepositHistoryRequest) Do(ctx context.Context) ([]Deposit, error) { func (g *GetDepositHistoryRequest) Do(ctx context.Context) ([]Deposit, error) {
// empty params for GET operation // empty params for GET operation
@ -187,7 +193,9 @@ func (g *GetDepositHistoryRequest) Do(ctx context.Context) ([]Deposit, error) {
return nil, err return nil, err
} }
apiURL := "v2/deposits" var apiURL string
apiURL = g.GetPath()
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params) req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
if err != nil { if err != nil {
@ -200,8 +208,32 @@ func (g *GetDepositHistoryRequest) Do(ctx context.Context) ([]Deposit, error) {
} }
var apiResponse []Deposit var apiResponse []Deposit
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err type responseUnmarshaler interface {
Unmarshal(data []byte) error
}
if unmarshaler, ok := interface{}(&apiResponse).(responseUnmarshaler); ok {
if err := unmarshaler.Unmarshal(response.Body); err != nil {
return nil, err
}
} else {
// The line below checks the content type, however, some API server might not send the correct content type header,
// Hence, this is commented for backward compatibility
// response.IsJSON()
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
}
type responseValidator interface {
Validate() error
}
if validator, ok := interface{}(&apiResponse).(responseValidator); ok {
if err := validator.Validate(); err != nil {
return nil, err
}
} }
return apiResponse, nil return apiResponse, nil
} }

View File

@ -109,13 +109,21 @@ func (g *GetVipLevelRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil return slugs, nil
} }
// GetPath returns the request path of the API
func (g *GetVipLevelRequest) GetPath() string {
return "v2/members/vip_level"
}
// Do generates the request object and send the request object to the API endpoint
func (g *GetVipLevelRequest) Do(ctx context.Context) (*VipLevel, error) { func (g *GetVipLevelRequest) Do(ctx context.Context) (*VipLevel, error) {
// no body params // no body params
var params interface{} var params interface{}
query := url.Values{} query := url.Values{}
apiURL := "v2/members/vip_level" var apiURL string
apiURL = g.GetPath()
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params) req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
if err != nil { if err != nil {
@ -128,8 +136,32 @@ func (g *GetVipLevelRequest) Do(ctx context.Context) (*VipLevel, error) {
} }
var apiResponse VipLevel var apiResponse VipLevel
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err type responseUnmarshaler interface {
Unmarshal(data []byte) error
}
if unmarshaler, ok := interface{}(&apiResponse).(responseUnmarshaler); ok {
if err := unmarshaler.Unmarshal(response.Body); err != nil {
return nil, err
}
} else {
// The line below checks the content type, however, some API server might not send the correct content type header,
// Hence, this is commented for backward compatibility
// response.IsJSON()
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
}
type responseValidator interface {
Validate() error
}
if validator, ok := interface{}(&apiResponse).(responseValidator); ok {
if err := validator.Validate(); err != nil {
return nil, err
}
} }
return &apiResponse, nil return &apiResponse, nil
} }

View File

@ -1,4 +1,4 @@
// Code generated by "requestgen -method GET -url v2/withdrawals -type GetWithdrawHistoryRequest -responseType []Withdraw"; DO NOT EDIT. // Code generated by "requestgen -method GET -url v3/withdrawals -type GetWithdrawHistoryRequest -responseType []Withdraw"; DO NOT EDIT.
package max package max
@ -14,7 +14,12 @@ import (
) )
func (g *GetWithdrawHistoryRequest) Currency(currency string) *GetWithdrawHistoryRequest { func (g *GetWithdrawHistoryRequest) Currency(currency string) *GetWithdrawHistoryRequest {
g.currency = currency g.currency = &currency
return g
}
func (g *GetWithdrawHistoryRequest) State(state string) *GetWithdrawHistoryRequest {
g.state = &state
return g return g
} }
@ -28,11 +33,6 @@ func (g *GetWithdrawHistoryRequest) To(to time.Time) *GetWithdrawHistoryRequest
return g return g
} }
func (g *GetWithdrawHistoryRequest) State(state string) *GetWithdrawHistoryRequest {
g.state = &state
return g
}
func (g *GetWithdrawHistoryRequest) Limit(limit int) *GetWithdrawHistoryRequest { func (g *GetWithdrawHistoryRequest) Limit(limit int) *GetWithdrawHistoryRequest {
g.limit = &limit g.limit = &limit
return g return g
@ -54,10 +54,21 @@ func (g *GetWithdrawHistoryRequest) GetQueryParameters() (url.Values, error) {
func (g *GetWithdrawHistoryRequest) GetParameters() (map[string]interface{}, error) { func (g *GetWithdrawHistoryRequest) GetParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{} var params = map[string]interface{}{}
// check currency field -> json key currency // check currency field -> json key currency
currency := g.currency if g.currency != nil {
currency := *g.currency
// assign parameter of currency // assign parameter of currency
params["currency"] = currency params["currency"] = currency
} else {
}
// check state field -> json key state
if g.state != nil {
state := *g.state
// assign parameter of state
params["state"] = state
} else {
}
// check from field -> json key from // check from field -> json key from
if g.from != nil { if g.from != nil {
from := *g.from from := *g.from
@ -76,14 +87,6 @@ func (g *GetWithdrawHistoryRequest) GetParameters() (map[string]interface{}, err
params["to"] = strconv.FormatInt(to.Unix(), 10) params["to"] = strconv.FormatInt(to.Unix(), 10)
} else { } else {
} }
// check state field -> json key state
if g.state != nil {
state := *g.state
// assign parameter of state
params["state"] = state
} else {
}
// check limit field -> json key limit // check limit field -> json key limit
if g.limit != nil { if g.limit != nil {
limit := *g.limit limit := *g.limit
@ -175,6 +178,12 @@ func (g *GetWithdrawHistoryRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil return slugs, nil
} }
// GetPath returns the request path of the API
func (g *GetWithdrawHistoryRequest) GetPath() string {
return "v3/withdrawals"
}
// Do generates the request object and send the request object to the API endpoint
func (g *GetWithdrawHistoryRequest) Do(ctx context.Context) ([]Withdraw, error) { func (g *GetWithdrawHistoryRequest) Do(ctx context.Context) ([]Withdraw, error) {
// empty params for GET operation // empty params for GET operation
@ -184,7 +193,9 @@ func (g *GetWithdrawHistoryRequest) Do(ctx context.Context) ([]Withdraw, error)
return nil, err return nil, err
} }
apiURL := "v2/withdrawals" var apiURL string
apiURL = g.GetPath()
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params) req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
if err != nil { if err != nil {
@ -197,8 +208,32 @@ func (g *GetWithdrawHistoryRequest) Do(ctx context.Context) ([]Withdraw, error)
} }
var apiResponse []Withdraw var apiResponse []Withdraw
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err type responseUnmarshaler interface {
Unmarshal(data []byte) error
}
if unmarshaler, ok := interface{}(&apiResponse).(responseUnmarshaler); ok {
if err := unmarshaler.Unmarshal(response.Body); err != nil {
return nil, err
}
} else {
// The line below checks the content type, however, some API server might not send the correct content type header,
// Hence, this is commented for backward compatibility
// response.IsJSON()
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
}
type responseValidator interface {
Validate() error
}
if validator, ok := interface{}(&apiResponse).(responseValidator); ok {
if err := validator.Validate(); err != nil {
return nil, err
}
} }
return apiResponse, nil return apiResponse, nil
} }

View File

@ -28,7 +28,7 @@ type SimplePriceResolver struct {
mu sync.Mutex mu sync.Mutex
} }
func NewPriceMap(markets types.MarketMap) *SimplePriceResolver { func NewSimplePriceResolver(markets types.MarketMap) *SimplePriceResolver {
return &SimplePriceResolver{ return &SimplePriceResolver{
markets: markets, markets: markets,
symbolPrices: make(map[string]fixedpoint.Value), symbolPrices: make(map[string]fixedpoint.Value),

View File

@ -38,7 +38,7 @@ func TestSimplePriceResolver(t *testing.T) {
} }
t.Run("direct reference", func(t *testing.T) { t.Run("direct reference", func(t *testing.T) {
pm := NewPriceMap(markets) pm := NewSimplePriceResolver(markets)
pm.UpdateFromTrade(types.Trade{ pm.UpdateFromTrade(types.Trade{
Symbol: "BTCUSDT", Symbol: "BTCUSDT",
Price: Number(48000.0), Price: Number(48000.0),
@ -69,7 +69,7 @@ func TestSimplePriceResolver(t *testing.T) {
}) })
t.Run("simple reference", func(t *testing.T) { t.Run("simple reference", func(t *testing.T) {
pm := NewPriceMap(markets) pm := NewSimplePriceResolver(markets)
pm.UpdateFromTrade(types.Trade{ pm.UpdateFromTrade(types.Trade{
Symbol: "BTCUSDT", Symbol: "BTCUSDT",
Price: Number(48000.0), Price: Number(48000.0),
@ -90,7 +90,7 @@ func TestSimplePriceResolver(t *testing.T) {
}) })
t.Run("crypto reference", func(t *testing.T) { t.Run("crypto reference", func(t *testing.T) {
pm := NewPriceMap(markets) pm := NewSimplePriceResolver(markets)
pm.UpdateFromTrade(types.Trade{ pm.UpdateFromTrade(types.Trade{
Symbol: "BTCUSDT", Symbol: "BTCUSDT",
Price: Number(52000.0), Price: Number(52000.0),
@ -111,7 +111,7 @@ func TestSimplePriceResolver(t *testing.T) {
}) })
t.Run("inverse reference", func(t *testing.T) { t.Run("inverse reference", func(t *testing.T) {
pm := NewPriceMap(markets) pm := NewSimplePriceResolver(markets)
pm.UpdateFromTrade(types.Trade{ pm.UpdateFromTrade(types.Trade{
Symbol: "BTCTWD", Symbol: "BTCTWD",
Price: Number(1536000.0), Price: Number(1536000.0),
@ -128,7 +128,7 @@ func TestSimplePriceResolver(t *testing.T) {
}) })
t.Run("inverse reference", func(t *testing.T) { t.Run("inverse reference", func(t *testing.T) {
pm := NewPriceMap(markets) pm := NewSimplePriceResolver(markets)
pm.UpdateFromTrade(types.Trade{ pm.UpdateFromTrade(types.Trade{
Symbol: "BTCTWD", Symbol: "BTCTWD",
Price: Number(1536000.0), Price: Number(1536000.0),

View File

@ -14,6 +14,7 @@ import (
"github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/core" "github.com/c9s/bbgo/pkg/core"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/priceresolver"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -56,6 +57,8 @@ type Strategy struct {
faultBalanceRecords map[string][]TimeBalance faultBalanceRecords map[string][]TimeBalance
priceResolver *priceresolver.SimplePriceResolver
sessions map[string]*bbgo.ExchangeSession sessions map[string]*bbgo.ExchangeSession
orderBooks map[string]*bbgo.ActiveOrderBook orderBooks map[string]*bbgo.ActiveOrderBook
@ -350,6 +353,7 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
s.orderStore = core.NewOrderStore("") s.orderStore = core.NewOrderStore("")
markets := types.MarketMap{}
for _, sessionName := range s.PreferredSessions { for _, sessionName := range s.PreferredSessions {
session, ok := sessions[sessionName] session, ok := sessions[sessionName]
if !ok { if !ok {
@ -363,8 +367,12 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
s.orderBooks[sessionName] = orderBook s.orderBooks[sessionName] = orderBook
s.sessions[sessionName] = session s.sessions[sessionName] = session
// session.Market(symbol)
} }
s.priceResolver = priceresolver.NewSimplePriceResolver(markets)
bbgo.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) { bbgo.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
for n, session := range s.sessions { for n, session := range s.sessions {