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包含则成交