// Package backtest 提供可转债量化回测引擎(MVC Service 层)。 // 采用事件驱动模式:按交易日推进,策略在任意交易日返回目标持仓, // 引擎以当日收盘价成交并逐日记录组合净值。 package backtest import ( "context" "sort" "stock-analysis/internal/model" ) // Strategy 定义可插拔的回测策略接口。 // 用户实现该接口即可自定义轮动/网格等策略,无需关心成交与持仓细节。 type Strategy interface { // Name 返回策略名称(用于结果标识)。 Name() string // OnBar 每个交易日调用。返回 nil 表示当日不调仓; // 返回目标持仓时,引擎按各标的权重以当日收盘价调仓。 OnBar(ctx context.Context, date string, universe []Quote, hist *History) ([]Target, error) } // Quote 某转债在某一交易日的基本行情快照。 // 溢价率数据来自基本面入库(cmd/fundamentals 步骤3),未计算时为 0。 type Quote struct { Code string Price float64 // 收盘价 Open float64 High float64 Low float64 Volume int64 ConvertValue float64 // 转股价值(元) PremiumRate float64 // 转股溢价率(%) } // Target 目标持仓:转债代码 → 组合权重(0~1,各权重之和应为 1)。 type Target struct { Code string Weight float64 } // History 提供全量历史K线查询,策略可访问任意代码任意日期的历史行情。 type History struct { klines map[string][]model.Kline // code → 按日期升序的K线 } // CloseOn 返回 code 在 date 当日(或之前最近交易日)的收盘价。 // 用于处理调仓时个别持仓当日停牌/退市等无报价的情况。 func (h *History) CloseOn(code, date string) (float64, bool) { ks, ok := h.klines[code] if !ok { return 0, false } // 二分查找最近一根 <= date 的K线。 i := sort.Search(len(ks), func(i int) bool { return ks[i].Date > date }) if i == 0 { return 0, false } return ks[i-1].Close, true }