mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 00:35:15 +00:00
FEATURE: split self trades when use MAX RESTful API to query trades
This commit is contained in:
parent
f26568e213
commit
f9f6346468
|
@ -5,7 +5,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/exchange/max/maxapi"
|
||||
max "github.com/c9s/bbgo/pkg/exchange/max/maxapi"
|
||||
v3 "github.com/c9s/bbgo/pkg/exchange/max/maxapi/v3"
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
@ -193,7 +194,50 @@ func toGlobalOrder(maxOrder max.Order) (*types.Order, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func toGlobalTrade(t max.Trade) (*types.Trade, error) {
|
||||
func toGlobalTradeV3(t v3.Trade) ([]types.Trade, error) {
|
||||
var trades []types.Trade
|
||||
isMargin := t.WalletType == max.WalletTypeMargin
|
||||
side := toGlobalSideType(t.Side)
|
||||
|
||||
trade := types.Trade{
|
||||
ID: t.ID,
|
||||
OrderID: t.OrderID,
|
||||
Price: t.Price,
|
||||
Symbol: toGlobalSymbol(t.Market),
|
||||
Exchange: types.ExchangeMax,
|
||||
Quantity: t.Volume,
|
||||
Side: side,
|
||||
IsBuyer: t.IsBuyer(),
|
||||
IsMaker: t.IsMaker(),
|
||||
Fee: t.Fee,
|
||||
FeeCurrency: toGlobalCurrency(t.FeeCurrency),
|
||||
QuoteQuantity: t.Funds,
|
||||
Time: types.Time(t.CreatedAt),
|
||||
IsMargin: isMargin,
|
||||
IsIsolated: false,
|
||||
IsFutures: false,
|
||||
}
|
||||
|
||||
if t.Side == "self-trade" {
|
||||
trade.Side = types.SideTypeSell
|
||||
|
||||
// create trade for bid
|
||||
bidTrade := trade
|
||||
bidTrade.Side = types.SideTypeBuy
|
||||
bidTrade.OrderID = t.SelfTradeBidOrderID
|
||||
bidTrade.Fee = t.SelfTradeBidFee
|
||||
bidTrade.FeeCurrency = t.SelfTradeBidFeeCurrency
|
||||
bidTrade.IsBuyer = !trade.IsBuyer
|
||||
bidTrade.IsMaker = !trade.IsMaker
|
||||
trades = append(trades, bidTrade)
|
||||
}
|
||||
|
||||
trades = append(trades, trade)
|
||||
|
||||
return trades, nil
|
||||
}
|
||||
|
||||
func toGlobalTradeV2(t max.Trade) (*types.Trade, error) {
|
||||
isMargin := t.WalletType == max.WalletTypeMargin
|
||||
side := toGlobalSideType(t.Side)
|
||||
return &types.Trade{
|
||||
|
|
116
pkg/exchange/max/convert_test.go
Normal file
116
pkg/exchange/max/convert_test.go
Normal file
|
@ -0,0 +1,116 @@
|
|||
package max
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
v3 "github.com/c9s/bbgo/pkg/exchange/max/maxapi/v3"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_toGlobalTradeV3(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
t.Run("ask trade", func(t *testing.T) {
|
||||
str := `
|
||||
{
|
||||
"id": 68444,
|
||||
"order_id": 87,
|
||||
"wallet_type": "spot",
|
||||
"price": "21499.0",
|
||||
"volume": "0.2658",
|
||||
"funds": "5714.4",
|
||||
"market": "ethtwd",
|
||||
"market_name": "ETH/TWD",
|
||||
"side": "bid",
|
||||
"fee": "0.00001",
|
||||
"fee_currency": "usdt",
|
||||
"self_trade_bid_fee": "0.00001",
|
||||
"self_trade_bid_fee_currency": "eth",
|
||||
"self_trade_bid_order_id": 86,
|
||||
"liquidity": "maker",
|
||||
"created_at": 1521726960357
|
||||
}
|
||||
`
|
||||
|
||||
var trade v3.Trade
|
||||
assert.NoError(json.Unmarshal([]byte(str), &trade))
|
||||
|
||||
trades, err := toGlobalTradeV3(trade)
|
||||
assert.NoError(err)
|
||||
assert.Len(trades, 1)
|
||||
|
||||
assert.Equal(uint64(87), trades[0].OrderID)
|
||||
assert.Equal(types.SideTypeBuy, trades[0].Side)
|
||||
})
|
||||
|
||||
t.Run("bid trade", func(t *testing.T) {
|
||||
str := `
|
||||
{
|
||||
"id": 68444,
|
||||
"order_id": 87,
|
||||
"wallet_type": "spot",
|
||||
"price": "21499.0",
|
||||
"volume": "0.2658",
|
||||
"funds": "5714.4",
|
||||
"market": "ethtwd",
|
||||
"market_name": "ETH/TWD",
|
||||
"side": "ask",
|
||||
"fee": "0.00001",
|
||||
"fee_currency": "usdt",
|
||||
"self_trade_bid_fee": "0.00001",
|
||||
"self_trade_bid_fee_currency": "eth",
|
||||
"self_trade_bid_order_id": 86,
|
||||
"liquidity": "maker",
|
||||
"created_at": 1521726960357
|
||||
}
|
||||
`
|
||||
|
||||
var trade v3.Trade
|
||||
assert.NoError(json.Unmarshal([]byte(str), &trade))
|
||||
|
||||
trades, err := toGlobalTradeV3(trade)
|
||||
assert.NoError(err)
|
||||
assert.Len(trades, 1)
|
||||
|
||||
assert.Equal(uint64(87), trades[0].OrderID)
|
||||
assert.Equal(types.SideTypeSell, trades[0].Side)
|
||||
})
|
||||
|
||||
t.Run("self trade", func(t *testing.T) {
|
||||
str := `
|
||||
{
|
||||
"id": 68444,
|
||||
"order_id": 87,
|
||||
"wallet_type": "spot",
|
||||
"price": "21499.0",
|
||||
"volume": "0.2658",
|
||||
"funds": "5714.4",
|
||||
"market": "ethtwd",
|
||||
"market_name": "ETH/TWD",
|
||||
"side": "self-trade",
|
||||
"fee": "0.00001",
|
||||
"fee_currency": "usdt",
|
||||
"self_trade_bid_fee": "0.00001",
|
||||
"self_trade_bid_fee_currency": "eth",
|
||||
"self_trade_bid_order_id": 86,
|
||||
"liquidity": "maker",
|
||||
"created_at": 1521726960357
|
||||
}
|
||||
`
|
||||
|
||||
var trade v3.Trade
|
||||
assert.NoError(json.Unmarshal([]byte(str), &trade))
|
||||
|
||||
trades, err := toGlobalTradeV3(trade)
|
||||
assert.NoError(err)
|
||||
assert.Len(trades, 2)
|
||||
|
||||
assert.Equal(uint64(86), trades[0].OrderID)
|
||||
assert.Equal(types.SideTypeBuy, trades[0].Side)
|
||||
|
||||
assert.Equal(uint64(87), trades[1].OrderID)
|
||||
assert.Equal(types.SideTypeSell, trades[1].Side)
|
||||
})
|
||||
}
|
|
@ -186,13 +186,13 @@ func (e *Exchange) QueryOrderTrades(ctx context.Context, q types.OrderQuery) ([]
|
|||
|
||||
var trades []types.Trade
|
||||
for _, t := range maxTrades {
|
||||
localTrade, err := toGlobalTrade(t)
|
||||
localTrades, err := toGlobalTradeV3(t)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("can not convert trade: %+v", t)
|
||||
continue
|
||||
}
|
||||
|
||||
trades = append(trades, *localTrade)
|
||||
trades = append(trades, localTrades...)
|
||||
}
|
||||
|
||||
// ensure everything is sorted ascending
|
||||
|
@ -806,13 +806,13 @@ func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *type
|
|||
}
|
||||
|
||||
for _, t := range maxTrades {
|
||||
localTrade, err := toGlobalTrade(t)
|
||||
localTrades, err := toGlobalTradeV3(t)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("can not convert trade: %+v", t)
|
||||
continue
|
||||
}
|
||||
|
||||
trades = append(trades, *localTrade)
|
||||
trades = append(trades, localTrades...)
|
||||
}
|
||||
|
||||
// ensure everything is sorted ascending
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/c9s/bbgo/pkg/exchange/max/maxapi"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
@ -136,7 +135,7 @@ func (g *GetOrderTradesRequest) GetSlugsMap() (map[string]string, error) {
|
|||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetOrderTradesRequest) Do(ctx context.Context) ([]max.Trade, error) {
|
||||
func (g *GetOrderTradesRequest) Do(ctx context.Context) ([]Trade, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
|
@ -157,7 +156,7 @@ func (g *GetOrderTradesRequest) Do(ctx context.Context) ([]max.Trade, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse []max.Trade
|
||||
var apiResponse []Trade
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ func (g *GetWalletTradesRequest) GetSlugsMap() (map[string]string, error) {
|
|||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetWalletTradesRequest) Do(ctx context.Context) ([]max.Trade, error) {
|
||||
func (g *GetWalletTradesRequest) Do(ctx context.Context) ([]Trade, error) {
|
||||
|
||||
// empty params for GET operation
|
||||
var params interface{}
|
||||
|
@ -225,7 +225,7 @@ func (g *GetWalletTradesRequest) Do(ctx context.Context) ([]max.Trade, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var apiResponse []max.Trade
|
||||
var apiResponse []Trade
|
||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ type WalletType = maxapi.WalletType
|
|||
type OrderType = maxapi.OrderType
|
||||
|
||||
type Order = maxapi.Order
|
||||
type Trade = maxapi.Trade
|
||||
type Account = maxapi.Account
|
||||
|
||||
// OrderService manages the Order endpoint.
|
||||
|
|
33
pkg/exchange/max/maxapi/v3/trade.go
Normal file
33
pkg/exchange/max/maxapi/v3/trade.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package v3
|
||||
|
||||
import (
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type Trade struct {
|
||||
ID uint64 `json:"id" db:"exchange_id"`
|
||||
WalletType WalletType `json:"wallet_type,omitempty"`
|
||||
Price fixedpoint.Value `json:"price"`
|
||||
Volume fixedpoint.Value `json:"volume"`
|
||||
Funds fixedpoint.Value `json:"funds"`
|
||||
Market string `json:"market"`
|
||||
MarketName string `json:"market_name"`
|
||||
CreatedAt types.MillisecondTimestamp `json:"created_at"`
|
||||
Side string `json:"side"`
|
||||
OrderID uint64 `json:"order_id"`
|
||||
Fee fixedpoint.Value `json:"fee"` // float number as string
|
||||
FeeCurrency string `json:"fee_currency"`
|
||||
Liquidity string `json:"liquidity"`
|
||||
SelfTradeBidFee fixedpoint.Value `json:"self_trade_bid_fee"`
|
||||
SelfTradeBidFeeCurrency string `json:"self_trade_bid_fee_currency"`
|
||||
SelfTradeBidOrderID uint64 `json:"self_trade_bid_order_id"`
|
||||
}
|
||||
|
||||
func (t Trade) IsBuyer() bool {
|
||||
return t.Side == "bid"
|
||||
}
|
||||
|
||||
func (t Trade) IsMaker() bool {
|
||||
return t.Liquidity == "maker"
|
||||
}
|
Loading…
Reference in New Issue
Block a user