From a3d23c945089e179f99998de52cd62f0e4f91609 Mon Sep 17 00:00:00 2001 From: hmo Date: Thu, 30 Jul 2026 18:18:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=AD=96=E7=95=A5=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E5=BA=93+API=E8=BF=94=E5=9B=9Edescription+=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=E5=88=97(=E5=85=A8=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E7=AE=97=E6=B3=95/=E6=80=9D=E8=B7=AF/=E8=AF=81=E6=8D=AE?= =?UTF-8?q?=E8=AF=A6=E5=B0=BD=E8=AE=B0=E5=BD=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.py | 7 ++- static/index.html | 10 +++ strategy_lab.py | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-) diff --git a/server.py b/server.py index 54e9bc6b..634d7089 100644 --- a/server.py +++ b/server.py @@ -537,9 +537,12 @@ def get_tracking(): def api_research_strategies(): """策略版本列表(含回测结果摘要,支持 period_tag 区间过滤)""" try: - from strategy_lab import list_strategies + from strategy_lab import list_strategies, STRATEGY_DESCRIPTIONS pt = request.args.get('period_tag') - return jsonify({'strategies': list_strategies(period_tag=pt)}) + strats = list_strategies(period_tag=pt) + for s in strats: + s['description'] = STRATEGY_DESCRIPTIONS.get(s['version'], {}) + return jsonify({'strategies': strats}) except Exception as e: return jsonify({'error': str(e)}), 500 diff --git a/static/index.html b/static/index.html index d638f0db..a21099a7 100644 --- a/static/index.html +++ b/static/index.html @@ -1972,6 +1972,14 @@ async function loadStrategyList() { } const ASC_DEFAULT = new Set(['max_dd']); // 回撤类:小=好,默认升序 +function showDesc(version) { + const s = (window._strats || []).find(x => x.version === version); + const d = s && s.description; + if (!d || !d.title) return alert('暂无说明'); + const text = `【${d.title}】\n\n【算法】${d.algorithm || ''}\n\n【思路】${d.rationale || ''}\n\n【证据】${d.evidence || ''}`; + alert(text); +} + function sortBy(key) { if (window._sortKey === key) { window._sortDir = window._sortDir === 'desc' ? 'asc' : 'desc'; @@ -2102,6 +2110,7 @@ function renderStrategyTable(strategies) { let html = '
' + th('version', '版本', 'text-left') + th('name', '名称', 'text-left') + th('sizing_slots', '仓位', 'text-center') + + '' + th('composite', '综合', 'text-right') + th('universality', '普适', 'text-right') + th('full_return', '全参与', 'text-right') + @@ -2123,6 +2132,7 @@ function renderStrategyTable(strategies) { html += '' + '' + '' + + '' + '' + cell('composite', s._composite, v => v + (s._confidence != null && s._confidence < 1 ? '×' + s._confidence.toFixed(2) + '' : ''), 'font-bold text-amber-300') + cell('universality_score', (st.universality || {}).score, v => v + '/' + (st.universality || {}).months + '月') + diff --git a/strategy_lab.py b/strategy_lab.py index 8a8376d8..7bd69ff5 100644 --- a/strategy_lab.py +++ b/strategy_lab.py @@ -329,6 +329,163 @@ STRATEGIES.update({ }) +# ══════════════════════════════════════════════════════ +# 策略详尽说明(给老爸和未来的我看 — 2026-07-30 记录) +# ══════════════════════════════════════════════════════ +STRATEGY_DESCRIPTIONS = { + "v1.0": { + "title": "多因子基线(五因子评分≥45 + 动量≥8)", + "algorithm": "入场: 五因子评分(趋势0-25+动量0-20+量能0-20+波动率0-15+风险0-20)≥45 且动量分≥8。出场: 10%止盈 / 2×ATR止损 / 20天。仓位: 半Kelly。", + "rationale": "验证多因子评分体系的基础有效性,是所有版本的基线参照。", + "evidence": "2年55.3%/+28.2%(年化12.8%), 5年46.9%/-10.5%(年化-2.2%)。高频(1万+笔/2年)靠量取胜, 跨周期亏损。费用-11pp是高频致命伤。", + }, + "v2.0": { + "title": "趋势动能过滤(v1+MACD柱>0+ROC>2+ADX≥20+ATR%≥2.8)", + "algorithm": "v1.0基础上加: MACD柱>0, ROC>2, ADX≥20(趋势强度), ATR%≥2.8(排除死鱼股)。", + "rationale": "v1归因: MACD>0.69胜率54%vs33%, ROC>11胜率57%vs35%。过滤无趋势/无动能/死鱼股。", + "evidence": "2年胜率52.9%/+24.4%。过滤后交易减半但胜率+6pp。", + }, + "v3.0": { + "title": "强动量+优盈亏比(ROC≥8+距MA20≥4%+量比1.0~1.8;止盈15%/止损1.5ATR)", + "algorithm": "v2 + ROC≥8, dist_ma20≥4%, vol_ratio 1.0~1.8。出场改: 15%止盈/1.5×ATR止损(RR从1.1:1提到2.2:1)。", + "rationale": "v2归因: 均亏-9.14%≈止盈10%, RR仅1.1:1是盈亏比恶化主因。收紧止损放大止盈。", + "evidence": "2年+37.9%(年化16.9%)。均赢14.4%vs均亏-7.7%。夏普从-0.10→+1.57。", + }, + "v4.0": { + "title": "大盘回调+趋势结构(v3+大盘MA20上+斜率<0+hh结构)", + "algorithm": "v3 + 大盘在MA20上且MA20斜率<-0.05(上升中回调) + 个股更高高点(hh)结构。", + "rationale": "v3归因: 大盘MA20斜率-1.76~-0.56时胜率58.8%vs平坡20.6%(差38pp最强信号)。回调买是核心边缘。", + "evidence": "仅5笔交易(80%胜率/+9.51%)。过滤器叠加过拟合的教训——分桶样本仅36笔/桶时不能叠加6个过滤器。", + }, + "v4.0f": { + "title": "单放量比(v4.0消融: 量比0.9~2.0)", + "algorithm": "v4.0只放宽量比带1.2~1.5→0.9~2.0, 其余全保持。", + "rationale": "消融实验找瓶颈: 量比带是v4.0最大限制。", + "evidence": "5笔→15笔, 胜率73.3%/盈亏比2.92。证明量比窄带误杀高质量交易。", + }, + "v5.0": { + "title": "量比+ATR融合(v4.0+量比0.9~2.0+ATR2.8~6.5)", + "algorithm": "v4.0 + 量比0.9~2.0 + ATR% 2.8~6.5(消融胜出的双放宽融合)。", + "evidence": "24笔/66.7%胜率/+6.03%。但21/24笔集中2026-04月——单一市场情景,普适性差。", + }, + "v6.0": { + "title": "资金流过滤(v4.0f+资金5日净占比>-2.5)", + "algorithm": "v4.0f + flow_5d>-2.5(排除主力持续流出)。", + "rationale": "资金流归因: flow_5d<-2.7的持续流出组胜率仅37.5%, 其余55-78%。", + "evidence": "34笔/70.6%胜率/+7.93%。资金数据仅2025-11月起, 5年无法验证。", + }, + "v6.1": { + "title": "板块不追高(v4.0f+板块MA20斜率≤1.0)", + "algorithm": "v4.0f + 板块MA20斜率≤1.0(排除已强涨板块)。", + "rationale": "板块归因: sector_slope>1.04的强涨板块入场胜率仅27.3%, 回调/横盘板块80%。与大盘/个股'回调买'三层同构。", + "evidence": "2年148笔/61.5%/+5.17%, 5年+12.9%(年化2.4%)。v6.1曾被误为最强(数据未统一时), 现证实v6.1-2.5+板块斜率≤1.0)", + "algorithm": "v4.0f + flow_5d>-2.5 + 板块MA20斜率≤1.0。", + "evidence": "28笔/82.1%胜率/+10.07%/回撤9.68%。但仅2月分布=单窗口运气, 置信系数×0.23打落榜首。", + }, + "v7.0": { + "title": "分批止盈(v6.1+50%@+8%落袋+50%@+15%)", + "algorithm": "v6.1入场不变; 出场改分批: 50%仓在+8%落袋, 50%仓在+15%落袋, 止损不变。", + "rationale": "亏损尸检: 12笔亏损9笔为止损出局——先到+8%落袋一半可将部分止损单转为盈利单。", + "evidence": "2年胜率64.2%→72.5%但均收益5.94%→4.95%(截断大赢家)。胜率换收益的典型。", + }, + "v7.1": { + "title": "尸检因子过滤(v6.1+hl结构+RSI增量≥6)【当前实盘基线】", + "algorithm": "入场: 评分≥45+动量≥8+ADX≥20+ATR3.5~5.5%+ROC10~25+MACD柱0.25~1.3+dist_ma20≥4%+量比0.9~2.0+ma20_slope≤1.5+大盘MA20上+大盘ADX≥20+大盘斜率≤-0.05+hh+hl+RSI增量≥6+板块斜率≤1.0。出场: 15%止盈/1.5×ATR止损/20天。", + "rationale": "亏损尸检: 盈利组100%具备hl结构(亏损组仅75%), RSI增量赢11.3vs亏6.1——动量加速度区分输赢。", + "evidence": "2年64.7%/+22.2%(年化10.2%), 5年56.3%/+29.3%(年化5.2%)。趋势强化后震荡年0笔、牛市85%。当前实盘策略。", + }, + "v7.1b": { + "title": "v7.1+动量基因缩放(DNA票仓位×2.5)", + "algorithm": "v7.1全执行; 收缩突破动量基因票(ATR处20日最低1/4位+破20日新高+量比>1.2)仓位×2.5, 其余×1.0。", + "rationale": "v7.1的75笔中15笔带收缩突破DNA(80-91.7%胜率/+10.22% vs 无基因70%/+6.75%), ×2.5重仓它们。", + "evidence": "原版+25.6%→缩放+38.9%, 回撤2.8%→1.8%。信念缩放完美兑现: 基因票更可靠, 重仓反而降风险。", + }, + "v7.2": { + "title": "尸检+分批(v7.1入场+分批止盈出场)", + "algorithm": "v7.1入场 + v7.0的分批止盈出场(50%@+8%+50%@+15%)。", + "evidence": "2年74笔/79.7%胜率(最高)/+6.59%/回撤0.9%(最低)。稳定王但均收益被分批截断。", + }, + "v7.3": { + "title": "资金+板块+分批(v6.2入场+分批出场)", + "algorithm": "v6.2入场 + 分批止盈出场。", + "evidence": "28笔/85.7%胜率(最高)/+7.92%/回撤9.68%。仅12月+数据, 小样本。", + }, + "v8.0": { + "title": "趋势持有·结构出场(v7.1入场+破MA10两日/破MA20/横盘出货识别)", + "algorithm": "v7.1入场; 出场改结构驱动: 连续2日收破MA10 或 收破MA20 或 高位放量滞涨(5日振幅<4%+均量>前20日1.3倍) → 出场。无固定目标, 最长40天。", + "rationale": "固定15%目标截断利润——拉伸段不必早出场, 让利润奔跑至结构破位。", + "evidence": "2年均亏-5.31%→-2.81%(砍亏最快), 盈亏比5.06(最高), 100%执行±0.0%方差(完全确定)。风控之王。", + }, + "v8.1": { + "title": "波段先出再进(v7.1入场+MA10波段出场)【当前最优单策略】", + "algorithm": "v7.1入场; 出场改波段: 跌破MA10先出(锁利润), 收回MA10且突破前一日高点再进(吃下一波), 各段复合, 最长60天。", + "rationale": "拉伸段不出场, 调整时先出再进——破MA10锁定利润, 结构恢复再进场吃下一波。", + "evidence": "2年70.6%/+37.5%(年化16.7%), 5年57.3%/+40.5%(年化6.9%)。均赢+21.78%(最高单笔经济性), 牛市100%全胜, 真波段(44次先出+10次再进验证)。收益王。", + }, + "v8.3": { + "title": "波段40天(v8.1持仓60→40天)", + "algorithm": "v8.1持仓期60天→40天。", + "evidence": "+9.99%(vs v8.1的60天版+12.6%), 保住80%收益但资金周转快1/3。", + }, + "v9.0": { + "title": "周线趋势过滤(v7.1+周线收盘须站上周线MA10)", + "algorithm": "v7.1 + 周线close>周线MA10(中期趋势向上才买)。", + "evidence": "23笔/60.9%。被证据否决: v7.1交易中weekly_up=False胜率78.4%vsTrue60.9%——周线破位恰恰是回调买点本身, 与回调买入逻辑冲突。", + }, + "v9.1": { + "title": "周线多头排列(v7.1+周线MA10>MA20)", + "algorithm": "v7.1 + 周线MA10>MA20(周线均线多头排列)。", + "evidence": "59笔/69.5%/+6.92%。比weekly_up更严但同样与回调逻辑部分冲突。", + }, + "v9.2": { + "title": "周线破位日线强(v7.1+周线收盘须低于周线MA10)", + "algorithm": "v7.1 + 周线close<周线MA10(反向利用: 周线级回调中的日线动量回归正是回调策略核心边缘)。", + "rationale": "v9归因反用: v7.1交易中weekly_up=False胜率78.4%vsTrue60.9%。", + "evidence": "2年/5年都是72.5%胜率(跨周期最高), 回撤0.9%(最低), 2023震荡年0笔(完全避开)。稳定王/防守首选。", + }, + "v11.0": { + "title": "波段·枢轴版(v8.1入场+破弱支撑先出/收复弱压再进)", + "algorithm": "v8.1入场; 出场改枢轴体系: 破弱支撑(2×PP-H)先出, 收复弱压(2×PP-L)且创新高再进。", + "evidence": "3仓+116.4%/回撤1.7%但实为'纯趋势硬扛60天'(弱撑随趋势上移从不触发, swing从未发生), 非真波段。集中运气, 全参与仅+28.9%现原形。", + }, + "v11.1": { + "title": "强压止盈弱撑止损(v7.1入场+枢轴强压止盈/弱支撑止损)", + "algorithm": "v7.1入场; 出场改实盘口径: 强压(PP+有效区间)止盈 + 弱支撑(2×PP-H)止损。", + "evidence": "+52.0%vs v7.1固定出场的+74.6%——裸枢轴强压太远(够不着)、弱撑太近(老被洗), 固定15%/1.5ATR更优。证明固定百分比出场比裸枢轴更适合v7.1类策略。", + }, + "v11.2": { + "title": "真波段+枢轴减半(v8.1+弱支撑止损+强压减半仓)【已否决】", + "algorithm": "v8.1真波段 + 弱支撑止损 + 强压减半仓。", + "evidence": "77%被洗出场(弱支撑日内贴身位当止损=自杀)。强压减半砍掉大赢腿(+32.4%vs v8.1的+93.2%)。枢轴S/R不适用于出场。", + }, + "v_combo": { + "title": "组合·v8.1波段+B20动量(并集)", + "algorithm": "v8.1回调入场(波段出场) + B严格收缩突破动量入场(ATR最低1/4位+破20日新高+量比>1.5+评分≥50+ROC>4+大盘MA20上+大盘ADX≥20, 20%宽止盈/1.5ATR止损), 两族信号并集去重。", + "rationale": "回调族(v7.1系)与动量族(B突破)信号零重叠——一个抓跌出来的机会, 一个抓涨出来的机会, 两行情段全覆盖。", + "evidence": "2年219笔/57.5%/+7.10%/组合+47.9%/回撤1.6%/98%执行。但5年验证2023/2024震荡转折年亏损(B动量族假突破)——v8.1主策略, B只配强牛增强。", + }, + "v_next": { + "title": "v8.1+三重信念×2(DNA+行业ADX≥20+资金加速度, 均衡版)【当前最优】", + "algorithm": "v8.1波段出场基座 + 三重已验证信念信号分级重仓(×2): 动量基因(DNA,62.5%胜率)/行业趋势强(行业ADX≥20,69%胜率+16.31%)/资金加速(flow_delta>0,100%胜率+16.74%)。其余×1.0。", + "rationale": "v8.1波段单笔最优(均赢+21.78%), 叠加三重信念放大优质交易——分得清好坏才配重仓。", + "evidence": "全参与+48.2%(年化8.8%)/回撤4.1%。×2票69%胜率/+14.23% vs ×1票48%/+5.99%。收益最高且可解释可复现经5年验证。当前最优策略。", + }, + "h1.0": { + "title": "港股v1-全堆(过拟合教训)", + "algorithm": "v7.1港股化全堆: ATR无上限+量比无上限+MACD窄幅0~0.3+周线向上。", + "evidence": "仅2笔交易——过滤器全堆导致过拟合, 证明弱信号(MACD窄幅±3pp)不能进过滤器。", + }, + "h1.1": { + "title": "港股v1.1-三强信号(ATR/量比无上限+周线向上)", + "algorithm": "v7.1港股化仅三处: ATR无上限+量比无上限+周线必须向上。", + "evidence": "27笔/59.3%/+4.56%——与v7.1港股基线(26笔/61.5%/+4.03%)打平, 港股无需单独调参。", + }, +} + + def get_strategy(version): if version not in STRATEGIES: raise ValueError(f"未知策略版本: {version},可用: {list(STRATEGIES.keys())}")
说明
' + s.version + (isCurrent ? ' 当前' : '') + ((s.market && s.market !== 'all') ? ' ' + (s.market === 'hk' ? '港' : 'A') + '' : '') + '' + (s.name || '') + (smallSample ? ' ⚠️' : '') + '' + ((s.description && s.description.title) ? '' : '') + '' + (st.sizing_slots ? st.sizing_slots + '仓' : '10仓') + '