rename trade volume to quantity and record quote quantity

This commit is contained in:
c9s 2020-07-22 12:26:27 +08:00
parent da75905aeb
commit 4a4178286a
5 changed files with 137 additions and 14 deletions

View File

@ -164,7 +164,82 @@ func (e *Exchange) QueryKLines(ctx context.Context, symbol, interval string, opt
return kLines, nil
}
func (e *Exchange) BatchQueryTrades(ctx context.Context, symbol string, startTime time.Time) (trades []types.Trade, err error) {
type TradeQueryOptions struct {
StartTime *time.Time
EndTime *time.Time
Limit int
LastTradeID int64
}
func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *TradeQueryOptions) (trades []types.Trade, err error) {
req := e.Client.NewListTradesService().
Limit(1000).
Symbol(symbol)
if options.Limit > 0 {
req.Limit(options.Limit)
}
if options.StartTime != nil {
req.StartTime(options.StartTime.UnixNano() / int64(time.Millisecond))
}
if options.EndTime != nil {
req.EndTime(options.EndTime.UnixNano() / int64(time.Millisecond))
}
if options.LastTradeID > 0 {
req.FromID(options.LastTradeID)
}
remoteTrades, err := req.Do(ctx)
if err != nil {
return nil, err
}
for _, t := range remoteTrades {
// skip trade ID that is the same. however this should not happen
var side string
if t.IsBuyer {
side = "BUY"
} else {
side = "SELL"
}
// trade time
tt := time.Unix(0, t.Time*1000000)
logrus.Infof("[binance] trade: %d %s % 4s price: % 13s volume: % 11s %6s % 5s %s", t.ID, t.Symbol, side, t.Price, t.Quantity, BuyerOrSellerLabel(t), MakerOrTakerLabel(t), tt)
price, err := strconv.ParseFloat(t.Price, 64)
if err != nil {
return nil, err
}
quantity, err := strconv.ParseFloat(t.Quantity, 64)
if err != nil {
return nil, err
}
fee, err := strconv.ParseFloat(t.Commission, 64)
if err != nil {
return nil, err
}
trades = append(trades, types.Trade{
ID: t.ID,
Price: price,
Quantity: quantity,
Side: side,
IsBuyer: t.IsBuyer,
IsMaker: t.IsMaker,
Fee: fee,
FeeCurrency: t.CommissionAsset,
Time: tt,
})
}
}
func (e *Exchange) BatchQueryTrades(ctx context.Context, symbol string, startTime time.Time, options *TradeQueryOptions) (trades []types.Trade, err error) {
logrus.Infof("[binance] querying %s trades from %s", symbol, startTime)
var lastTradeID int64 = 0
@ -223,7 +298,7 @@ func (e *Exchange) BatchQueryTrades(ctx context.Context, symbol string, startTim
trades = append(trades, types.Trade{
ID: t.ID,
Price: price,
Volume: quantity,
Quantity: quantity,
Side: side,
IsBuyer: t.IsBuyer,
IsMaker: t.IsMaker,
@ -238,3 +313,49 @@ func (e *Exchange) BatchQueryTrades(ctx context.Context, symbol string, startTim
return trades, nil
}
func convertRemoteTrade(t binance.TradeV3) (*types.Trade, error) {
// skip trade ID that is the same. however this should not happen
var side string
if t.IsBuyer {
side = "BUY"
} else {
side = "SELL"
}
// trade time
mts := time.Unix(0, t.Time*int64(time.Millisecond))
price, err := strconv.ParseFloat(t.Price, 64)
if err != nil {
return nil, err
}
quantity, err := strconv.ParseFloat(t.Quantity, 64)
if err != nil {
return nil, err
}
quoteQuantity, err := strconv.ParseFloat(t.QuoteQuantity, 64)
if err != nil {
return nil, err
}
fee, err := strconv.ParseFloat(t.Commission, 64)
if err != nil {
return nil, err
}
return &types.Trade{
ID: t.ID,
Price: price,
Quantity: quantity,
Side: side,
IsBuyer: t.IsBuyer,
IsMaker: t.IsMaker,
Fee: fee,
FeeCurrency: t.CommissionAsset,
QuoteQuantity: quoteQuantity,
Time: mts,
}, nil
}

View File

@ -93,7 +93,7 @@ func (e *ExecutionReportEvent) Trade() (*types.Trade, error) {
ID: e.TradeID,
Symbol: e.Symbol,
Price: util.MustParseFloat(e.LastExecutedPrice),
Volume: util.MustParseFloat(e.LastExecutedQuantity),
Quantity: util.MustParseFloat(e.LastExecutedQuantity),
Side: e.Side,
IsBuyer: e.Side == "BUY",
IsMaker: e.IsMaker,

View File

@ -48,8 +48,8 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
for _, t := range trades {
if t.IsBuyer {
bidVolume += t.Volume
bidAmount += t.Price * t.Volume
bidVolume += t.Quantity
bidAmount += t.Price * t.Quantity
// since we use USDT as the quote currency, we simply check if it matches the currency symbol
if strings.HasPrefix(t.Symbol, t.FeeCurrency) {
@ -66,8 +66,8 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
for _, t := range trades {
if !t.IsBuyer {
profit += (t.Price - averageBidPrice) * t.Volume
askVolume += t.Volume
profit += (t.Price - averageBidPrice) * t.Quantity
askVolume += t.Quantity
// since we use USDT as the quote currency, we simply check if it matches the currency symbol
if strings.HasPrefix(t.Symbol, t.FeeCurrency) {

View File

@ -119,7 +119,7 @@ func (trader *KLineRegressionTrader) RunStrategy(ctx context.Context, strategy S
trade := types.Trade{
ID: tradeID,
Price: price,
Volume: volume,
Quantity: volume,
Side: string(order.Side),
IsBuyer: order.Side == types.SideTypeBuy,
IsMaker: false,

View File

@ -10,11 +10,13 @@ type Trade struct {
GID int64 `json:"gid" db:"gid"`
// ID is the source trade ID
ID int64 `json:"id" db:"id"`
Exchange string `json:"exchange" db:"exchange"`
Price float64 `json:"price" db:"price"`
Volume float64 `json:"volume" db:"volume"`
Symbol string `json:"symbol" db:"symbol"`
ID int64 `json:"id" db:"id"`
Exchange string `json:"exchange" db:"exchange"`
Price float64 `json:"price" db:"price"`
Quantity float64 `json:"quantity" db:"quantity"`
QuoteQuantity float64 `json:"quoteQuantity" db:"quote_quantity"`
Symbol string `json:"symbol" db:"symbol"`
Side string `json:"side" db:"side"`
IsBuyer bool `json:"isBuyer" db:"is_buyer"`
IsMaker bool `json:"isMaker" db:"is_maker"`
@ -48,7 +50,7 @@ func (trade Trade) SlackAttachment() slack.Attachment {
{Title: "Symbol", Value: trade.Symbol, Short: true},
{Title: "Side", Value: trade.Side, Short: true},
{Title: "Price", Value: market.FormatPrice(trade.Price), Short: true},
{Title: "Volume", Value: market.FormatVolume(trade.Volume), Short: true},
{Title: "Volume", Value: market.FormatVolume(trade.Quantity), Short: true},
},
// Footer: tradingCtx.TradeStartTime.Format(time.RFC822),
// FooterIcon: "",