AI 量化不是"用 LSTM 预测股价"这么简单。专业做法是把机器学习嵌入完整的量化流水线:数据治理 → 因子构造 → 模型训练 → 信号生成 → 组合优化 → 风险控制 → 回测归因。模型只是其中一环,工程纪律与风控才是长期盈利的关键。
量化策略九成时间花在数据上。必须处理复权、停牌、退市、幸存者偏差。
import pandas as pd
import numpy as np
def load_prices(path: str) -> pd.DataFrame:
df = pd.read_parquet(path)
df["date"] = pd.to_datetime(df["date"])
df = df.sort_values(["symbol", "date"])
# 前复权收盘价
df["adj_close"] = df["close"] * df["adj_factor"]
# 剔除停牌与涨跌停不可交易样本
df = df[~df["suspended"]]
# 计算未来一期收益作为标签
df["ret_fwd"] = df.groupby("symbol")["adj_close"].pct_change().shift(-1)
return df.dropna(subset=["ret_fwd"])注意标签必须 shift(-1) 对齐未来收益,且要防止用未来信息构造因子。
因子是量化的核心。常见类别包括动量、反转、波动率、流动性、估值。以下构造三个经典因子:
def build_factors(df: pd.DataFrame) -> pd.DataFrame:
g = df.groupby("symbol")["adj_close"]
# 20日动量
df["mom20"] = g.pct_change(20)
# 5日反转
df["rev5"] = -g.pct_change(5)
# 20日波动率
df["vol20"] = g.pct_change().groupby(df["symbol"]).rolling(20).std().reset_index(0, drop=True)
# 横截面标准化,消除量纲
for f in ["mom20", "rev5", "vol20"]:
df[f] = df.groupby("date")[f].transform(
lambda x: (x - x.mean()) / (x.std() + 1e-9))
return df.dropna()横截面标准化是专业实践的关键,让因子在不同日期可比。
金融数据信噪比极低,深度模型容易过拟合。推荐 LightGBM 或线性模型,配合时间序列交叉验证。
import lightgbm as lgb
from sklearn.model_selection import TimeSeriesSplit
FEATURES = ["mom20", "rev5", "vol20"]
def train_model(df: pd.DataFrame):
X, y = df[FEATURES], df["ret_fwd"]
tscv = TimeSeriesSplit(n_splits=5)
models, scores = [], []
for train_idx, val_idx in tscv.split(X):
model = lgb.LGBMRegressor(
n_estimators=300, learning_rate=0.05,
num_leaves=31, min_child_samples=50,
subsample=0.8, colsample_bytree=0.8)
model.fit(X.iloc[train_idx], y.iloc[train_idx])
pred = model.predict(X.iloc[val_idx])
ic = np.corrcoef(pred, y.iloc[val_idx])[0, 1]
scores.append(ic)
models.append(model)
print(f"IC均值: {np.mean(scores):.4f}")
return models评价指标用 IC(信息系数)与 ICIR,而非 MSE。IC 稳定在 0.03 以上就值得进一步验证。
预测值不能直接当仓位。需做横截面排序、行业中性、风险约束与成本控制。
from scipy.optimize import minimize
def optimize_weights(signals: pd.Series, cov: pd.DataFrame,
max_weight: float = 0.05) -> pd.Series:
n = len(signals)
mu = signals.values
# 目标:最大化预期收益 - 风险惩罚
def neg_utility(w):
return -(mu @ w - 5 * w @ cov.values @ w)
constraints = [{"type": "eq", "fun": lambda w: w.sum() - 1}]
bounds = [(0, max_weight)] * n
w0 = np.ones(n) / n
res = minimize(neg_utility, w0, bounds=bounds, constraints=constraints)
return pd.Series(res.x, index=signals.index)约束包括:单票上限、行业暴露、换手率惩罚。真实交易还要考虑冲击成本与最小交易单位。
回测必须模拟真实约束:T+1、涨跌停、手续费、滑点。
def backtest(df: pd.DataFrame, signals: pd.Series,
cost: float = 0.0015) -> pd.Series:
weights = signals.groupby("date").apply(
lambda s: s / s.abs().sum()).unstack().fillna(0)
returns = df.pivot(index="date", columns="symbol", values="ret_fwd").fillna(0)
turnover = weights.diff().abs().sum(axis=1).fillna(0)
gross = (weights.shift(1) * returns).sum(axis=1)
net = gross - turnover * cost
return net.cumsum()关键指标:年化收益、夏普、最大回撤、换手率、容量估计。若扣费后夏普低于 1,策略不具备实盘价值。
t 时刻及之前数据,标签对齐未来收益。总结:AI 量化的核心竞争力不在模型复杂度,而在数据质量、因子逻辑、验证严谨与风控执行。代码只是载体,纪律才是护城河。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。