103 lines
3.6 KiB
Go
103 lines
3.6 KiB
Go
package grid2
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/mock/gomock"
|
|
|
|
"git.qtrade.icu/lychiyu/bbgo/pkg/fixedpoint"
|
|
"git.qtrade.icu/lychiyu/bbgo/pkg/types"
|
|
"git.qtrade.icu/lychiyu/bbgo/pkg/types/mocks"
|
|
)
|
|
|
|
func mustNewTime(v string) time.Time {
|
|
t, err := time.Parse(time.RFC3339, v)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return t
|
|
}
|
|
|
|
var testClosedOrderID = uint64(0)
|
|
|
|
func newClosedLimitOrder(symbol string, side types.SideType, price, quantity fixedpoint.Value, ta ...time.Time) types.Order {
|
|
testClosedOrderID++
|
|
creationTime := time.Now()
|
|
updateTime := creationTime
|
|
|
|
if len(ta) > 0 {
|
|
creationTime = ta[0]
|
|
if len(ta) > 1 {
|
|
updateTime = ta[1]
|
|
}
|
|
}
|
|
|
|
return types.Order{
|
|
SubmitOrder: types.SubmitOrder{
|
|
Symbol: symbol,
|
|
Side: side,
|
|
Type: types.OrderTypeLimit,
|
|
Quantity: quantity,
|
|
Price: price,
|
|
},
|
|
Exchange: types.ExchangeBinance,
|
|
OrderID: testClosedOrderID,
|
|
Status: types.OrderStatusFilled,
|
|
ExecutedQuantity: quantity,
|
|
CreationTime: types.Time(creationTime),
|
|
UpdateTime: types.Time(updateTime),
|
|
}
|
|
}
|
|
|
|
func TestProfitFixer(t *testing.T) {
|
|
testClosedOrderID = 0
|
|
|
|
mockCtrl := gomock.NewController(t)
|
|
defer mockCtrl.Finish()
|
|
|
|
ctx := context.Background()
|
|
mockHistoryService := mocks.NewMockExchangeTradeHistoryService(mockCtrl)
|
|
|
|
mockHistoryService.EXPECT().QueryClosedOrders(gomock.Any(), "ETHUSDT", mustNewTime("2022-01-01T00:00:00Z"), mustNewTime("2022-01-07T00:00:00Z"), uint64(0)).
|
|
Return([]types.Order{
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeBuy, number(1800.0), number(0.1), mustNewTime("2022-01-01T00:01:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeBuy, number(1700.0), number(0.1), mustNewTime("2022-01-01T00:01:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeSell, number(1800.0), number(0.1), mustNewTime("2022-01-01T00:01:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeSell, number(1900.0), number(0.1), mustNewTime("2022-01-01T00:03:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeSell, number(1905.0), number(0.1), mustNewTime("2022-01-01T00:03:00Z")),
|
|
}, nil)
|
|
|
|
mockHistoryService.EXPECT().QueryClosedOrders(gomock.Any(), "ETHUSDT", mustNewTime("2022-01-01T00:03:00Z"), mustNewTime("2022-01-07T00:00:00Z"), uint64(5)).
|
|
Return([]types.Order{
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeBuy, number(1900.0), number(0.1), mustNewTime("2022-01-01T00:04:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeBuy, number(1800.0), number(0.1), mustNewTime("2022-01-01T00:04:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeBuy, number(1700.0), number(0.1), mustNewTime("2022-01-01T00:04:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeSell, number(1800.0), number(0.1), mustNewTime("2022-01-01T00:04:00Z")),
|
|
newClosedLimitOrder("ETHUSDT", types.SideTypeSell, number(1900.0), number(0.1), mustNewTime("2022-01-01T00:08:00Z")),
|
|
}, nil)
|
|
|
|
mockHistoryService.EXPECT().QueryClosedOrders(gomock.Any(), "ETHUSDT", mustNewTime("2022-01-01T00:08:00Z"), mustNewTime("2022-01-07T00:00:00Z"), uint64(10)).
|
|
Return([]types.Order{}, nil)
|
|
|
|
grid := NewGrid(number(1000.0), number(2000.0), number(11), number(0.01))
|
|
grid.CalculateArithmeticPins()
|
|
|
|
since, err := time.Parse(time.RFC3339, "2022-01-01T00:00:00Z")
|
|
assert.NoError(t, err)
|
|
|
|
until, err := time.Parse(time.RFC3339, "2022-01-07T00:00:00Z")
|
|
assert.NoError(t, err)
|
|
|
|
stats := &GridProfitStats{}
|
|
fixer := newProfitFixer(grid, "ETHUSDT", mockHistoryService)
|
|
err = fixer.Fix(ctx, since, until, 0, stats)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "40", stats.TotalQuoteProfit.String())
|
|
assert.Equal(t, 4, stats.ArbitrageCount)
|
|
}
|