/~learn/s/c328de79
> 📅 2026-09-21 建立 > > 本文把「把 K 线取对数 → 在对数价格空间做择时 → 回测验证」这条链路完整走一遍,并给出在 6 个品种、16 年样本上的实证结果。 > > 配套的两份东西: > - 代码:LogPriceStrategy.py(策略类)+ log_price_backtest.py(回测脚本)+ test_log_price_strategy.py(TDD 单元测试,8/8 通过) > - 流程:策略研发标准化流程-从策略基类到GA优化到策略池.md(本策略就是照那条 SOP 落地的) > > 本文回答三个问题: > 1. 为什么把价格取对数,就能体现年化?(第一节 · 原理) > 2. 「对数回归」这个实验怎么把年化算出来,结果如何?(第二节 · 验证) > 3. 基于对数价水平 / 一阶导 / 二阶导能做出什么策略,回测表现如何?(第三、四、五节)
---
对数价格 ln(P) 对时间做最小二乘回归,斜率 × 252 就是连续复利年化——这验证了"取对数就能体现年化"。基于对数时间序列构造的四种择时信号里,对数价一阶导(趋势)且平滑窗口 ≈ 20 个交易日是全场最强、最稳健的信号:它在 6 个品种上全部取得正收益(年化 5.4%~17.1%),且在 5 个品种上是第一名;相反,日频(未平滑)的对数一阶导和二阶导基本是噪声,而"三者同时成立"的 composite 组合信号资金占用只有约 20%,几乎没有实战价值。
---
记价格为 $P_t$,对数价格为 $\ell_t = \ln P_t$。三个关键性质:
$$\ln P_t - \ln P_{t-k} = \ln\frac{P_t}{P_{t-k}} \approx k \text{ 期的收益率}$$
普通收益率是连乘的($1+r_1)(1+r_2)\cdots$),取对数后变成连加。这带来两个好处:
如果 $\ell_t \approx a + b\cdot t$($t$ 为交易日序号),那么 $b$ 就是每个交易日的对数收益,于是:
$$\text{连续复利年化} = e^{\,b \times 252} - 1$$
这就是"取完对数后能体现出年化"的数学来源:对 ln(P) 做线性回归,斜率直接对应年化收益。
> 🌟 这条是后文最重要的"先验指标":先看 $R^2$,再决定要不要在这个品种上用趋势类对数信号。
---
log_price = np.log(close)
t = np.arange(len(log_price))
b, a = np.polyfit(t, log_price, 1) # 斜率 b = 日均对数收益
annualized = np.exp(b * 252) - 1 # 连续复利年化
r2 = 1 - ss_res / ss_tot # 拟合优度
样本:2010-01-01 ~ 2025-12-31 日线,6 个品种(数据来自 akshare 新浪指数日线,全历史)。
| 品种 | 名称 | 日均对数收益 | 连续复利年化 | $R^2$(趋势稳定性) | 样本数 |
| ------ | ------ | ------------ | ---------------- | -------------- | -------- |
| 399102 | 创业板综 | 0.000356 | 9.39% | 0.6104 | 3732 |
| 399006 | 创业板指 | 0.000285 | 7.43% | 0.5251 | 3787 |
| 000913.SH | 沪深300医药卫生 | 0.000226 | 5.86% | 0.4879 | 3886 |
| 000933.SH | 中证医药卫生 | 0.000168 | 4.33% | 0.3883 | 3886 |
| 399300 | 沪深300 | 0.000140 | 3.60% | 0.4616 | 3886 |
| 399001 | 深证成指 | 0.000032 | 0.80% | 0.0384 | 3886 |
读表:
---
LogPriceStrategy
文件:LogPriceStrategy.py · class LogPriceStrategy(Strategy)
在对数价格空间构造 3 个基础指标 + 1 个组合信号:
| signal_type | 定义 | 直觉 |
| ------------- | ------ | ------ |
level | level = ln(P) − MA(ln(P), level_window),取 level > 0 | 对数价高于自身中枢 → "偏高/偏强" |
d1 | d1 = ln(P).diff(smooth_window),取 d1 > 0 | 对数价一阶导(趋势)向上 → 上涨中 |
d2 | d2 = d1.diff(1),取 d2 > 0 | 对数价二阶导(加速度)向上 → 涨势在加速 |
composite | level>0 且 d1>0 且 d2>0 | 三者同时成立的 AND |
持仓口径:指标全部只用截止到 t 日(含)的数据,仓位 position[i] = raw_signal[i-1](严格 shift 1 天),杜绝未来函数;signal_offset 参数可再额外延后成交时点。
暴露的参数(四者同名,符合 SOP 的「形参名 = 属性名 = params_grid key = 基因名」约定):
| 参数 | 含义 | params_grid 边界 |
| ------ | ------ | ------------------ |
signal_type | 信号类型(枚举) | ['level','d1','d2','composite'] |
smooth_window | d1 的差分窗口,1=日频 | (1, 60) |
level_window | level 的中枢均线窗口 | (3, 250) |
signal_offset | 信号额外延迟天数 | [0, 1, 2] |
参数边界声明:params_grid.py · LogPriceStrategy_params
---
运行:
python -m adata.aohan.quant.chart_test.log_price_backtest
口径:9 组代表性固定参数(尚未做 GA 优化,纯基线),下表为「总回报 / 年化(annual_return)」。
| 品种\信号 | level-20 | level-60 | level-120 | d1-1 | d1-5 | d1-20 | d2-1 | d2-5 | composite |
| ------------ | --------- | --------- | ---------- | ------ | ------ | ---------- | ------ | ------ | ----------- |
| 000933.SH | 104.3% | 66.1% | −26.3% | 53.0% | 3.1% | 259.9% | 195.0% | 102.8% | 16.2% |
| 000913.SH | 77.9% | 24.7% | 21.9% | 86.0% | −6.1% | 181.2% | 182.8% | 98.4% | −6.8% |
| 399300 | 34.4% | 53.1% | 48.8% | −44.7% | 11.1% | 117.1% | −45.1% | −12.5% | 36.4% |
| 399102 | 337.3% | 165.3% | 197.9% | 67.9% | 141.4% | 702.5% | 96.5% | 81.8% | 5.3% |
| 399006 | 357.2% | 166.3% | 127.9% | −4.1% | 130.2% | 1066.2% | 135.5% | 77.0% | −2.6% |
| 399001 | 58.6% | 51.3% | 8.2% | −62.0% | −43.9% | 132.3% | −53.2% | −0.6% | 6.9% |
(加粗 = 该品种最优;level-20 表示 level_window=20,d1-20 表示 smooth_window=20,以此类推。)
| 品种\信号 | level-20 | level-60 | level-120 | d1-1 | d1-5 | d1-20 | d2-1 | d2-5 | composite |
| ------------ | --------- | --------- | ---------- | ------ | ------ | ---------- | ------ | ------ | ----------- |
| 000933.SH | 4.57% | 3.22% | −1.89% | 2.69% | 0.19% | 8.33% | 7.00% | 4.52% | 0.94% |
| 000913.SH | 3.66% | 1.39% | 1.25% | 3.95% | −0.39% | 6.67% | 6.71% | 4.37% | −0.44% |
| 399300 | 1.86% | 2.70% | 2.52% | −3.63% | 0.66% | 4.96% | −3.68% | −0.83% | 1.96% |
| 399102 | 10.07% | 6.55% | 7.36% | 3.43% | 5.90% | 14.50% | 4.49% | 3.96% | 0.34% |
| 399006 | 10.24% | 6.48% | 5.43% | −0.27% | 5.49% | 17.06% | 5.65% | 3.73% | −0.17% |
| 399001 | 2.93% | 2.62% | 0.49% | −5.87% | −3.55% | 5.41% | −4.64% | −0.04% | 0.42% |
---
d1 + smooth_window ≈ 20 是全场最强、最稳健的信号。6 个品种全部取得正收益,在 000933.SH / 399300 / 399102 / 399006 / 399001 上均为第一名,仅在 000913.SH 上以微弱差距(6.67% vs 6.71%)位列第二。这意味着:"约一个月的对数收益趋势为正就持有" 这个极简规则,是这批实验里最值得复用的核心信号。
在 3 个宽基指数上巨亏(399300 −44.7%、399001 −62.0%、399006 −4.1%),交易近千次。原因是单日对数收益符号几乎无自相关性,频繁反向交易被摩擦成本吃光。教训:对数趋势必须做足够长的平滑,否则就是在赌硬币。
在医药指数上表现很好(000933.SH d2-1: 195.0%、000913.SH d2-1: 182.8%),但在宽基上很糟(399300 −45.1%、399001 −53.2%)。二阶导对噪声更敏感,不适合做通用信号,只适合在特定品种上单独优化。
level_window=20 普遍优于 120;创业板系尤其亮眼(399006 level-20: 357.2%、399102 level-20: 337.3%)。但代价是最大回撤偏大(−46%~−57%)。level 本质是"均值回归式追涨",在趋势强的品种上吃满主升浪。
资金占用仅 ~20%,年化 0 附近徘徊(甚至为负)。条件过于苛刻 → 出手极少 → 收益被稀释。建议弃用,或改为 OR(任一成立)/加权复合。
$R^2$ 高的品种(399102=0.61、399006=0.53),其 d1-20 年化也最高(14.5%、17.1%);$R^2$ 极低的 399001(0.04),所有趋势类信号几乎全线失效。实操上:先算对数回归 $R^2$,只对 $R^2$ 达标的品种上趋势类对数信号。
---
d1(对数价一阶导)且 smooth_window ≈ 20(约一个月)。d1-1(日频)、d2-1(日频)、composite(AND 组合)。
LogPriceStrategy 接入 params_deep_seek.py 的 strategy_configs,重点在 signal_type='d1'、smooth_window ∈ (10, 40) 区间精调,其他信号作为对照。shift(1),但仍需按 SOP 手工再 shift(1) 跑一次对比收益是否缩水 —— 本次仅完成编码级防未来函数,终检尚未执行。add_strategy_to_board 注册进 timing_config.py。---
# 1. 单元测试(8/8 通过,验证四种信号 + 防未来函数契约)
python -m pytest tests/adata_test/quant/test_log_price_strategy.py -v
# 2. 对数回归 + 回测(默认 6 品种,也可传入自定义代码)
python -m adata.aohan.quant.chart_test.log_price_backtest
python -m adata.aohan.quant.chart_test.log_price_backtest 399006 399102
数据来源说明:本项目 fetch_data 对纯数字指数代码(如 399102)的路由不稳定(会返回空 DataFrame);
本脚本改用 akshare stock_zh_index_daily(全历史、稳定,全项目已有多处使用),
并保留 fetch_data 作为回退。代码映射规则见 _to_akshare_symbol。
---