原创 · 约 8 分钟阅读 · 阅读 --
Last updated on
程序员量化交易实战 13:给策略参数做第一版网格搜索
程序员量化交易实战 13:给策略参数做第一版网格搜索
古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。
有了指标以后,可以开始比较参数。
第 13 篇先做最朴素的网格搜索:短均线窗口、长均线窗口、仓位比例三类参数组合起来,每组跑一次回测,然后按评分排序。它不聪明,但透明、可复现,适合作为后面大模型辅助策略研究的基线。

先不要急着让模型改策略
参数搜索最容易变成过拟合。
所以第一版先把过程写得足够清楚:候选参数怎么生成,哪些组合被过滤,评分怎么算,结果怎么排序。

参数候选
第 13 章新增 app/parameter_search.py。
@dataclass(frozen=True)
class ParameterCandidate:
short_window: int
long_window: int
position_ratio: float
候选生成时会过滤无效组合:
if short_window <= 1 or long_window <= short_window:
continue
if not 0 < position_ratio <= 1:
continue
这能避免出现短窗口大于长窗口、仓位比例为 0 或超过 100% 这类明显无意义参数。
每组参数都跑同一套回测
搜索函数会遍历候选参数:
backtest = run_signal_backtest(
symbol,
all_bars,
initial_cash=initial_cash,
position_ratio=params.position_ratio,
short_window=params.short_window,
long_window=params.long_window,
)
metrics = compute_performance_metrics(backtest.equity_curve, backtest.trades, initial_cash, backtest.max_drawdown)
这样第 10 篇的回测和第 12 篇的指标就串起来了。
评分要惩罚风险和无交易
当前评分函数很简单:
def score_search_result(result: ParameterSearchResult) -> float:
metrics = result.metrics
drawdown_penalty = abs(metrics.max_drawdown) * 0.5
turnover_penalty = max(0.0, metrics.turnover - 4.0) * 0.02
trade_penalty = 0.01 if metrics.trade_count == 0 else 0.0
return round(metrics.total_return - drawdown_penalty - turnover_penalty - trade_penalty, 6)
它不会保证最优,但能表达一个工程态度:收益不是唯一目标,深回撤、高换手和无交易候选都应该被扣分。
本章更新与代码仓库
本章更新内容:
- 新增
app/parameter_search.py。 - 实现参数网格生成、候选回测、指标计算、风险惩罚评分和结果 payload。
- 新增
tests/test_parameter_search.py,覆盖无效参数过滤、排序和空数据边界。
代码仓库:
https://github.com/ax2/zi-quant-platform
本章代码:
git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-13
uv sync --extra dev
uv run pytest tests/test_parameter_search.py
第 13 章全量测试通过:179 passed,仍只有既有 FastAPI deprecation warning。
本篇小结
参数搜索不是为了榨出漂亮收益,而是为了让策略候选的产生过程可复查。
第 13 篇把参数候选、回测、指标和排序串起来。下一篇把候选结果保存成实验记录,为后面的策略晋升做准备。