From e9c93fe05a1fe3582a2ee39cd84611cf4a9810f9 Mon Sep 17 00:00:00 2001 From: hmo Date: Wed, 29 Jul 2026 22:52:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BB=84=E5=90=88=E6=A8=A1=E6=8B=9F?= =?UTF-8?q?=E5=90=AB=E4=BA=A4=E6=98=93=E8=B4=B9=E7=94=A8(=E5=BE=80?= =?UTF-8?q?=E8=BF=940.2%,=E6=B3=A2=E6=AE=B5=E5=8F=8C=E8=85=BF2=E5=80=8D)?= =?UTF-8?q?=E2=80=94=E2=80=94v1.0=E9=AB=98=E9=A2=91=E8=A2=AB=E8=B4=B9?= =?UTF-8?q?=E6=96=A9-11.1pp=E7=8E=B0=E5=8E=9F=E5=BD=A2,v6.1=E4=BB=A5?= =?UTF-8?q?=E5=90=AB=E8=B4=B9+41.5%=E5=B1=85=E9=A6=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strategy_lab.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/strategy_lab.py b/strategy_lab.py index a7525187..7a1bdabb 100644 --- a/strategy_lab.py +++ b/strategy_lab.py @@ -1073,9 +1073,16 @@ def portfolio_sim_full(trades, capital=1000000): return r -def portfolio_sim(trades, capital=1000000, max_positions=10): +COST_RATE = 0.002 # 往返交易费用率(佣金+印花税+滑点≈0.2%) + +def _trade_legs(t): + """波段类出场按2次往返计费""" + return 2 if t.get('exit_reason') in ('swing_re', 'swing_ptp') else 1 + +def portfolio_sim(trades, capital=1000000, max_positions=10, cost=True): """组合级模拟:固定等分仓位,按交易日历执行,返回最终资产/总收益/资产曲线回撤 - 规则:每日先结算到期仓位 → 再执行当日入场(仓位满跳过)→ 持仓按成本估值""" + 规则:每日先结算到期仓位 → 再执行当日入场(仓位满跳过)→ 持仓按成本估值 + 含交易费用:每笔往返扣 COST_RATE(2026-07-29 老爸:高频策略必须上费用天平)""" if not trades: return {} # 交易日历(用大盘指数日期) @@ -1107,6 +1114,8 @@ def portfolio_sim(trades, capital=1000000, max_positions=10): for p in open_pos: if p['exit_date'] <= day: cash += p['alloc'] * (1 + p['pnl'] / 100) + if cost: + cash -= p['alloc'] * COST_RATE * _trade_legs(p.get('trade', {})) else: still.append(p) open_pos = still @@ -1123,17 +1132,18 @@ def portfolio_sim(trades, capital=1000000, max_positions=10): cash -= alloc open_pos.append({ 'exit_date': add_days(t['entry_date'], t['hold_days']), - 'alloc': alloc, 'pnl': t['profit_pct'], + 'alloc': alloc, 'pnl': t['profit_pct'], 'trade': t, }) equity = cash + sum(p['alloc'] for p in open_pos) peak = max(peak, equity) max_dd = max(max_dd, (peak - equity) / peak * 100) # 期末结算全部 - final = cash + sum(p['alloc'] * (1 + p['pnl'] / 100) for p in open_pos) + final = cash + sum(p['alloc'] * (1 + p['pnl'] / 100 - (COST_RATE * _trade_legs(p.get('trade', {})) if cost else 0)) for p in open_pos) total_ret = (final - capital) / capital * 100 # 年化 days = len(cal) cagr = ((final / capital) ** (250 / days) - 1) * 100 if days > 0 and final > 0 else 0 + total_cost = capital - final + sum(1 for _ in []) # placeholder return { 'capital_final': round(final, 0), 'total_return_pct': round(total_ret, 1),