You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

54 lines
1.4 KiB

package backtest
import (
"math"
"sig-pub/pkg/data"
"sig-pub/pkg/trade"
"sig-pub/pkg/types"
"sig-pub/pkg/types/decimals"
)
type TradeSimulator struct {
FeePct float64 // e.g. 0.0005 = 0.05%
SlippagePct float64 // e.g. 0.001 = 0.1%
}
func NewTradeSimulator(feePct, slippagePct float64) *TradeSimulator {
return &TradeSimulator{FeePct: feePct, SlippagePct: slippagePct}
}
// ExecuteMarket 执行市价单,使用kline信息决定成交价(使用close以及滑点)
func (s *TradeSimulator) ExecuteMarket(tradeId int64, symbol string, ticket trade.TradeTicket) (order *trade.TradeOrder) {
price := ticket.Price
slippage := s.SlippagePct
switch ticket.Side {
default:
panic("invalid trade side")
case types.SideLong:
// buy: worse price higher
price = price * (1 + slippage)
case types.SideShort:
// sell: worse price lower
price = price * (1 - slippage)
}
ticketQty := decimals.MustToFloat64(ticket.Qty)
fee := math.Abs(price*ticketQty) * s.FeePct
order = &trade.TradeOrder{
TradeId: tradeId,
TradeType: ticket.TradeType,
InstId: symbol,
Side: ticket.Side,
Qty: ticket.Qty,
Price: price,
Fee: fee,
Leverage: ticket.Leverage,
Ctime: ticket.Ktime,
Status: data.StatusOk,
PeakPx: ticket.Price,
CloseCause: ticket.Cause,
}
return
}
// ExecuteLimit todo 简单实现: 如果limit价格被kline的high/low包含则成交