2020-11-07 08:08:20 +00:00
|
|
|
package backtest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
|
|
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
|
|
|
"github.com/c9s/bbgo/pkg/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
func newLimitOrder(symbol string, side types.SideType, price, quantity float64) types.SubmitOrder {
|
|
|
|
return types.SubmitOrder{
|
|
|
|
Symbol: symbol,
|
|
|
|
Side: side,
|
|
|
|
Type: types.OrderTypeLimit,
|
|
|
|
Quantity: quantity,
|
|
|
|
Price: price,
|
|
|
|
TimeInForce: "GTC",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-08 19:17:02 +00:00
|
|
|
func TestSimplePriceMatching_LimitOrder(t *testing.T) {
|
|
|
|
account := &types.Account{
|
|
|
|
MakerCommission: 15,
|
|
|
|
TakerCommission: 15,
|
|
|
|
}
|
|
|
|
|
2020-11-08 13:52:44 +00:00
|
|
|
account.UpdateBalances(types.BalanceMap{
|
2020-11-10 06:18:04 +00:00
|
|
|
"USDT": {Currency: "USDT", Available: fixedpoint.NewFromFloat(1000000.0)},
|
|
|
|
"BTC": {Currency: "BTC", Available: fixedpoint.NewFromFloat(100.0)},
|
2020-11-08 13:52:44 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
market := types.Market{
|
|
|
|
Symbol: "BTCUSDT",
|
|
|
|
PricePrecision: 8,
|
|
|
|
VolumePrecision: 8,
|
|
|
|
QuoteCurrency: "USDT",
|
|
|
|
BaseCurrency: "BTC",
|
|
|
|
MinNotional: 0.001,
|
|
|
|
MinAmount: 10.0,
|
|
|
|
MinQuantity: 0.001,
|
|
|
|
}
|
|
|
|
|
2020-11-07 08:08:20 +00:00
|
|
|
engine := &SimplePriceMatching{
|
|
|
|
CurrentTime: time.Now(),
|
2020-11-08 13:52:44 +00:00
|
|
|
Account: account,
|
|
|
|
Market: market,
|
2020-11-07 08:08:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
_, _, err := engine.PlaceOrder(newLimitOrder("BTCUSDT", types.SideTypeBuy, 8000.0-float64(i), 1.0))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
assert.Len(t, engine.bidOrders, 5)
|
|
|
|
assert.Len(t, engine.askOrders, 0)
|
|
|
|
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
_, _, err := engine.PlaceOrder(newLimitOrder("BTCUSDT", types.SideTypeSell, 9000.0+float64(i), 1.0))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
assert.Len(t, engine.bidOrders, 5)
|
|
|
|
assert.Len(t, engine.askOrders, 5)
|
|
|
|
|
|
|
|
closedOrders, trades := engine.SellToPrice(fixedpoint.NewFromFloat(8100.0))
|
|
|
|
assert.Len(t, closedOrders, 0)
|
|
|
|
assert.Len(t, trades, 0)
|
|
|
|
|
|
|
|
closedOrders, trades = engine.SellToPrice(fixedpoint.NewFromFloat(8000.0))
|
|
|
|
assert.Len(t, closedOrders, 1)
|
|
|
|
assert.Len(t, trades, 1)
|
2020-11-10 06:18:04 +00:00
|
|
|
for _, trade := range trades {
|
|
|
|
assert.True(t, trade.IsBuyer)
|
|
|
|
}
|
|
|
|
|
2020-11-07 08:08:20 +00:00
|
|
|
for _, o := range closedOrders {
|
|
|
|
assert.Equal(t, types.SideTypeBuy, o.Side)
|
|
|
|
}
|
|
|
|
|
|
|
|
closedOrders, trades = engine.SellToPrice(fixedpoint.NewFromFloat(7000.0))
|
|
|
|
assert.Len(t, closedOrders, 4)
|
|
|
|
assert.Len(t, trades, 4)
|
|
|
|
|
|
|
|
closedOrders, trades = engine.BuyToPrice(fixedpoint.NewFromFloat(8900.0))
|
|
|
|
assert.Len(t, closedOrders, 0)
|
|
|
|
assert.Len(t, trades, 0)
|
|
|
|
|
|
|
|
closedOrders, trades = engine.BuyToPrice(fixedpoint.NewFromFloat(9000.0))
|
|
|
|
assert.Len(t, closedOrders, 1)
|
|
|
|
assert.Len(t, trades, 1)
|
|
|
|
for _, o := range closedOrders {
|
|
|
|
assert.Equal(t, types.SideTypeSell, o.Side)
|
|
|
|
}
|
|
|
|
for _, trade := range trades {
|
|
|
|
assert.Equal(t, types.SideTypeSell, trade.Side)
|
|
|
|
}
|
|
|
|
|
|
|
|
closedOrders, trades = engine.BuyToPrice(fixedpoint.NewFromFloat(9500.0))
|
|
|
|
assert.Len(t, closedOrders, 4)
|
|
|
|
assert.Len(t, trades, 4)
|
|
|
|
}
|