跳到主要内容

量化开发速查表

本文档汇总了量化开发中常用的公式、指标和代码片段,方便快速查阅。

常用收益率计算

简单收益率

Rt=PtPt1Pt1R_t = \frac{P_t - P_{t-1}}{P_{t-1}}

returns = df['Close'].pct_change()

对数收益率

rt=ln(PtPt1)r_t = \ln\left(\frac{P_t}{P_{t-1}}\right)

log_returns = np.log(df['Close'] / df['Close'].shift(1))

累计收益率

Cumulative Return=i=1n(1+Ri)1Cumulative\ Return = \prod_{i=1}^{n}(1 + R_i) - 1

cumulative_return = (1 + returns).cumprod() - 1

年化收益率

Annualized Return=(1+Ravg)2521Annualized\ Return = (1 + R_{avg})^{252} - 1

annual_return = (1 + returns.mean()) ** 252 - 1

风险指标

波动率

σannual=σdaily×252\sigma_{annual} = \sigma_{daily} \times \sqrt{252}

volatility = returns.std() * np.sqrt(252)

最大回撤

MDD=maxtVpeakVtVpeakMDD = \max_t \frac{V_{peak} - V_t}{V_{peak}}

cumulative = (1 + returns).cumprod()
running_max = cumulative.cummax()
drawdown = (cumulative - running_max) / running_max
max_drawdown = abs(drawdown.min())

夏普比率

Sharpe=RpRfσpSharpe = \frac{R_p - R_f}{\sigma_p}

sharpe = (returns.mean() * 252 - risk_free_rate) / (returns.std() * np.sqrt(252))

索提诺比率

Sortino=RpRfσdownSortino = \frac{R_p - R_f}{\sigma_{down}}

downside_returns = returns[returns < 0]
downside_std = downside_returns.std() * np.sqrt(252)
sortino = (returns.mean() * 252 - risk_free_rate) / downside_std

卡玛比率

Calmar=RannualMDDCalmar = \frac{R_{annual}}{MDD}

calmar = annual_return / max_drawdown

VaR

var_95 = np.percentile(returns, 5)  # 95% VaR

CVaR

cvar_95 = returns[returns <= var_95].mean()

技术指标公式

移动平均线

SMASMAn=1ni=0n1PtiSMA_n = \frac{1}{n}\sum_{i=0}^{n-1}P_{t-i}

sma = df['Close'].rolling(window=20).mean()

EMAEMAt=α×Pt+(1α)×EMAt1EMA_t = \alpha \times P_t + (1-\alpha) \times EMA_{t-1}

ema = df['Close'].ewm(span=20, adjust=False).mean()

MACD

DIF=EMA12EMA26DIF = EMA_{12} - EMA_{26} DEA=EMA9(DIF)DEA = EMA_9(DIF) MACD=(DIFDEA)×2MACD = (DIF - DEA) \times 2

ema12 = df['Close'].ewm(span=12).mean()
ema26 = df['Close'].ewm(span=26).mean()
dif = ema12 - ema26
dea = dif.ewm(span=9).mean()
macd = (dif - dea) * 2

RSI

RSI=1001001+RSRSI = 100 - \frac{100}{1 + RS}

其中 RS=Average GainAverage LossRS = \frac{Average\ Gain}{Average\ Loss}

delta = df['Close'].diff()
gain = delta.where(delta > 0, 0).rolling(14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))

布林带

Middle=SMAnMiddle = SMA_n Upper=Middle+k×σUpper = Middle + k \times \sigma Lower=Middlek×σLower = Middle - k \times \sigma

middle = df['Close'].rolling(20).mean()
std = df['Close'].rolling(20).std()
upper = middle + 2 * std
lower = middle - 2 * std

ATR

TR=max(HighLow,HighCloseprev,LowCloseprev)TR = \max(High - Low, |High - Close_{prev}|, |Low - Close_{prev}|) ATR=SMAn(TR)ATR = SMA_n(TR)

