金融与交易
用 VectorBT 回测交易策略时,按市场获取数据、用…
适用于需要基于 vectorbt 对股票、期货或加密货币策略进行历史回测、信号生成、参数优化、绩效分析与基准对比的场景。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
用 VectorBT 回测交易策略时,按特定
解决思路
- 安装/准备 Python 环境:包含 vectorbt、pandas、numpy、plotly。
- 选择数据源:OpenAlgo(印度市场)、DuckDB(直接数据库)、yfinance(美国/全球)、CCXT(加密)、自定义 provider。
- 使用 DuckDB 时同时支持自定义 DuckDB 和 OpenAlgo Historify 格式。
- 通过 python-dotenv + find_dotenv() 从项目根目录单个 .env 加载 API keys;绝不硬编码密钥。
- 技术指标默认使用 OpenAlgo ta(from openalgo import ta,100+ 指标,覆盖 trend/momentum/volatility/volume/oscillators/statistical/hybrid)。
- 仅当用户明确要求 TA-Lib/talib 时使用 TA-Lib。
- 无论使用哪个指标库,都不要使用 VectorBT 内置指标。
- 无 TA-Lib 等价物的 specialty 指标始终使用 openalgo.ta:Supertrend、Donchian、Ichimoku、HMA、KAMA、ALMA、ZLEMA、VWMA。
- 信号清理始终使用 openalgo.ta 的 exrem、crossover、crossunder、flip,不论使用哪个指标库。
- 费用模型:印度市场标准(STT + statutory charges + Rs 20/order)。
- 默认基准:通过 OpenAlgo 的 NIFTY 50(NSE_INDEX)。
- 图表:Plotly 使用 template="plotly_dark"。
- 环境变量从项目根目录单个 .env 通过 find_dotenv() 加载(从脚本目录向上查找)。
- 脚本放在 backtesting/{strategy_name}/ 目录(按需创建,不预先创建)。
- 代码或 logger 输出中绝不使用图标/emoji。
- 默认对全部技术指标使用 OpenAlgo ta(from openalgo import ta),包括 EMA、SMA、RSI、MACD、BBANDS、ATR、ADX、STDDEV、MOM 及另外 90+;仅当用户 prompt 明确要求 "talib"/"TA-Lib" 时才用 TA-Lib;绝不使用 vbt.MA.run()、vbt.RSI.run() 或任何 VectorBT 内置指标。
- 对 TA-Lib 完全没有的指标始终使用 OpenAlgo ta:Supertrend、Donchian、Ichimoku、HMA、KAMA、ALMA、ZLEMA、VWMA;即使用户选择 TA-Lib 也要用 openalgo.ta。
- 信号工具使用 OpenAlgo ta:ta.exrem()、ta.crossover()、ta.crossunder()、ta.flip();若 openalgo.ta 不可导入(standalone DuckDB),使用 inline exrem() fallback;参见 rules/duckdb-data.md。
- 生成原始买卖信号后始终用 ta.exrem() 清理信号;在 exrem 前始终 .fillna(False)。
- 按市场自动选择费用模型:印度(rules/indian-market-costs.md)、美国(rules/us-market-costs.md)、加密(rules/crypto-market-costs.md)。
- 默认基准:印度=NIFTY via OpenAlgo,美国=S&P 500(^GSPC),加密=Bitcoin(BTC-USD);参见 rules/data-fetching.md 的 Market Selection Guide。
- 每次回测后始终生成 Strategy vs Benchmark 对比表。
- 始终用通俗语言解释回测报告,让普通交易者理解风险与强度。
- Plotly candlestick 图表必须使用 xaxis type="category" 避免周末缺口。
- 股票始终设置 min_size=1, size_granularity=1 以使用整数股。
- 当用户提供 DuckDB 路径时,用 duckdb.connect() 直接加载数据并设置 read_only=True;自动检测格式:OpenAlgo Historify(表 market_data、epoch 时间戳)vs 自定义(表 ohlcv、date+time 列);参见 rules/duckdb-data.md。
- 查阅 rules/data-fetching.md:OpenAlgo(印度)、yfinance(美国)、CCXT(加密)、自定义 provider、.env 设置。
- 查阅 rules/simulation-modes.md:from_signals、from_orders、from_holding、direction 类型。
- 查阅 rules/position-sizing.md:Amount/Value/Percent/TargetPercent sizing。
- 查阅 rules/indicators-signals.md:OpenAlgo ta 指标参考(默认)、TA-Lib opt-in、信号生成。
- 查阅 rules/openalgo-ta-helpers.md:完整 OpenAlgo ta 目录(100+ 指标):exrem、crossover、Supertrend、Donchian、Ichimoku、MAs。
- 查阅 rules/stop-loss-take-profit.md:固定 SL、TP、trailing stop。
- 查阅 rules/parameter-optimization.md:broadcasting 和 loop-based optimization。
- 查阅 rules/performance-analysis.md:统计、指标、基准对比、CAGR。
- 查阅 rules/plotting.md:Candlestick(category x-axis)、VectorBT plots、自定义 Plotly。
- 查阅 rules/indian-market-costs.md:按 segment 的印度市场费用模型。
- 查阅 rules/us-market-costs.md:美国市场费用模型(stocks、options、futures)。
- 查阅 rules/crypto-market-costs.md:加密费用模型(spot、USDT-M、COIN-M futures)。
- 查阅 rules/futures-backtesting.md:Lot sizes(SEBI revised Dec 2025)、value sizing。
- 查阅 rules/long-short-trading.md:同时 long/short、direction comparison。
- 查阅 rules/duckdb-data.md:DuckDB direct loading、Historify format、auto-detect、resampling、multi-symbol。
- 查阅 rules/csv-data-resampling.md:加载 CSV、按印度市场 alignment resampling。
- 查阅 rules/walk-forward.md:Walk-forward analysis、WFE ratio。
- 查阅 rules/robustness-testing.md:Monte Carlo、noise test、parameter sensitivity、delay test。
- 查阅 rules/pitfalls.md:常见错误与 go live 前 checklist。
- 查阅 rules/strategy-catalog.md:带代码片段的策略参考。
- 查阅 rules/openstatz-tearsheet.md:OpenStatz 交互式离线 dashboard、指标、Monte Carlo(替代 QuantStats)。
- 使用 rules/assets/ 下生产就绪脚本(含真实费用、NIFTY 基准、对比表、通俗语言报告):EMA Crossover:assets/ema_crossover/backtest.py(EMA 10/20 crossover)。
- RSI:assets/rsi/backtest.py(RSI(14) oversold/overbought)。
- Donchian:assets/donchian/backtest.py(Donchian channel breakout)。
- Supertrend:assets/supertrend/backtest.py(Supertrend with intraday sessions)。
- MACD:assets/macd/backtest.py(MACD signal-candle breakout)。
- SDA2:assets/sda2/backtest.py(SDA2 trend following)。
- Momentum:assets/momentum/backtest.py(Double momentum (MOM + MOM-of-MOM))。
- Dual Momentum:assets/dual_momentum/backtest.py(Quarterly ETF rotation)。
- Buy & Hold:assets/buy_hold/backtest.py(Static multi-asset allocation)。
- RSI Accumulation:assets/rsi_accumulation/backtest.py(Weekly RSI slab-wise accumulation)。
- Walk-Forward:assets/walk_forward/template.py(Walk-forward analysis template)。
- Realistic Costs:assets/realistic_costs/template.py(Transaction cost impact comparison)。
- 标准回测脚本导入 os、datetime、timedelta、Path、numpy、pandas、vectorbt、dotenv 的 find_dotenv/load_dotenv、openalgo 的 api 和 ta。
- 设置 script_dir = Path(__file__).resolve().parent;load_dotenv(find_dotenv(), override=False)。
- 配置 SYMBOL、EXCHANGE、INTERVAL、INIT_CASH、FEES、FIXED_FEES、ALLOCATION、BENCHMARK_SYMBOL、BENCHMARK_EXCHANGE。
- 用 client = api(api_key=os.getenv("OPENALGO_API_KEY"), host=os.getenv("OPENALGO_HOST", "http://127.0.0.1:5000")) 创建客户端。
- 计算 end_date = datetime.now().date(),start_date = end_date - timedelta(days=365 * 3)。
- 用 client.history(symbol=SYMBOL, exchange=EXCHANGE, interval=INTERVAL, start_date=..., end_date=...) 获取数据。
- 若存在 timestamp 列,pd.to_datetime 并 set_index("timestamp");否则将 index 转为 datetime;排序;若 index 有 tz,则 tz_convert(None)。
- close = df["close"]。
- 用 ta.ema(close, 10) 和 ta.ema(close, 20) 计算 EMA。
- 生成 raw buy/sell:buy_raw = (ema_fast > ema_slow) & (ema_fast.shift(1) <= ema_slow.shift(1));sell_raw = (ema_fast < ema_slow) & (ema_fast.shift(1) >= ema_slow.shift(1))。
- entries = ta.exrem(buy_raw.fillna(False), sell_raw.fillna(False));exits = ta.exrem(sell_raw.fillna(False), buy_raw.fillna(False))。
- 用 vbt.Portfolio.from_signals(close, entries, exits, init_cash=INIT_CASH, size=ALLOCATION, size_type="percent", fees=FEES, fixed_fees=FIXED_FEES, direction="longonly", min_size=1, size_granularity=1, freq="1D") 回测。
- 获取 benchmark 数据:client.history(symbol=BENCHMARK_SYMBOL, exchange=BENCHMARK_EXCHANGE, interval=INTERVAL, start_date=..., end_date=...);同样规范化 timestamp/index、排序、tz_convert(None)。
- bench_close = df_bench["close"].reindex(close.index).ffill().bfill();pf_bench = vbt.Portfolio.from_holding(bench_close, init_cash=INIT_CASH, fees=FEES, freq="1D")。
- 打印 pf.stats()。
- 构建 comparison = pd.DataFrame({...}, index=["Total Return", "Sharpe Ratio", "Sortino Ratio", "Max Drawdown", "Win Rate", "Total Trades", "Profit Factor"]),Strategy 列用 pf.total_return()、pf.sharpe_ratio()、pf.sortino_ratio()、pf.max_drawdown()、pf.trades.win_rate()、pf.trades.count()、pf.trades.profit_factor(),Benchmark 列用 pf_bench 对应值,缺失填 "-";print(comparison.to_string())。
- 打印通俗解释:Total Return vs NIFTY、Max Drawdown,以及 worst temporary loss = abs(pf.max_drawdown()) * INIT_CASH。
- 用 fig = pf.plot(subplots=['value', 'underwater', 'cum_returns'], template="plotly_dark");fig.show() 绘图。
- 用 pf.positions.records_readable.to_csv(script_dir / f"{SYMBOL}_trades.csv", index=False) 导出交易记录。
- 尝试 from openalgo import ta;exrem = ta.exrem;ema = ta.ema;except ImportError 时,仅在 openalgo 包未安装的 standalone DuckDB 场景,import talib as tl;定义 ema(data, period) 返回 pd.Series(tl.EMA(data.values, timeperiod=period), index=data.index);定义 inline exrem(signal1, signal2) 循环实现。
- 配置 SYMBOL、DB_PATH、INIT_CASH、FEES、FIXED_FEES。
- 用 con = duckdb.connect(DB_PATH, read_only=True);df = con.execute("SELECT date, time, open, high, low, close, volume FROM ohlcv WHERE symbol = ? ORDER BY date, time", [SYMBOL]).fetchdf();con.close() 从 DuckDB 加载。
- df["datetime"] = pd.to_datetime(df["date"].astype(str) + " " + df["time"].astype(str));df = df.set_index("datetime").sort_index();df = df.drop(columns=["date", "time"])。
- 用 df.resample("5min", origin="start_day", offset="9h15min", label="right", closed="right").agg({"open":"first","high":"max","low":"min","close":"last","volume":"sum"}).dropna() 重采样到 5min;close = df_5m["close"]。
- 策略 + 回测同 OpenAlgo 模板,但使用上面解析出的 ema()/exrem()。
- 如果用户明确要求 TA-Lib,跳过 try/except 并直接 import talib as tl;exrem fallback 仅在 openalgo 本身不可用时使用。
适用边界 · 注意事项
- 不适用于非 Python/非 vectorbt 的回测环境。
- 未安装或无法访问 vectorbt、openalgo、DuckDB、数据源或 API keys 时不要使用。
- 不适用于需要完全避免 OpenAlgo/TA-Lib/第三方数据源或要求无代码 GUI 的场景。