2023-02-17 11:50:46 +00:00
|
|
|
package bbgo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
|
|
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
2023-11-25 05:22:03 +00:00
|
|
|
. "github.com/c9s/bbgo/pkg/testing/testhelper"
|
2023-02-17 11:50:46 +00:00
|
|
|
"github.com/c9s/bbgo/pkg/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestActiveOrderBook_pendingOrders(t *testing.T) {
|
|
|
|
now := time.Now()
|
2023-11-25 05:22:03 +00:00
|
|
|
t1 := now
|
|
|
|
t2 := now.Add(time.Millisecond)
|
2023-02-23 13:46:57 +00:00
|
|
|
|
2023-11-25 05:22:03 +00:00
|
|
|
ob := NewActiveOrderBook("BTCUSDT")
|
2023-02-17 11:50:46 +00:00
|
|
|
|
2023-02-23 13:46:57 +00:00
|
|
|
filled := false
|
|
|
|
ob.OnFilled(func(o types.Order) {
|
|
|
|
filled = true
|
|
|
|
})
|
|
|
|
|
2023-11-25 05:22:03 +00:00
|
|
|
quantity := Number("0.01")
|
|
|
|
orderUpdate1 := types.Order{
|
2023-02-17 11:50:46 +00:00
|
|
|
OrderID: 99,
|
|
|
|
SubmitOrder: types.SubmitOrder{
|
|
|
|
Symbol: "BTCUSDT",
|
|
|
|
Side: types.SideTypeBuy,
|
|
|
|
Type: types.OrderTypeLimit,
|
2023-11-25 05:22:03 +00:00
|
|
|
Quantity: quantity,
|
|
|
|
Price: Number(19000.0),
|
2023-02-17 11:50:46 +00:00
|
|
|
AveragePrice: fixedpoint.Zero,
|
|
|
|
StopPrice: fixedpoint.Zero,
|
|
|
|
},
|
2023-11-25 05:22:03 +00:00
|
|
|
ExecutedQuantity: Number(0.0),
|
|
|
|
Status: types.OrderStatusNew,
|
|
|
|
CreationTime: types.Time(t1),
|
|
|
|
UpdateTime: types.Time(t1),
|
2023-02-23 13:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-11-25 05:22:03 +00:00
|
|
|
orderUpdate2 := types.Order{
|
2023-02-17 11:50:46 +00:00
|
|
|
OrderID: 99,
|
|
|
|
SubmitOrder: types.SubmitOrder{
|
|
|
|
Symbol: "BTCUSDT",
|
|
|
|
Side: types.SideTypeBuy,
|
|
|
|
Type: types.OrderTypeLimit,
|
2023-11-25 05:22:03 +00:00
|
|
|
Quantity: quantity,
|
|
|
|
Price: Number(19000.0),
|
2023-02-17 11:50:46 +00:00
|
|
|
AveragePrice: fixedpoint.Zero,
|
|
|
|
StopPrice: fixedpoint.Zero,
|
|
|
|
},
|
2023-11-25 05:22:03 +00:00
|
|
|
ExecutedQuantity: quantity,
|
|
|
|
Status: types.OrderStatusFilled,
|
|
|
|
CreationTime: types.Time(t1),
|
|
|
|
UpdateTime: types.Time(t2),
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.True(t, isNewerOrderUpdate(orderUpdate2, orderUpdate1), "orderUpdate2 should be newer than orderUpdate1")
|
|
|
|
|
|
|
|
// if we received filled order first
|
|
|
|
// should be added to pending orders
|
|
|
|
ob.Update(orderUpdate2)
|
|
|
|
assert.Len(t, ob.pendingOrderUpdates.Orders(), 1)
|
|
|
|
|
|
|
|
o99, ok := ob.pendingOrderUpdates.Get(99)
|
|
|
|
if assert.True(t, ok) {
|
|
|
|
assert.Equal(t, types.OrderStatusFilled, o99.Status)
|
|
|
|
}
|
2023-02-17 11:50:46 +00:00
|
|
|
|
2023-11-25 05:22:03 +00:00
|
|
|
// when adding the older order update to the book,
|
|
|
|
// it should trigger the filled event once the order is registered to the active order book
|
|
|
|
ob.Add(orderUpdate1)
|
2023-02-23 13:46:57 +00:00
|
|
|
assert.True(t, filled, "filled event should be fired")
|
2023-02-17 11:50:46 +00:00
|
|
|
}
|
2023-11-22 09:37:10 +00:00
|
|
|
|
2024-03-14 14:41:58 +00:00
|
|
|
func Test_RestoreParametersOnUpdateHandler(t *testing.T) {
|
|
|
|
now := time.Now()
|
|
|
|
t1 := now
|
|
|
|
t2 := now.Add(time.Millisecond)
|
|
|
|
ob := NewActiveOrderBook("BTCUSDT")
|
|
|
|
|
|
|
|
var updatedOrder types.Order
|
|
|
|
ob.OnFilled(func(o types.Order) {
|
|
|
|
updatedOrder = o
|
|
|
|
})
|
|
|
|
quantity := Number("0.01")
|
|
|
|
orderUpdate1 := types.Order{
|
|
|
|
OrderID: 99,
|
|
|
|
SubmitOrder: types.SubmitOrder{
|
|
|
|
Symbol: "BTCUSDT",
|
|
|
|
Side: types.SideTypeBuy,
|
|
|
|
Type: types.OrderTypeLimit,
|
|
|
|
Quantity: quantity,
|
|
|
|
Price: Number(19000.0),
|
|
|
|
AveragePrice: fixedpoint.Zero,
|
|
|
|
StopPrice: fixedpoint.Zero,
|
|
|
|
Tag: "tag1",
|
|
|
|
GroupID: uint32(1),
|
|
|
|
},
|
|
|
|
ExecutedQuantity: Number(0.0),
|
|
|
|
Status: types.OrderStatusNew,
|
|
|
|
CreationTime: types.Time(t1),
|
|
|
|
UpdateTime: types.Time(t1),
|
|
|
|
}
|
|
|
|
|
|
|
|
orderUpdate2 := types.Order{
|
|
|
|
OrderID: 99,
|
|
|
|
SubmitOrder: types.SubmitOrder{
|
|
|
|
Symbol: "BTCUSDT",
|
|
|
|
Side: types.SideTypeBuy,
|
|
|
|
Type: types.OrderTypeLimit,
|
|
|
|
Quantity: quantity,
|
|
|
|
Price: Number(19000.0),
|
|
|
|
AveragePrice: fixedpoint.Zero,
|
|
|
|
StopPrice: fixedpoint.Zero,
|
|
|
|
},
|
|
|
|
ExecutedQuantity: quantity,
|
|
|
|
Status: types.OrderStatusFilled,
|
|
|
|
CreationTime: types.Time(t1),
|
|
|
|
UpdateTime: types.Time(t2),
|
|
|
|
}
|
|
|
|
ob.add(orderUpdate1)
|
|
|
|
ob.orderUpdateHandler(orderUpdate2)
|
|
|
|
assert.Equal(t, "tag1", updatedOrder.Tag)
|
|
|
|
assert.Equal(t, uint32(1), updatedOrder.GroupID)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-11-22 09:37:10 +00:00
|
|
|
func Test_isNewerUpdate(t *testing.T) {
|
|
|
|
a := types.Order{
|
|
|
|
Status: types.OrderStatusPartiallyFilled,
|
|
|
|
ExecutedQuantity: number(0.2),
|
|
|
|
}
|
|
|
|
b := types.Order{
|
|
|
|
Status: types.OrderStatusPartiallyFilled,
|
|
|
|
ExecutedQuantity: number(0.1),
|
|
|
|
}
|
2023-11-22 09:44:41 +00:00
|
|
|
ret := isNewerOrderUpdate(a, b)
|
2023-11-22 09:37:10 +00:00
|
|
|
assert.True(t, ret)
|
|
|
|
}
|
2023-11-22 09:43:38 +00:00
|
|
|
|
|
|
|
func Test_isNewerUpdateTime(t *testing.T) {
|
|
|
|
a := types.Order{
|
|
|
|
UpdateTime: types.NewTimeFromUnix(200, 0),
|
|
|
|
}
|
|
|
|
b := types.Order{
|
|
|
|
UpdateTime: types.NewTimeFromUnix(100, 0),
|
|
|
|
}
|
2023-11-22 09:44:41 +00:00
|
|
|
ret := isNewerOrderUpdateTime(a, b)
|
2023-11-22 09:43:38 +00:00
|
|
|
assert.True(t, ret)
|
|
|
|
}
|