high = df['High']
low = df['Low']
close_prev = df['Close'].shift(1)
tr = pd.concat([
high - low,
(high - close_prev).abs(),
(low - close_prev).abs()
], axis=1).max(axis=1)
atr = tr.rolling(14).mean()

仓位管理公式

凯利公式

f=p×bqbf^* = \frac{p \times b - q}{b}

其中 pp 是胜率,q=1pq = 1-pbb 是盈亏比。

def kelly_criterion(win_rate, avg_win, avg_loss):
b = avg_win / abs(avg_loss)
p = win_rate
q = 1 - p
kelly = (p * b - q) / b
return max(0, min(kelly, 1))

波动率倒数仓位

Position=Target VolAsset VolPosition = \frac{Target\ Vol}{Asset\ Vol}

position_ratio = target_vol / asset_vol

因子分析指标

IC(信息系数)

IC=corr(Factort,Returnt+1)IC = corr(Factor_t, Return_{t+1})

ic = factor.corr(forward_return)

ICIR

ICIR=ICmeanICstdICIR = \frac{IC_{mean}}{IC_{std}}

icir = ic_series.mean() / ic_series.std()

IR(信息比率)

IR=RpRbσtrackingIR = \frac{R_p - R_b}{\sigma_{tracking}}

excess_return = portfolio_return - benchmark_return
tracking_error = (portfolio_return - benchmark_return).std()
ir = excess_return.mean() / tracking_error

常用数据处理

去极值

def winsorize(series, limits=(0.01, 0.01)):
lower = series.quantile(limits[0])
upper = series.quantile(1 - limits[1])
return series.clip(lower, upper)

标准化

# Z-score标准化
standardized = (series - series.mean()) / series.std()

# Min-Max标准化
normalized = (series - series.min()) / (series.max() - series.min())

# 排名标准化
rank_normalized = series.rank(pct=True)

缺失值处理

# 删除
df.dropna()

# 前向填充
df.fillna(method='ffill')

# 线性插值
df.interpolate(method='linear')

Backtrader常用代码

策略模板

class MyStrategy(bt.Strategy):
params = (('period', 20),)

def __init__(self):
self.ma = bt.indicators.SMA(self.data.close, period=self.params.period)
self.order = None

def notify_order(self, order):
if order.status in [order.Completed]:
pass
self.order = None

def next(self):
if self.order:
return

if not self.position:
if self.data.close[0] > self.ma[0]:
self.order = self.buy()
else:
if self.data.close[0] < self.ma[0]:
self.order = self.sell()

添加分析器

cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades')

常用数据源

数据源类型说明
yfinance免费美股、港股数据
tushare免费/付费A股数据
akshare免费A股、期货数据
Wind付费专业金融数据
Bloomberg付费全球金融数据

常用库列表

# 数据处理
import numpy as np
import pandas as pd

# 数据获取
import yfinance as yf
import tushare as ts

# 技术指标
import talib

# 回测框架
import backtrader as bt

# 机器学习
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import lightgbm as lgb

# 可视化
import matplotlib.pyplot as plt
import seaborn as sns

# 统计分析
from scipy import stats
import statsmodels.api as sm

交易时间参考

市场交易时间(北京时间)
A股9:30-11:30, 13:00-15:00
港股9:30-12:00, 13:00-16:00
美股21:30-04:00 (夏令时) / 22:30-05:00 (冬令时)
期货(日盘)9:00-11:30, 13:30-15:00
期货(夜盘)21:00-次日02:30(部分品种)

风险管理检查清单

  • 单笔风险不超过总资金的2%
  • 总敞口不超过设定上限
  • 设置止损止盈
  • 最大回撤预警
  • 流动性检查
  • 相关性检查
  • 压力测试

策略评估检查清单

  • 样本外测试
  • 参数稳健性检验
  • 交易成本测试
  • 滑点敏感性分析
  • 与基准对比
  • 不同市场环境表现
  • 过拟合检验