mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 08:15:15 +00:00
backtest: fix execution price for stop limit taker orders
This commit is contained in:
parent
9f9fc098f4
commit
3a24a48cde
|
@ -366,8 +366,7 @@ func (m *SimplePriceMatching) buyToPrice(price fixedpoint.Value) (closedOrders [
|
||||||
if o.Price.Compare(price) >= 0 {
|
if o.Price.Compare(price) >= 0 {
|
||||||
// limit buy taker order, move it to the closed order
|
// limit buy taker order, move it to the closed order
|
||||||
// we assume that we have no price slippage here, so the latest price will be the executed price
|
// we assume that we have no price slippage here, so the latest price will be the executed price
|
||||||
// TODO: simulate slippage here
|
o.AveragePrice = price
|
||||||
o.Price = price
|
|
||||||
o.ExecutedQuantity = o.Quantity
|
o.ExecutedQuantity = o.Quantity
|
||||||
o.Status = types.OrderStatusFilled
|
o.Status = types.OrderStatusFilled
|
||||||
closedOrders = append(closedOrders, o)
|
closedOrders = append(closedOrders, o)
|
||||||
|
@ -414,8 +413,7 @@ func (m *SimplePriceMatching) buyToPrice(price fixedpoint.Value) (closedOrders [
|
||||||
// limit sell order as taker, move it to the closed order
|
// limit sell order as taker, move it to the closed order
|
||||||
// we assume that we have no price slippage here, so the latest price will be the executed price
|
// we assume that we have no price slippage here, so the latest price will be the executed price
|
||||||
// TODO: simulate slippage here
|
// TODO: simulate slippage here
|
||||||
o.Price = price
|
o.AveragePrice = price
|
||||||
|
|
||||||
o.ExecutedQuantity = o.Quantity
|
o.ExecutedQuantity = o.Quantity
|
||||||
o.Status = types.OrderStatusFilled
|
o.Status = types.OrderStatusFilled
|
||||||
closedOrders = append(closedOrders, o)
|
closedOrders = append(closedOrders, o)
|
||||||
|
@ -444,7 +442,12 @@ func (m *SimplePriceMatching) buyToPrice(price fixedpoint.Value) (closedOrders [
|
||||||
|
|
||||||
for i := range closedOrders {
|
for i := range closedOrders {
|
||||||
o := closedOrders[i]
|
o := closedOrders[i]
|
||||||
trade := m.newTradeFromOrder(&o, true, o.Price)
|
executedPrice := o.Price
|
||||||
|
if !o.AveragePrice.IsZero() {
|
||||||
|
executedPrice = o.AveragePrice
|
||||||
|
}
|
||||||
|
|
||||||
|
trade := m.newTradeFromOrder(&o, !isTakerOrder(o), executedPrice)
|
||||||
m.executeTrade(trade)
|
m.executeTrade(trade)
|
||||||
closedOrders[i] = o
|
closedOrders[i] = o
|
||||||
|
|
||||||
|
@ -495,7 +498,7 @@ func (m *SimplePriceMatching) sellToPrice(price fixedpoint.Value) (closedOrders
|
||||||
// if the order price is lower than the current price
|
// if the order price is lower than the current price
|
||||||
// it's a taker order
|
// it's a taker order
|
||||||
if o.Price.Compare(price) <= 0 {
|
if o.Price.Compare(price) <= 0 {
|
||||||
o.Price = price
|
o.AveragePrice = price
|
||||||
o.ExecutedQuantity = o.Quantity
|
o.ExecutedQuantity = o.Quantity
|
||||||
o.Status = types.OrderStatusFilled
|
o.Status = types.OrderStatusFilled
|
||||||
closedOrders = append(closedOrders, o)
|
closedOrders = append(closedOrders, o)
|
||||||
|
@ -539,9 +542,9 @@ func (m *SimplePriceMatching) sellToPrice(price fixedpoint.Value) (closedOrders
|
||||||
|
|
||||||
o.Type = types.OrderTypeLimit
|
o.Type = types.OrderTypeLimit
|
||||||
|
|
||||||
// taker order?
|
// handle TAKER order
|
||||||
if o.Price.Compare(price) >= 0 {
|
if o.Price.Compare(price) >= 0 {
|
||||||
o.Price = price
|
o.AveragePrice = price
|
||||||
o.ExecutedQuantity = o.Quantity
|
o.ExecutedQuantity = o.Quantity
|
||||||
o.Status = types.OrderStatusFilled
|
o.Status = types.OrderStatusFilled
|
||||||
closedOrders = append(closedOrders, o)
|
closedOrders = append(closedOrders, o)
|
||||||
|
@ -568,7 +571,12 @@ func (m *SimplePriceMatching) sellToPrice(price fixedpoint.Value) (closedOrders
|
||||||
|
|
||||||
for i := range closedOrders {
|
for i := range closedOrders {
|
||||||
o := closedOrders[i]
|
o := closedOrders[i]
|
||||||
trade := m.newTradeFromOrder(&o, true, o.Price)
|
executedPrice := o.Price
|
||||||
|
if !o.AveragePrice.IsZero() {
|
||||||
|
executedPrice = o.AveragePrice
|
||||||
|
}
|
||||||
|
|
||||||
|
trade := m.newTradeFromOrder(&o, !isTakerOrder(o), executedPrice)
|
||||||
m.executeTrade(trade)
|
m.executeTrade(trade)
|
||||||
closedOrders[i] = o
|
closedOrders[i] = o
|
||||||
|
|
||||||
|
@ -678,6 +686,22 @@ func calculateNativeOrderFee(order *types.Order, market types.Market, feeRate fi
|
||||||
return fee, feeCurrency
|
return fee, feeCurrency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isTakerOrder(o types.Order) bool {
|
||||||
|
if o.AveragePrice.IsZero() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch o.Side {
|
||||||
|
case types.SideTypeBuy:
|
||||||
|
return o.AveragePrice.Compare(o.Price) < 0
|
||||||
|
|
||||||
|
case types.SideTypeSell:
|
||||||
|
return o.AveragePrice.Compare(o.Price) > 0
|
||||||
|
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func isLimitTakerOrder(o types.SubmitOrder, currentPrice fixedpoint.Value) bool {
|
func isLimitTakerOrder(o types.SubmitOrder, currentPrice fixedpoint.Value) bool {
|
||||||
if currentPrice.IsZero() {
|
if currentPrice.IsZero() {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -293,7 +293,7 @@ func TestSimplePriceMatching_StopLimitOrderBuy(t *testing.T) {
|
||||||
assert.Equal(t, types.OrderStatusFilled, closedOrders[0].Status)
|
assert.Equal(t, types.OrderStatusFilled, closedOrders[0].Status)
|
||||||
assert.Equal(t, types.OrderTypeLimit, closedOrders[0].Type)
|
assert.Equal(t, types.OrderTypeLimit, closedOrders[0].Type)
|
||||||
assert.Equal(t, "21001", trades[0].Price.String())
|
assert.Equal(t, "21001", trades[0].Price.String())
|
||||||
assert.Equal(t, "21001", closedOrders[0].Price.String(), "order.Price should be adjusted")
|
assert.Equal(t, "22000", closedOrders[0].Price.String(), "order.Price should not be adjusted")
|
||||||
|
|
||||||
assert.Equal(t, fixedpoint.NewFromFloat(21001.0).String(), engine.LastPrice.String())
|
assert.Equal(t, fixedpoint.NewFromFloat(21001.0).String(), engine.LastPrice.String())
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ func TestSimplePriceMatching_StopLimitOrderSell(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, types.OrderStatusFilled, closedOrders[0].Status)
|
assert.Equal(t, types.OrderStatusFilled, closedOrders[0].Status)
|
||||||
assert.Equal(t, types.OrderTypeLimit, closedOrders[0].Type)
|
assert.Equal(t, types.OrderTypeLimit, closedOrders[0].Type)
|
||||||
assert.Equal(t, "20990", closedOrders[0].Price.String())
|
assert.Equal(t, "20000", closedOrders[0].Price.String(), "limit order price should not be changed")
|
||||||
assert.Equal(t, "20990", trades[0].Price.String())
|
assert.Equal(t, "20990", trades[0].Price.String())
|
||||||
assert.Equal(t, "20990", engine.LastPrice.String())
|
assert.Equal(t, "20990", engine.LastPrice.String())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user