optz
This commit is contained in:
41
labs/analysis/etf/capital.py
Normal file
41
labs/analysis/etf/capital.py
Normal file
@@ -0,0 +1,41 @@
|
||||
"""读仓库 _etf.yaml 后,先定"要多大的账户才铺得开",再跑基准回测。
|
||||
|
||||
用法: py -3.14 -B analysis/etf/capital.py
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
sys.path.insert(0, str(HERE))
|
||||
|
||||
import backtest as B # noqa: E402
|
||||
from backtest import SYMBOL_PARAMS, SYMBOLS, SYMBOL_PARAMS, analyze, fetch_daily, simulate # noqa: E402
|
||||
|
||||
data = {code: fetch_daily(code) for code in SYMBOLS}
|
||||
|
||||
print("== 新配置的资金需求(按区间最低价估算)==")
|
||||
need = {}
|
||||
for code, p in SYMBOL_PARAMS.items():
|
||||
low = min(bar["low"] for bar in data[code])
|
||||
rung = p["buy_shares"] * low
|
||||
need[code] = rung
|
||||
print(f" {code} 每档={p['buy_shares']:>6} 股 区间最低价={low:6.3f} "
|
||||
f"1 档≈{rung:9.0f} 10 档≈{rung * 10:10.0f} 单标上限={p['max_shares']} 股")
|
||||
print(f" 三只各铺 1 档 ≈ {sum(need.values()):,.0f};三只铺满 10 档 ≈ {sum(need.values()) * 10:,.0f}")
|
||||
|
||||
print()
|
||||
print("== 不同起始资金(参数完全不变,只改账户规模)==")
|
||||
print(f"{'起始资金':>10} {'权益变动':>10} {'收益率':>7} {'最大回撤':>8} {'平均占用':>8} "
|
||||
f"{'峰值占用':>8} {'资金拒绝':>8} {'底仓':>4} {'补仓':>4} {'主出口':>5}")
|
||||
for cash in (200_000, 300_000, 500_000, 800_000, 1_200_000, 1_500_000):
|
||||
result = simulate(data, start_cash=cash)
|
||||
stats = analyze(result)
|
||||
delta = stats["final_equity"] - cash
|
||||
print(f"{cash:10,.0f} {delta:10.2f} {stats['return_pct']:6.2f}% {stats['max_dd_pct']:7.2f}% "
|
||||
f"{stats['avg_deployed'] / cash * 100:7.2f}% {stats['max_deployed'] / cash * 100:7.2f}% "
|
||||
f"{'':>8} {sum(1 for f in result['fills'] if f.kind == 'base'):4} "
|
||||
f"{sum(1 for f in result['fills'] if f.kind == 'add'):4} "
|
||||
f"{sum(1 for f in result['fills'] if f.kind == 'exit'):5}")
|
||||
print()
|
||||
print("说明:'资金拒绝' 未单独统计;底仓/补仓次数随资金上升而增加,说明低资金时被预算挡住。")
|
||||
Reference in New Issue
Block a user