991 lines
33 KiB
Markdown
991 lines
33 KiB
Markdown
|
|
# RaptorBT 使用手册(含 ferro-ta 扩展版)
|
|||
|
|
|
|||
|
|
> 基于 RaptorBT v0.4.1,集成 ferro-ta 指标库,提供 80 个技术指标
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 目录
|
|||
|
|
|
|||
|
|
- [项目简介](#项目简介)
|
|||
|
|
- [安装与部署](#安装与部署)
|
|||
|
|
- [快速开始](#快速开始)
|
|||
|
|
- [策略类型](#策略类型)
|
|||
|
|
- [指标完整参考](#指标完整参考)
|
|||
|
|
- [趋势指标 (Trend)](#趋势指标-trend)
|
|||
|
|
- [动量指标 (Momentum)](#动量指标-momentum)
|
|||
|
|
- [波动率指标 (Volatility)](#波动率指标-volatility)
|
|||
|
|
- [强度指标 (Strength)](#强度指标-strength)
|
|||
|
|
- [成交量指标 (Volume)](#成交量指标-volume)
|
|||
|
|
- [价格变换指标 (Price Transform)](#价格变换指标-price-transform)
|
|||
|
|
- [统计指标 (Statistic)](#统计指标-statistic)
|
|||
|
|
- [P0 扩展指标 (P0 Extended)](#p0-扩展指标-p0-extended)
|
|||
|
|
- [周期变换指标 (Hilbert Transform / Cycle)](#周期变换指标-hilbert-transform-cycle)
|
|||
|
|
- [市场状态检测 (Market Regime)](#市场状态检测-market-regime)
|
|||
|
|
- [投资组合工具 (Portfolio Tools)](#投资组合工具-portfolio-tools)
|
|||
|
|
- [Tick 微结构函数](#tick-微结构函数)
|
|||
|
|
- [止损与止盈](#止损与止盈)
|
|||
|
|
- [蒙特卡洛组合模拟](#蒙特卡洛组合模拟)
|
|||
|
|
- [回测结果与指标](#回测结果与指标)
|
|||
|
|
- [前视偏差防范](#前视偏差防范)
|
|||
|
|
- [ sourcing修改与编译指南](#源码修改与编译指南)
|
|||
|
|
- [项目结构](#项目结构)
|
|||
|
|
- [添加新指标](#添加新指标)
|
|||
|
|
- [编译与打包](#编译与打包)
|
|||
|
|
- [常见编译问题](#常见编译问题)
|
|||
|
|
- [移植与分发](#移植与分发)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 项目简介
|
|||
|
|
|
|||
|
|
RaptorBT 是一个高性能 Rust 回测引擎,通过 PyO3 提供 Python 绑定:
|
|||
|
|
|
|||
|
|
- **亚毫秒级回测**:1K bars ~0.03ms,50K bars ~1.4ms
|
|||
|
|
- **7 种策略类型**:单标的、篮子、配对、期权、价差、多策略、Tick 级
|
|||
|
|
- **33 项绩效指标**:Sharpe、Sortino、Calmar、Omega、SQN 等
|
|||
|
|
- **确定性执行**:相同输入产生 bit-for-bit 相同结果
|
|||
|
|
- **原生并行**:Rayon 并行 + SIMD 优化
|
|||
|
|
- **80 个技术指标**:集成 ferro-ta 指标库,覆盖趋势、动量、波动率、强度、成交量、价格变换、统计、周期变换、市场状态检测、投资组合工具
|
|||
|
|
|
|||
|
|
本扩展版在原版 12 个指标基础上,集成 ferro-ta 指标库,将指标总数扩展至 **51 个**。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 安装与部署
|
|||
|
|
|
|||
|
|
### 方式一:安装修改版 whl(推荐)
|
|||
|
|
|
|||
|
|
适用于同平台同 Python 版本的电脑,无需编译环境:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
pip install raptorbt-0.4.1-cp312-cp312-win_amd64.whl
|
|||
|
|
pip install -r requirements.txt
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`requirements.txt` 内容:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
numpy
|
|||
|
|
pandas
|
|||
|
|
requests
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> **注意**:whl 文件名中 `cp312` 表示 CPython 3.12,`win_amd64` 表示 Windows 64位。目标电脑必须满足相同条件。
|
|||
|
|
|
|||
|
|
### 方式二:从源码编译
|
|||
|
|
|
|||
|
|
需要 Rust 1.70+、Python 3.10+、maturin:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
cd raptorbt
|
|||
|
|
pip install maturin
|
|||
|
|
maturin develop --release
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 验证安装
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
import raptorbt
|
|||
|
|
print(raptorbt.__version__) # 0.4.1
|
|||
|
|
print(raptorbt.cci) # <built-in function cci> — 扩展指标可用
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 快速开始
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
import numpy as np
|
|||
|
|
import raptorbt
|
|||
|
|
|
|||
|
|
# 准备数据
|
|||
|
|
n = 500
|
|||
|
|
close = np.cumprod(1 + np.random.randn(n) * 0.02) * 100
|
|||
|
|
timestamps = np.arange(n, dtype=np.int64)
|
|||
|
|
open_ = close * 1.001
|
|||
|
|
high = close * 1.01
|
|||
|
|
low = close * 0.99
|
|||
|
|
volume = np.ones(n) * 1000
|
|||
|
|
|
|||
|
|
# 使用指标生成信号
|
|||
|
|
sma_fast = raptorbt.sma(close, period=10)
|
|||
|
|
sma_slow = raptorbt.sma(close, period=20)
|
|||
|
|
entries = (sma_fast > sma_slow) & np.roll(sma_fast <= sma_slow, 1)
|
|||
|
|
exits = (sma_fast < sma_slow) & np.roll(sma_fast >= sma_slow, 1)
|
|||
|
|
|
|||
|
|
# 配置回测
|
|||
|
|
config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001)
|
|||
|
|
|
|||
|
|
# 运行回测
|
|||
|
|
result = raptorbt.run_single_backtest(
|
|||
|
|
timestamps=timestamps,
|
|||
|
|
open=open_, high=high, low=low, close=close,
|
|||
|
|
volume=volume,
|
|||
|
|
entries=entries, exits=exits,
|
|||
|
|
direction=1, weight=1.0, symbol="TEST",
|
|||
|
|
config=config,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 查看结果
|
|||
|
|
print(f"收益率: {result.metrics.total_return_pct:.2f}%")
|
|||
|
|
print(f"夏普比率: {result.metrics.sharpe_ratio:.2f}")
|
|||
|
|
print(f"最大回撤: {result.metrics.max_drawdown_pct:.2f}%")
|
|||
|
|
print(f"交易次数: {result.metrics.total_trades}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 策略类型
|
|||
|
|
|
|||
|
|
### 1. 单标的回测 (run_single_backtest)
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
result = raptorbt.run_single_backtest(
|
|||
|
|
timestamps=timestamps, # int64 数组
|
|||
|
|
open=open, high=high, low=low, close=close, # float64 数组
|
|||
|
|
volume=volume, # float64 数组
|
|||
|
|
entries=entries, # bool 数组
|
|||
|
|
exits=exits, # bool 数组
|
|||
|
|
direction=1, # 1=做多, -1=做空
|
|||
|
|
weight=1.0,
|
|||
|
|
symbol="AAPL",
|
|||
|
|
config=config,
|
|||
|
|
instrument_config=raptorbt.PyInstrumentConfig(lot_size=1.0), # 可选
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 篮子回测 (run_basket_backtest)
|
|||
|
|
|
|||
|
|
多标的同步信号交易:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
instruments = [
|
|||
|
|
(ts, o1, h1, l1, c1, v1, entries1, exits1, 1, 0.33, "AAPL"),
|
|||
|
|
(ts, o2, h2, l2, c2, v2, entries2, exits2, 1, 0.33, "GOOGL"),
|
|||
|
|
(ts, o3, h3, l3, c3, v3, entries3, exits3, 1, 0.34, "MSFT"),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
result = raptorbt.run_basket_backtest(
|
|||
|
|
instruments=instruments,
|
|||
|
|
config=config,
|
|||
|
|
sync_mode="all", # "all" | "any" | "majority" | "master"
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 配对交易 (run_pairs_backtest)
|
|||
|
|
|
|||
|
|
做多一个标的,做空另一个:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
result = raptorbt.run_pairs_backtest(
|
|||
|
|
leg1_timestamps=ts, leg1_open=..., leg1_high=..., leg1_low=..., leg1_close=..., leg1_volume=...,
|
|||
|
|
leg2_timestamps=ts, leg2_open=..., leg2_high=..., leg2_low=..., leg2_close=..., leg2_volume=...,
|
|||
|
|
entries=entries, exits=exits,
|
|||
|
|
direction=1, symbol="PAIR",
|
|||
|
|
config=config,
|
|||
|
|
hedge_ratio=1.5, # 空头 1.5 倍
|
|||
|
|
dynamic_hedge=False,
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 期权回测 (run_options_backtest)
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
result = raptorbt.run_options_backtest(
|
|||
|
|
timestamps=ts, open=..., high=..., low=..., close=..., volume=...,
|
|||
|
|
option_prices=option_premiums,
|
|||
|
|
entries=entries, exits=exits,
|
|||
|
|
direction=1, symbol="NIFTY_CE",
|
|||
|
|
config=config,
|
|||
|
|
option_type="call", # "call" | "put"
|
|||
|
|
strike_selection="atm", # "atm" | "otm1" | "otm2" | "itm1" | "itm2"
|
|||
|
|
size_type="percent", # "percent" | "contracts" | "notional" | "risk"
|
|||
|
|
size_value=0.1,
|
|||
|
|
lot_size=50,
|
|||
|
|
strike_interval=50.0,
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. 多策略回测 (run_multi_backtest)
|
|||
|
|
|
|||
|
|
同一标的上组合多个策略:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
strategies = [
|
|||
|
|
(entries_sma, exits_sma, 1, 0.4, "SMA_Cross"),
|
|||
|
|
(entries_rsi, exits_rsi, 1, 0.35, "RSI_MeanRev"),
|
|||
|
|
(entries_bb, exits_bb, 1, 0.25, "BB_Break"),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
result = raptorbt.run_multi_backtest(
|
|||
|
|
timestamps=ts, open=..., high=..., low=..., close=..., volume=...,
|
|||
|
|
strategies=strategies,
|
|||
|
|
config=config,
|
|||
|
|
combine_mode="any", # "any" | "all" | "majority" | "weighted" | "independent"
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6. 批量价差回测 (batch_spread_backtest)
|
|||
|
|
|
|||
|
|
Rayon 并行执行多个价差回测,GIL 释放:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
items = [
|
|||
|
|
raptorbt.PyBatchSpreadItem(
|
|||
|
|
strategy_id="straddle_24000",
|
|||
|
|
legs_premiums=[call_premiums, put_premiums],
|
|||
|
|
leg_configs=[("CE", 24000.0, -1, 50), ("PE", 24000.0, -1, 50)],
|
|||
|
|
entries=entries, exits=exits,
|
|||
|
|
spread_type="straddle",
|
|||
|
|
max_loss=5000.0, target_profit=3000.0,
|
|||
|
|
),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
results = raptorbt.batch_spread_backtest(
|
|||
|
|
timestamps=ts, underlying_close=close,
|
|||
|
|
items=items, config=config,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
for sid, result in results:
|
|||
|
|
print(f"{sid}: {result.metrics.total_return_pct:.2f}%")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7. Tick 级回测 (run_tick_backtest)
|
|||
|
|
|
|||
|
|
全 Tick 分辨率模拟,无 bar 重采样:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
result = raptorbt.run_tick_backtest(
|
|||
|
|
timestamps=timestamps_ns, # int64 纳秒
|
|||
|
|
ltp=ltp_arr, bid=bid_arr, ask=ask_arr,
|
|||
|
|
buy_qty_delta=buy_delta, sell_qty_delta=sell_delta,
|
|||
|
|
oi=oi_arr,
|
|||
|
|
entries=entry_signals, exits=exit_signals,
|
|||
|
|
symbol="NIFTY26APR24600PE",
|
|||
|
|
initial_capital=100000.0, fees=0.001, slippage=0.0005,
|
|||
|
|
stop_loss_pct=5.0, take_profit_pct=10.0,
|
|||
|
|
max_hold_seconds=1800, entry_cooldown_ticks=10, max_trades=50,
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> **Zerodha 数据注意**:`total_buy_qty` / `total_sell_qty` 是累计值,需先转换:
|
|||
|
|
> `buy_delta = np.diff(buy_cum, prepend=0).clip(min=0)`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 指标完整参考
|
|||
|
|
|
|||
|
|
所有指标函数接收 NumPy `float64` 数组,返回 NumPy 数组。预热期返回 `NaN`。
|
|||
|
|
|
|||
|
|
### 趋势指标 (Trend)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `sma` | `sma(data, period)` | `ndarray` | 简单移动平均 |
|
|||
|
|
| `ema` | `ema(data, period)` | `ndarray` | 指数移动平均 |
|
|||
|
|
| `wma` | `wma(data, period)` | `ndarray` | 加权移动平均 |
|
|||
|
|
| `dema` | `dema(data, period)` | `ndarray` | 双重指数移动平均 |
|
|||
|
|
| `tema` | `tema(data, period)` | `ndarray` | 三重指数移动平均 |
|
|||
|
|
| `kama` | `kama(data, period)` | `ndarray` | Kaufman 自适应移动平均 |
|
|||
|
|
| `t3` | `t3(data, period=5, vfactor=0.7)` | `ndarray` | Tillson T3 移动平均 |
|
|||
|
|
| `trima` | `trima(data, period)` | `ndarray` | 三角移动平均 |
|
|||
|
|
| `midpoint` | `midpoint(data, period)` | `ndarray` | 周期内中点值 |
|
|||
|
|
| `midprice` | `midprice(high, low, period)` | `ndarray` | 周期内最高/最低均价 |
|
|||
|
|
| `sar` | `sar(high, low, acceleration=0.02, maximum=0.2)` | `ndarray` | 抛物线 SAR |
|
|||
|
|
| `supertrend` | `supertrend(high, low, close, period=10, multiplier=3.0)` | `(ndarray, ndarray)` | Supertrend 线 + 方向 (1=多, -1=空) |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
import raptorbt
|
|||
|
|
import numpy as np
|
|||
|
|
|
|||
|
|
close = np.array([...], dtype=np.float64)
|
|||
|
|
high = np.array([...], dtype=np.float64)
|
|||
|
|
low = np.array([...], dtype=np.float64)
|
|||
|
|
|
|||
|
|
sma20 = raptorbt.sma(close, period=20)
|
|||
|
|
ema20 = raptorbt.ema(close, period=20)
|
|||
|
|
dema20 = raptorbt.dema(close, period=20)
|
|||
|
|
kama10 = raptorbt.kama(close, period=10)
|
|||
|
|
t3_val = raptorbt.t3(close, period=20, vfactor=0.7)
|
|||
|
|
sar_val = raptorbt.sar(high, low, acceleration=0.02, maximum=0.2)
|
|||
|
|
st_line, st_dir = raptorbt.supertrend(high, low, close, period=10, multiplier=3.0)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 动量指标 (Momentum)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `rsi` | `rsi(data, period)` | `ndarray` | 相对强弱指数 (0~100) |
|
|||
|
|
| `macd` | `macd(data, fast_period=12, slow_period=26, signal_period=9)` | `(line, signal, hist)` | MACD |
|
|||
|
|
| `stochastic` | `stochastic(high, low, close, k_period=14, d_period=3)` | `(k, d)` | 随机振荡器 (0~100) |
|
|||
|
|
| `cci` | `cci(high, low, close, period)` | `ndarray` | 商品通道指数 |
|
|||
|
|
| `willr` | `willr(high, low, close, period)` | `ndarray` | 威廉指标 (-100~0) |
|
|||
|
|
| `roc` | `roc(data, period)` | `ndarray` | 变化率 |
|
|||
|
|
| `mom` | `mom(data, period)` | `ndarray` | 动量 |
|
|||
|
|
| `cmo` | `cmo(data, period)` | `ndarray` | 钱德动量振荡器 |
|
|||
|
|
| `trix` | `trix(data, period)` | `ndarray` | 三重指数平滑变化率 |
|
|||
|
|
| `stochrsi` | `stochrsi(data, timeperiod=14, fastk_period=5, fastd_period=3)` | `(fastk, fastd)` | 随机 RSI (0~100) |
|
|||
|
|
| `aroon` | `aroon(high, low, period)` | `(up, down)` | Aroon 上升/下降 (0~100) |
|
|||
|
|
| `aroonosc` | `aroonosc(high, low, period)` | `ndarray` | Aroon 振荡器 (-100~100) |
|
|||
|
|
| `bop` | `bop(open, high, low, close)` | `ndarray` | 力量平衡 (-1~1) |
|
|||
|
|
| `ultosc` | `ultosc(high, low, close, period1=7, period2=14, period3=28)` | `ndarray` | 终极振荡器 (0~100) |
|
|||
|
|
| `ppo` | `ppo(data, fastperiod=12, slowperiod=26, signalperiod=9)` | `(line, signal, hist)` | 百分比价格振荡器 |
|
|||
|
|
| `apo` | `apo(data, fastperiod=12, slowperiod=26)` | `ndarray` | 绝对价格振荡器 |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
rsi14 = raptorbt.rsi(close, period=14)
|
|||
|
|
macd_line, macd_signal, macd_hist = raptorbt.macd(close, 12, 26, 9)
|
|||
|
|
stoch_k, stoch_d = raptorbt.stochastic(high, low, close, k_period=14, d_period=3)
|
|||
|
|
cci20 = raptorbt.cci(high, low, close, period=20)
|
|||
|
|
ppo_line, ppo_signal, ppo_hist = raptorbt.ppo(close, fastperiod=12, slowperiod=26, signalperiod=9)
|
|||
|
|
aroon_up, aroon_down = raptorbt.aroon(high, low, period=14)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 波动率指标 (Volatility)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `atr` | `atr(high, low, close, period)` | `ndarray` | 平均真实波幅 |
|
|||
|
|
| `natr` | `natr(high, low, close, period)` | `ndarray` | 归一化 ATR (%) |
|
|||
|
|
| `trange` | `trange(high, low, close)` | `ndarray` | 真实波幅 |
|
|||
|
|
| `bollinger_bands` | `bollinger_bands(data, period=20, std_dev=2.0)` | `(upper, middle, lower)` | 布林带 |
|
|||
|
|
| `stddev` | `stddev(data, period, nbdev=1.0)` | `ndarray` | 标准差 |
|
|||
|
|
| `var` | `var(data, period, nbdev=1.0)` | `ndarray` | 方差 |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
atr14 = raptorbt.atr(high, low, close, period=14)
|
|||
|
|
natr14 = raptorbt.natr(high, low, close, period=14)
|
|||
|
|
bb_upper, bb_middle, bb_lower = raptorbt.bollinger_bands(close, period=20, std_dev=2.0)
|
|||
|
|
std20 = raptorbt.stddev(close, period=20, nbdev=1.0)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 强度指标 (Strength)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `adx` | `adx(high, low, close, period)` | `ndarray` | 平均方向指数 (0~100) |
|
|||
|
|
| `adx_all` | `adx_all(high, low, close, period)` | `(adx, +di, -di)` | ADX + 正DI + 负DI |
|
|||
|
|
| `adxr` | `adxr(high, low, close, period)` | `ndarray` | ADX 评级 |
|
|||
|
|
| `plus_di` | `plus_di(high, low, close, period)` | `ndarray` | +DI 方向指标 |
|
|||
|
|
| `minus_di` | `minus_di(high, low, close, period)` | `ndarray` | -DI 方向指标 |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
adx14 = raptorbt.adx(high, low, close, period=14)
|
|||
|
|
adx_val, plus_di, minus_di = raptorbt.adx_all(high, low, close, period=14)
|
|||
|
|
adxr14 = raptorbt.adxr(high, low, close, period=14)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 成交量指标 (Volume)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `vwap` | `vwap(high, low, close, volume)` | `ndarray` | 成交量加权平均价 |
|
|||
|
|
| `obv` | `obv(close, volume)` | `ndarray` | 能量潮 |
|
|||
|
|
| `ad` | `ad(high, low, close, volume)` | `ndarray` | 累积/派发线 |
|
|||
|
|
| `adosc` | `adosc(high, low, close, volume, fastperiod=3, slowperiod=10)` | `ndarray` | 累积/派发振荡器 |
|
|||
|
|
| `mfi` | `mfi(high, low, close, volume, period)` | `ndarray` | 资金流量指数 (0~100) |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
vwap_val = raptorbt.vwap(high, low, close, volume)
|
|||
|
|
obv_val = raptorbt.obv(close, volume)
|
|||
|
|
ad_val = raptorbt.ad(high, low, close, volume)
|
|||
|
|
adosc_val = raptorbt.adosc(high, low, close, volume, fastperiod=3, slowperiod=10)
|
|||
|
|
mfi14 = raptorbt.mfi(high, low, close, volume, period=14)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 价格变换指标 (Price Transform)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `typprice` | `typprice(high, low, close)` | `ndarray` | 典型价格 (H+L+C)/3 |
|
|||
|
|
| `medprice` | `medprice(high, low)` | `ndarray` | 中间价格 (H+L)/2 |
|
|||
|
|
| `avgprice` | `avgprice(open, high, low, close)` | `ndarray` | 平均价格 (O+H+L+C)/4 |
|
|||
|
|
| `wclprice` | `wclprice(high, low, close)` | `ndarray` | 加权收盘价 (H+L+C*2)/4 |
|
|||
|
|
|
|||
|
|
### 统计指标 (Statistic)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `linearreg` | `linearreg(data, period)` | `ndarray` | 线性回归 |
|
|||
|
|
| `linearreg_slope` | `linearreg_slope(data, period)` | `ndarray` | 线性回归斜率 |
|
|||
|
|
| `linearreg_intercept` | `linearreg_intercept(data, period)` | `ndarray` | 线性回归截距 |
|
|||
|
|
| `linearreg_angle` | `linearreg_angle(data, period)` | `ndarray` | 线性回归角度 |
|
|||
|
|
| `tsf` | `tsf(data, period)` | `ndarray` | 时间序列预测 |
|
|||
|
|
| `beta` | `beta(data0, data1, period)` | `ndarray` | Beta 系数 |
|
|||
|
|
| `correl` | `correl(data0, data1, period)` | `ndarray` | 相关系数 |
|
|||
|
|
|
|||
|
|
### P0 扩展指标 (P0 Extended)
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `vwma` | `vwma(data, volume, period=20)` | `ndarray` | 成交量加权移动平均 |
|
|||
|
|
| `donchian` | `donchian(high, low, period)` | `(upper, middle, lower)` | 唐奇安通道 |
|
|||
|
|
| `choppiness_index` | `choppiness_index(high, low, close, period=14)` | `ndarray` | 混沌指标 (0=趋势, 100=震荡) |
|
|||
|
|
| `hull_ma` | `hull_ma(data, period)` | `ndarray` | Hull 移动平均 |
|
|||
|
|
| `chandelier_exit` | `chandelier_exit(high, low, close, period=22, multiplier=3.0)` | `(long_exit, short_exit)` | 吊灯止损 (ATR追踪止损) |
|
|||
|
|
| `ichimoku` | `ichimoku(high, low, close, tenkan_period=9, kijun_period=26, senkou_b_period=52, displacement=26)` | `(tenkan, kijun, senkou_a, senkou_b, chikou)` | 一目均衡表 |
|
|||
|
|
| `pivot_points` | `pivot_points(high, low, close, method="classic")` | `(pivot, r1, s1, r2, s2)` | 枢轴点 (classic/fibonacci/camarilla) |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
vwap_val = raptorbt.vwma(close, volume, period=20)
|
|||
|
|
donchian_upper, donchian_middle, donchian_lower = raptorbt.donchian(high, low, 20)
|
|||
|
|
ci_val = raptorbt.choppiness_index(high, low, close, period=14)
|
|||
|
|
hma_val = raptorbt.hull_ma(close, period=14)
|
|||
|
|
clong, cshort = raptorbt.chandelier_exit(high, low, close, period=22, multiplier=3.0)
|
|||
|
|
tenkan, kijun, senkou_a, senkou_b, chikou = raptorbt.ichimoku(high, low, close)
|
|||
|
|
pivot, r1, s1, r2, s2 = raptorbt.pivot_points(high, low, close, method="classic")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 周期变换指标 (Hilbert Transform / Cycle)
|
|||
|
|
|
|||
|
|
基于希尔伯特变换的周期分析工具。要求数据至少 32 根 K 线。
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `ht_trendline` | `ht_trendline(data)` | `ndarray` | 希尔伯特瞬时趋势线 |
|
|||
|
|
| `ht_dcperiod` | `ht_dcperiod(data)` | `ndarray` | 主导周期周期 |
|
|||
|
|
| `ht_dcphase` | `ht_dcphase(data)` | `ndarray` | 主导周期相位(度) |
|
|||
|
|
| `ht_phasor` | `ht_phasor(data)` | `(in_phase, quadrature)` | 相量分量 |
|
|||
|
|
| `ht_sine` | `ht_sine(data)` | `(sine, lead_sine)` | 正弦波(含超前信号) |
|
|||
|
|
| `ht_trendmode` | `ht_trendmode(data)` | `ndarray[i32]` | 趋势/周期模式 (1=趋势, 0=周期) |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
trendline = raptorbt.ht_trendline(close)
|
|||
|
|
dcperiod = raptorbt.ht_dcperiod(close)
|
|||
|
|
dcphase = raptorbt.ht_dcphase(close)
|
|||
|
|
in_phase, quadrature = raptorbt.ht_phasor(close)
|
|||
|
|
sine, lead_sine = raptorbt.ht_sine(close)
|
|||
|
|
mode = raptorbt.ht_trendmode(close) # i32: 1=trend, 0=cycle
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 市场状态检测 (Market Regime)
|
|||
|
|
|
|||
|
|
用于判断当前市场处于趋势或震荡状态,以及检测结构性突变。
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `regime_adx` | `regime_adx(adx, threshold=25.0)` | `ndarray[i8]` | 基于 ADX 的趋势/震荡标签 (1=趋势, 0=震荡, -1=预热) |
|
|||
|
|
| `regime_combined` | `regime_combined(adx, atr, close, adx_threshold=25.0, atr_pct_threshold=2.0)` | `ndarray[i8]` | ADX+ATR 组合判断 |
|
|||
|
|
| `detect_breaks_cusum` | `detect_breaks_cusum(data, window, threshold, slack)` | `ndarray[i8]` | CUSUM 结构性突变检测 (1=突变点) |
|
|||
|
|
| `rolling_variance_break` | `rolling_variance_break(data, short_window, long_window, threshold)` | `ndarray[i8]` | 滚动方差比突变检测 (1=突变点) |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
adx_vals = raptorbt.adx(high, low, close, 14)
|
|||
|
|
regime = raptorbt.regime_adx(adx_vals, threshold=25.0) # 1=trend, 0=range
|
|||
|
|
|
|||
|
|
# 组合判断
|
|||
|
|
regime2 = raptorbt.regime_combined(adx_vals, atr_vals, close, 25.0, 2.0)
|
|||
|
|
|
|||
|
|
# 结构突变
|
|||
|
|
breaks = raptorbt.detect_breaks_cusum(close, window=30, threshold=1.5, slack=0.5)
|
|||
|
|
vol_breaks = raptorbt.rolling_variance_break(close, 10, 30, 2.0)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 投资组合工具 (Portfolio Tools)
|
|||
|
|
|
|||
|
|
跨序列分析工具,用于配对交易、风险管理、相对强度计算。
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `rolling_beta` | `rolling_beta(asset, benchmark, window)` | `ndarray` | 滚动 Beta 系数 |
|
|||
|
|
| `drawdown_series` | `drawdown_series(equity)` | `(dd_series, max_dd)` | 回撤序列 + 最大回撤 |
|
|||
|
|
| `zscore_series` | `zscore_series(data, window)` | `ndarray` | 滚动 Z-Score |
|
|||
|
|
| `relative_strength` | `relative_strength(asset_returns, benchmark_returns)` | `ndarray` | 相对强度 (excess return 风格) |
|
|||
|
|
| `spread` | `spread(a, b, hedge)` | `ndarray` | 价差序列 (a - hedge*b) |
|
|||
|
|
| `ratio` | `ratio(a, b)` | `ndarray` | 比率序列 (a/b) |
|
|||
|
|
|
|||
|
|
**用法示例:**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 滚动 Beta
|
|||
|
|
rb = raptorbt.rolling_beta(asset_returns, benchmark_returns, 30)
|
|||
|
|
|
|||
|
|
# 回撤分析
|
|||
|
|
dd_series, max_dd = raptorbt.drawdown_series(equity_curve)
|
|||
|
|
|
|||
|
|
# Z-Score
|
|||
|
|
zscore = raptorbt.zscore_series(close, window=20)
|
|||
|
|
|
|||
|
|
# 配对交易价差
|
|||
|
|
spread_val = raptorbt.spread(series_a, series_b, hedge=1.0)
|
|||
|
|
ratio_val = raptorbt.ratio(series_a, series_b)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 滚动统计
|
|||
|
|
|
|||
|
|
| 函数 | 签名 | 返回 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `rolling_min` | `rolling_min(data, period)` | `ndarray` | 周期内最低值 (LLV) |
|
|||
|
|
| `rolling_max` | `rolling_max(data, period)` | `ndarray` | 周期内最高值 (HHV) |
|
|||
|
|
|
|||
|
|
### Tick 微结构函数
|
|||
|
|
|
|||
|
|
用于 Tick 级回测的信号和特征函数:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 入场/出场信号
|
|||
|
|
entries = raptorbt.compute_tick_entry_signals(
|
|||
|
|
spread_pct=raptorbt.tick_spread_pct(bid, ask),
|
|||
|
|
bsi_delta=raptorbt.buy_sell_imbalance_delta(buy_cum, sell_cum),
|
|||
|
|
return_1m=raptorbt.return_window(timestamps_ns, ltp, window_seconds=60.0),
|
|||
|
|
spread_pct_max=3.0,
|
|||
|
|
bsi_min=0.55,
|
|||
|
|
return_1m_min_abs=0.3,
|
|||
|
|
return_direction=1,
|
|||
|
|
cooldown_ticks=10,
|
|||
|
|
)
|
|||
|
|
exits = raptorbt.compute_tick_exit_signals(timestamps_ns, eod_exit_time_ns)
|
|||
|
|
|
|||
|
|
# 特征数组
|
|||
|
|
spread = raptorbt.tick_spread_pct(bid, ask) # 价差百分比
|
|||
|
|
bsi = raptorbt.buy_sell_imbalance_delta(buy_cum, sell_cum) # 买卖失衡
|
|||
|
|
ret_1m = raptorbt.return_window(ts_ns, ltp, 60.0) # 1分钟回报
|
|||
|
|
vol = raptorbt.realized_vol_rolling(ts_ns, ltp, 300.0) # 5分钟已实现波动率
|
|||
|
|
oi_pos = raptorbt.oi_position_pct(oi, oi_high, oi_low) # OI 位置百分比
|
|||
|
|
velocity = raptorbt.tick_velocity(ts_ns, 60.0) # Tick 速度 (ticks/min)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 止损与止盈
|
|||
|
|
|
|||
|
|
### 固定百分比
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001)
|
|||
|
|
config.set_fixed_stop(0.02) # 2% 止损
|
|||
|
|
config.set_fixed_target(0.04) # 4% 止盈
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ATR 动态止损
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
config.set_atr_stop(multiplier=2.0, period=14) # 2倍 ATR 止损
|
|||
|
|
config.set_atr_target(multiplier=3.0, period=14) # 3倍 ATR 止盈
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 追踪止损
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
config.set_trailing_stop(0.02) # 2% 追踪止损
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 风险回报比止盈
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
config.set_risk_reward_target(ratio=2.0) # 2:1 风险回报比
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 出场原因
|
|||
|
|
|
|||
|
|
| 值 | 含义 |
|
|||
|
|
|---|------|
|
|||
|
|
| `Signal` | 策略信号出场 |
|
|||
|
|
| `StopLoss` | 触发止损 |
|
|||
|
|
| `TakeProfit` | 触发止盈 |
|
|||
|
|
| `TrailingStop` | 触发追踪止损 |
|
|||
|
|
| `EndOfData` | 数据结束 |
|
|||
|
|
| `Settlement` | 期权结算 |
|
|||
|
|
| `TimeExit` | 超时出场(Tick 级) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 蒙特卡洛组合模拟
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
result = raptorbt.simulate_portfolio_mc(
|
|||
|
|
returns=[ret1, ret2], # 各策略/资产的历史日收益率数组
|
|||
|
|
weights=np.array([0.6, 0.4]), # 组合权重(和为1)
|
|||
|
|
correlation_matrix=[ # N×N 相关系数矩阵
|
|||
|
|
np.array([1.0, 0.3]),
|
|||
|
|
np.array([0.3, 1.0]),
|
|||
|
|
],
|
|||
|
|
initial_value=100000.0,
|
|||
|
|
n_simulations=10000, # 模拟路径数
|
|||
|
|
horizon_days=252, # 前瞻天数
|
|||
|
|
seed=42, # 随机种子
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print(f"预期收益: {result['expected_return']:.2f}%")
|
|||
|
|
print(f"亏损概率: {result['probability_of_loss']:.2%}")
|
|||
|
|
print(f"VaR (95%): {result['var_95']:.2f}%")
|
|||
|
|
print(f"CVaR (95%): {result['cvar_95']:.2f}%")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 回测结果与指标
|
|||
|
|
|
|||
|
|
### PyBacktestResult
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
result.metrics # PyBacktestMetrics 对象
|
|||
|
|
result.equity_curve() # 权益曲线 ndarray
|
|||
|
|
result.drawdown_curve() # 回撤曲线 ndarray
|
|||
|
|
result.returns() # 收益率序列 ndarray
|
|||
|
|
result.trades() # 交易列表 List[PyTrade]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### PyBacktestMetrics(33 个字段)
|
|||
|
|
|
|||
|
|
**核心绩效:**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `total_return_pct` | 总收益率 (%) |
|
|||
|
|
| `sharpe_ratio` | 夏普比率(年化) |
|
|||
|
|
| `sortino_ratio` | 索提诺比率 |
|
|||
|
|
| `calmar_ratio` | 卡玛比率 |
|
|||
|
|
| `omega_ratio` | Omega 比率 |
|
|||
|
|
|
|||
|
|
**回撤:**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `max_drawdown_pct` | 最大回撤 (%) |
|
|||
|
|
| `max_drawdown_duration` | 最长回撤持续期 (bars) |
|
|||
|
|
|
|||
|
|
**交易统计:**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `total_trades` | 总交易数 |
|
|||
|
|
| `winning_trades` | 盈利交易数 |
|
|||
|
|
| `losing_trades` | 亏损交易数 |
|
|||
|
|
| `win_rate_pct` | 胜率 (%) |
|
|||
|
|
| `profit_factor` | 盈利因子 |
|
|||
|
|
| `expectancy` | 期望值 |
|
|||
|
|
| `sqn` | 系统质量数 |
|
|||
|
|
| `avg_trade_return_pct` | 平均交易收益 (%) |
|
|||
|
|
| `avg_win_pct` | 平均盈利 (%) |
|
|||
|
|
| `avg_loss_pct` | 平均亏损 (%) |
|
|||
|
|
| `best_trade_pct` | 最佳交易 (%) |
|
|||
|
|
| `worst_trade_pct` | 最差交易 (%) |
|
|||
|
|
| `payoff_ratio` | 盈亏比 |
|
|||
|
|
| `recovery_factor` | 恢复因子 |
|
|||
|
|
|
|||
|
|
**其他:**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `start_value` | 初始资金 |
|
|||
|
|
| `end_value` | 终值 |
|
|||
|
|
| `total_fees_paid` | 总手续费 |
|
|||
|
|
| `open_trade_pnl` | 未平仓盈亏 |
|
|||
|
|
| `exposure_pct` | 市场暴露度 (%) |
|
|||
|
|
| `avg_holding_period` | 平均持仓时间 (bars) |
|
|||
|
|
| `max_consecutive_wins` | 最大连胜 |
|
|||
|
|
| `max_consecutive_losses` | 最大连败 |
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
m = result.metrics
|
|||
|
|
print(m.total_return_pct, m.sharpe_ratio, m.max_drawdown_pct)
|
|||
|
|
|
|||
|
|
# 转为字典(24 个常用指标,带中文友好标签)
|
|||
|
|
stats = m.to_dict()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### PyTrade
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
for trade in result.trades():
|
|||
|
|
trade.id # 交易 ID
|
|||
|
|
trade.symbol # 标的
|
|||
|
|
trade.entry_idx # 入场 bar 索引
|
|||
|
|
trade.exit_idx # 出场 bar 索引
|
|||
|
|
trade.entry_price # 入场价
|
|||
|
|
trade.exit_price # 出场价
|
|||
|
|
trade.size # 仓位大小
|
|||
|
|
trade.direction # 1=多, -1=空
|
|||
|
|
trade.pnl # 盈亏金额
|
|||
|
|
trade.return_pct # 收益率 (%)
|
|||
|
|
trade.fees # 手续费
|
|||
|
|
trade.exit_reason # 出场原因
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 前视偏差防范
|
|||
|
|
|
|||
|
|
前视偏差(Look-ahead Bias)是回测中最危险的陷阱之一——无意中使用了"未来数据"来做出"当前决策",导致回测结果虚高。
|
|||
|
|
|
|||
|
|
### RaptorBT 的默认防护
|
|||
|
|
|
|||
|
|
RaptorBT 默认 `upon_bar_close=True`,含义是:
|
|||
|
|
|
|||
|
|
- 当前 K 线收盘后产生的信号,在**下一根 K 线开盘时**执行
|
|||
|
|
- 这保证了信号生成时只能看到当前及之前的数据,不可能用到未来数据
|
|||
|
|
|
|||
|
|
### 需要额外注意的场景
|
|||
|
|
|
|||
|
|
1. **指标预热期**:前 N 根 K 线的指标值为 NaN,不要用这些 NaN 值生成信号
|
|||
|
|
2. **未来函数**:避免使用 `shift(-1)` 等"偷看未来"的操作
|
|||
|
|
3. **日线数据**:如果用日线回测,确保信号不依赖当日收盘价之后的信息
|
|||
|
|
4. **复权数据**:前复权/后复权可能引入未来信息,建议使用不复权数据
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 源码修改与编译指南
|
|||
|
|
|
|||
|
|
### 项目结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
raptorbt/
|
|||
|
|
├── Cargo.toml # Rust 依赖配置
|
|||
|
|
├── pyproject.toml # Python 项目配置
|
|||
|
|
├── requirements.txt # Python 运行时依赖
|
|||
|
|
├── src/
|
|||
|
|
│ ├── lib.rs # Rust 库入口
|
|||
|
|
│ ├── core/
|
|||
|
|
│ │ └── error.rs # 错误类型定义
|
|||
|
|
│ ├── indicators/
|
|||
|
|
│ │ ├── mod.rs # 指标模块导出
|
|||
|
|
│ │ ├── trend.rs # 趋势指标(SMA, EMA, Supertrend)
|
|||
|
|
│ │ ├── momentum.rs # 动量指标(RSI, MACD, Stochastic)
|
|||
|
|
│ │ ├── volatility.rs # 波动率指标(ATR, Bollinger Bands)
|
|||
|
|
│ │ ├── strength.rs # 强度指标(ADX)
|
|||
|
|
│ │ ├── volume.rs # 成交量指标(VWAP, OBV, MFI)
|
|||
|
|
│ │ ├── rolling.rs # 滚动统计(Rolling Min/Max)
|
|||
|
|
│ │ ├── tick_features.rs # Tick 微结构函数
|
|||
|
|
│ │ └── ferro_bridge.rs # ferro-ta 指标桥接层 ★
|
|||
|
|
│ ├── portfolio/ # 回测引擎核心
|
|||
|
|
│ └── python/
|
|||
|
|
│ └── bindings.rs # PyO3 Python 绑定 ★
|
|||
|
|
├── python/
|
|||
|
|
│ └── raptorbt/
|
|||
|
|
│ └── __init__.py # Python 包导出 ★
|
|||
|
|
└── ferro-ta-main/ # ferro-ta 源码(编译时依赖)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
标 ★ 的文件是添加新指标时需要修改的。
|
|||
|
|
|
|||
|
|
### 添加新指标
|
|||
|
|
|
|||
|
|
以添加一个 ferro-ta 中的指标为例,需要修改 3 个文件:
|
|||
|
|
|
|||
|
|
#### 步骤 1:在 `ferro_bridge.rs` 中添加桥接函数
|
|||
|
|
|
|||
|
|
```rust
|
|||
|
|
// src/indicators/ferro_bridge.rs
|
|||
|
|
|
|||
|
|
pub fn my_indicator(data: &[f64], period: usize) -> Result<Vec<f64>> {
|
|||
|
|
if period == 0 {
|
|||
|
|
return Err(RaptorError::invalid_parameter("MyIndicator period must be > 0"));
|
|||
|
|
}
|
|||
|
|
Ok(ferro_ta_core::category::my_indicator(data, period))
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键注意事项:**
|
|||
|
|
|
|||
|
|
- 如果指标内部使用 EMA 处理中间结果(如 DEMA、TEMA、TRIX、PPO),必须使用 `ema_nan_safe` 而非 `ferro_ta_core::overlap::ema`,因为后者在输入含 NaN 时会全部输出 NaN
|
|||
|
|
- 多输出指标需要定义 Result 结构体(参考 `PpoResult`、`AroonResult`)
|
|||
|
|
|
|||
|
|
#### 步骤 2:在 `bindings.rs` 中添加 Python 绑定
|
|||
|
|
|
|||
|
|
```rust
|
|||
|
|
// src/python/bindings.rs
|
|||
|
|
|
|||
|
|
#[pyfunction]
|
|||
|
|
pub fn my_indicator<'py>(
|
|||
|
|
py: Python<'py>,
|
|||
|
|
data: PyReadonlyArray1<f64>,
|
|||
|
|
period: usize,
|
|||
|
|
) -> PyResult<&'py PyArray1<f64>> {
|
|||
|
|
let vec = numpy_to_vec_f64(data);
|
|||
|
|
let result = indicators::ferro_bridge::my_indicator(&vec, period)
|
|||
|
|
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
|
|||
|
|
Ok(vec_to_numpy_f64(py, result))
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
然后在 `#[pymodule]` 注册函数中添加:
|
|||
|
|
|
|||
|
|
```rust
|
|||
|
|
m.add_function(wrap_pyfunction!(my_indicator, m)?)?;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 步骤 3:在 `__init__.py` 中导出
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# python/raptorbt/__init__.py
|
|||
|
|
|
|||
|
|
from raptorbt._raptorbt import (
|
|||
|
|
# ... 已有导出 ...
|
|||
|
|
my_indicator,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
__all__ = [
|
|||
|
|
# ... 已有导出 ...
|
|||
|
|
"my_indicator",
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 步骤 4:在 `mod.rs` 中导出(如果需要在 Rust 内部使用)
|
|||
|
|
|
|||
|
|
```rust
|
|||
|
|
// src/indicators/mod.rs
|
|||
|
|
|
|||
|
|
pub use ferro_bridge::{ /* ... */, my_indicator };
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 编译与打包
|
|||
|
|
|
|||
|
|
#### 开发编译(直接安装到当前虚拟环境)
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
maturin develop --release
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 产出 whl 文件
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
maturin build --release
|
|||
|
|
# 产出: target/wheels/raptorbt-0.4.1-cp312-cp312-win_amd64.whl
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 安装 whl
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
pip uninstall raptorbt -y
|
|||
|
|
pip install target\wheels\raptorbt-0.4.1-cp312-cp312-win_amd64.whl
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 常见编译问题
|
|||
|
|
|
|||
|
|
#### 1. 拒绝访问 (os error 5)
|
|||
|
|
|
|||
|
|
**原因**:环境变量 `CARGO` 被错误设置为目录路径 `C:\Users\Administrator\.cargo\bin`,maturin 把目录当可执行文件调用。
|
|||
|
|
|
|||
|
|
**修复**:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
# 临时修复(当前终端,推荐)
|
|||
|
|
$env:CARGO = "C:\Users\Administrator\.cargo\bin\cargo.exe"
|
|||
|
|
|
|||
|
|
# 永久修复:系统属性 → 环境变量 → 删除或修正小写 CARGO 变量
|
|||
|
|
# 确保值指向可执行文件而非目录
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> 如果不想设置环境变量,也可以在 PowerShell profile 中配置:
|
|||
|
|
> `$HOME\.config\powershell\Microsoft.PowerShell_profile.ps1` 中添加 `$env:CARGO = "C:\Users\Administrator\.cargo\bin\cargo.exe"`
|
|||
|
|
|
|||
|
|
#### 2. .pyd 文件被锁定
|
|||
|
|
|
|||
|
|
**原因**:Python 进程占用了旧的 `.pyd` 文件。
|
|||
|
|
|
|||
|
|
**修复**:退出虚拟环境,关闭所有 Python 进程,重新打开终端编译。
|
|||
|
|
|
|||
|
|
#### 3. 找不到 ferro_ta_core
|
|||
|
|
|
|||
|
|
**原因**:`Cargo.toml` 中的本地依赖路径不正确。
|
|||
|
|
|
|||
|
|
**修复**:确认 `Cargo.toml` 中路径指向正确的 ferro-ta 源码位置:
|
|||
|
|
|
|||
|
|
```toml
|
|||
|
|
[dependencies]
|
|||
|
|
ferro_ta_core = { path = "./ferro-ta-main/crates/ferro_ta_core", default-features = false }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. EMA 链式指标全输出 NaN
|
|||
|
|
|
|||
|
|
**原因**:`ferro_ta_core::overlap::ema` 在输入含 NaN 时会传播 NaN,导致链式 EMA(DEMA、TEMA、TRIX、PPO)全部为 NaN。
|
|||
|
|
|
|||
|
|
**修复**:在 `ferro_bridge.rs` 中使用 `ema_nan_safe` 函数替代直接调用 `ferro_ta_core::overlap::ema` 处理中间结果。`ema_nan_safe` 会跳过 NaN 值计算初始种子,确保链式 EMA 正常工作。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 移植与分发
|
|||
|
|
|
|||
|
|
### whl 文件分发
|
|||
|
|
|
|||
|
|
修改版 whl 已静态链接所有 Rust 依赖(包括 ferro-ta),目标电脑**不需要**安装 Rust 或 ferro-ta 源码。
|
|||
|
|
|
|||
|
|
**前提条件**:
|
|||
|
|
- 相同操作系统 + 架构(如 Windows x64)
|
|||
|
|
- 相同 Python 版本(如 3.12)
|
|||
|
|
|
|||
|
|
**安装步骤**:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
pip install raptorbt-0.4.1-cp312-cp312-win_amd64.whl
|
|||
|
|
pip install numpy pandas requests
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 源码分发
|
|||
|
|
|
|||
|
|
如果目标电脑 Python 版本不同或需要进一步修改,需要携带源码:
|
|||
|
|
|
|||
|
|
**必须保留的文件/目录**:
|
|||
|
|
- `src/` — RaptorBT 修改后的源码
|
|||
|
|
- `python/` — Python 包代码
|
|||
|
|
- `Cargo.toml`、`pyproject.toml` — 项目配置
|
|||
|
|
- `ferro-ta-main/` — ferro-ta 源码(编译时需要)
|
|||
|
|
- `requirements.txt` — Python 依赖
|
|||
|
|
|
|||
|
|
**在新电脑上编译**:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
# 安装 Rust (https://rustup.rs)
|
|||
|
|
# 安装 Python 3.10+
|
|||
|
|
pip install maturin numpy
|
|||
|
|
maturin develop --release
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 关系图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
源码 (src/ + ferro-ta-main/)
|
|||
|
|
│
|
|||
|
|
├── maturin develop ──→ 直接安装到当前环境(开发用)
|
|||
|
|
│
|
|||
|
|
└── maturin build ───→ .whl 文件(分发用)
|
|||
|
|
│
|
|||
|
|
└── pip install xxx.whl → 可移植到同平台电脑
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录:指标分类速查
|
|||
|
|
|
|||
|
|
### 原版指标 (12个)
|
|||
|
|
|
|||
|
|
SMA, EMA, RSI, MACD, Stochastic, ATR, Bollinger Bands, ADX, VWAP, Supertrend, Rolling Min, Rolling Max
|
|||
|
|
|
|||
|
|
### ferro-ta 扩展指标 (68个)
|
|||
|
|
|
|||
|
|
**趋势类**:WMA, DEMA, TEMA, KAMA, T3, TRIMA, Midpoint, Midprice, SAR, HullMA, Donchian, ChoppinessIndex, ChandelierExit, Ichimoku, PivotPoints
|
|||
|
|
|
|||
|
|
**动量类**:CCI, WillR, ROC, MOM, CMO, TRIX, StochRSI, Aroon, AroonOsc, BOP, UltOSC, PPO, APO
|
|||
|
|
|
|||
|
|
**波动率类**:NATR, TRange, StdDev, VAR
|
|||
|
|
|
|||
|
|
**强度类**:ADXr, Plus_DI, Minus_DI, ADX_all
|
|||
|
|
|
|||
|
|
**成交量类**:AD, ADOSC, OBV, MFI, VWMA
|
|||
|
|
|
|||
|
|
**价格变换类**:TypPrice, MedPrice, AvgPrice, WclPrice
|
|||
|
|
|
|||
|
|
**统计类**:LinearReg, LinearReg_Slope, LinearReg_Intercept, LinearReg_Angle, TSF, Beta, Correl
|
|||
|
|
|
|||
|
|
**周期变换类 (Hilbert)**:HT_Trendline, HT_DCPeriod, HT_DCPhase, HT_Phasor, HT_Sine, HT_TrendMode
|
|||
|
|
|
|||
|
|
**市场状态类**:Regime_ADX, Regime_Combined, DetectBreaks_CUSUM, RollingVarianceBreak
|
|||
|
|
|
|||
|
|
**投资组合工具类**:RollingBeta, DrawdownSeries, ZScoreSeries, RelativeStrength, Spread, Ratio
|