name: “a-share-quant-research”
description: “A股量化投研一条龙:数据清洗→策略研究→回测验证→预测建模→新闻事件→风控评估→执行提示。为散户提供可复现、可审计、可回测的完整投研工具链,将主观炒股升级为数据驱动的系统化交易流程。”
A股量化投研一条龙 Skill
重要声明
本Skill仅提供数据处理、研究分析、回测验证、风险提示和信息整理功能,不构成任何投资建议。
- 市场存在不确定性,任何策略都可能失效
- 过往业绩不代表未来表现
- 使用者需独立做出交易决策并承担风险
- 本Skill旨在"减少拍脑袋、减少信息差、减少自嗨回测",不保证盈利
何时使用本Skill
适用场景
- 需要将零散的数据整合为可用的研究数据集
- 需要验证策略有效性,避免"自嗨式回测"
- 需要评估策略在不同市场环境下的稳健性
- 需要基于概率和分布进行选股/择时决策
- 需要将新闻事件结构化并评估其对持仓的影响
- 需要系统化的风控评估和交易纪律提示
不适用场景
- 寻求"稳赚不赔"的策略推荐
- 需要实时交易执行(本Skill仅提供研究分析和执行提示)
- 无编程基础且不愿学习量化基础概念
- 期望替代独立思考和决策
核心架构
本Skill包含四大核心模块,形成完整投研闭环:
┌─────────────────────────────────────────────────────────────────┐
│ A股量化投研一条龙 │
├─────────────┬─────────────┬─────────────┬─────────────────────┤
│ 模块1 │ 模块2 │ 模块3 │ 模块4 │
│ 数据清洗分析 │ 回测与风控 │ 预测与选股 │ 新闻事件驱动 │
├─────────────┼─────────────┼─────────────┼─────────────────────┤
│ • 行情清洗 │ • 回测引擎 │ • 预测目标 │ • 新闻获取 │
│ • 财务对齐 │ • 策略模板 │ • 防泄露 │ • 事件抽取 │
│ • 特征工程 │ • 风控评估 │ • 模型层 │ • 事件回测 │
│ • 研究视图 │ • 归因分析 │ • 信号落地 │ • 预警订阅 │
└─────────────┴─────────────┴─────────────┴─────────────────────┘
│
▼
┌─────────────────┐
│ 输出交付物 │
│ • 候选股票清单 │
│ • 组合建议 │
│ • 风险面板 │
│ • 事件摘要 │
│ • 回测报告 │
└─────────────────┘
输入规范
最小数据集(必填)
| 输入项 | 说明 | 格式示例 |
|---|---|---|
| 股票池 | 全市场/指定行业/自选股/指数成分 | ["000001.SZ", "600000.SH"] 或 "沪深300" |
| 时间周期 | 研究的时间范围 | {"start": "2020-01-01", "end": "2024-12-31"} |
| 交易规则 | 佣金、印花税、滑点等 | 见下方交易规则配置 |
交易规则配置
commission:
buy: 0.00025 # 买入佣金(万分之2.5) //可手动调整数值
sell: 0.00025 # 卖出佣金 //可手动调整数值
min: 5 # 最低佣金5元 //可手动调整数值
stamp_tax:
sell: 0.001 # 卖出印花税(千分之一) //可手动调整数值
transfer_fee:
rate: 0.00002 # 过户费(万分之0.2) //可手动调整数值
slippage:
model: "dynamic" # 固定: "fixed", 动态: "dynamic"
fixed_bp: 5 # 固定滑点(bp)
dynamic_factor: 1.0 # 动态滑点系数
constraints:
limit_up_buy: false # 涨停是否允许买入
limit_down_sell: false # 跌停是否允许卖出
handle_suspension: true # 处理停牌
rights_issue: true # 处理分红送转
风控偏好配置
risk_preference:
max_drawdown: 0.20 # 最大回撤容忍度 20%
max_single_position: 0.20 # 单票最大仓位 20%
max_industry_exposure: 0.30 # 行业暴露上限 30%
max_turnover: 0.50 # 日换手上限 50%
blacklist: [] # 黑名单股票代码
扩展数据集(可选)
- 行情数据:OHLCV、分钟线、Tick数据
- 财务数据:资产负债表、利润表、现金流量表
- 公告数据:定期报告、临时公告、重大事项
- 新闻数据:财经新闻、研报摘要、宏观政策
- 宏观数据:利率、汇率、PMI、CPI等
模块1:数据清洗分析
1.1 行情数据清洗
功能清单
| 功能 | 说明 | 关键参数 |
|---|---|---|
| 复权处理 | 前复权/后复权,处理分红送转 | adjust_type: "forward" |
| 缺失值处理 | 停牌、上市退市边界、ST处理 | fill_method: "ffill" |
| 异常检测 | 极端跳点、零成交量异常 | zscore_threshold: 4 |
| 交易日历 | 节假日对齐、临时停牌 | 自动同步交易所日历 |
| 指标衍生 | 涨跌幅、振幅、量比、换手率 | 自动计算 |
异常检测规则
# 价格异常
abs(return_t) > 0.21 # 超过21%(考虑科创板/创业板20%涨跌停)
# 成交量异常
volume == 0 and close != close.shift(1) # 零成交但有价格变化
# 涨跌停不一致
abs(close - pre_close) / pre_close > 0.095 and not is_limit
衍生指标列表
| 指标类别 | 指标名称 | 计算说明 |
|---|---|---|
| 价格动量 | return_1d, return_5d, return_20d |
N日涨跌幅 |
| 波动率 | volatility_20d, volatility_60d |
N日滚动标准差 |
| 流动性 | turnover_ratio, amount_ma20 |
换手率、成交额均线 |
| 盘口 | high_low_ratio, intraday_return |
日内高低比、日内收益 |
1.2 财务与估值数据清洗
关键处理规则
时点对齐(防未来函数)
# 财务数据必须按披露日期对齐,而非报告期
# 错误做法:2024-03-31的财报在2024-03-31就能用
# 正确做法:2024-03-31的财报在披露日(如2024-04-25)后才能用
def align_financial_data(df, report_date_col, announce_date_col):
"""
将财务数据按披露日期前向填充
"""
df = df.sort_values(["stock_code", announce_date_col])
df["effective_date"] = df[announce_date_col]
# 前向填充到下一次公告前
df = df.set_index("effective_date").groupby("stock_code").resample("D").ffill()
return df
财务指标口径统一
| 指标类型 | 处理方式 | 示例 |
|---|---|---|
| TTM | 滚动12个月 | revenue_ttm |
| 单季 | 当季值 | profit_q |
| 同比 | 同比增长率 | revenue_yoy |
| 环比 | 环比增长率 | profit_qoq |
异常值处理
- 一次性损益:标记并可选剔除
- 会计重述:检测重述记录,提示数据变更
- 口径变更:行业分类变更时记录历史映射
1.3 基础特征工程
特征库分类
price_momentum:
- momentum_5d: "5日动量"
- momentum_20d: "20日动量"
- reversal_60d: "60日反转"
- breakout_20d: "20日突破信号"
- ma_deviation: "均线偏离度"
- trend_strength: "趋势强度(ADX近似)"
volatility:
- hist_vol_20d: "20日历史波动率"
- vol_percentile: "波动率分位数"
- vol_clustering: "波动聚集指标"
liquidity:
- turnover_ratio: "换手率"
- volume_price_divergence: "量价背离"
- impact_cost_proxy: "冲击成本近似"
cross_section:
- size: "市值因子(对数)"
- value: "价值因子(PB/PE倒数)"
- quality: "质量因子(ROE稳定性)"
- growth: "成长因子(营收增长率)"
- sentiment: "情绪因子(分析师预期)"
style_exposure:
- market_beta: "市场暴露"
- industry_exposure: "行业暴露(申万一级)"
1.4 研究视图输出
单股画像
stock_profile:
trend:
direction: "up/down/sideways"
strength: 0-100
support_levels: [price1, price2]
resistance_levels: [price3, price4]
volatility:
current_vol: "20日波动率"
vol_regime: "high/medium/low"
vol_trend: "increasing/decreasing"
fundamentals:
earnings_trend: "accelerating/stable/decelerating"
valuation_percentile: "历史估值分位"
financial_health: "score 0-100"
events:
upcoming: ["2024-05-20 股东大会", "2024-06-15 分红除权"]
recent: ["2024-04-25 年报发布", "2024-03-10 股权激励"]
行业热度
industry_heatmap:
industry: "电子"
diffusion_index: 0.65 # 涨跌扩散指数
leading_stocks: ["002371.SZ", "603501.SH"]
risk_stocks: ["300XXX.SZ"] # 回撤风险较高
momentum_rank: 3 # 行业动量排名
因子有效性
factor_analysis:
factor_name: "momentum_20d"
ic_mean: 0.03
ic_std: 0.15
ic_ir: 0.20
rank_ic_mean: 0.04
quantile_return_spread: "Q5-Q1 = 1.2%"
stability: "trending/stable/decaying"
数据质量报告
data_quality_report:
coverage:
stocks: 5000
days: 1200
total_records: 6000000
missing:
overall_rate: 0.02
by_field:
close: 0.001
volume: 0.005
financial: 0.15
anomalies:
price_jumps: 120
volume_anomalies: 45
flagged_records: 835
usable_period: "2020-01-02 to 2024-12-31"
模块2:策略回测与风控评估
2.1 回测引擎配置
撮合规则
execution:
price_type: "close" # 可选: open, close, vwap_approx
# 开盘价成交
open_execution:
delay: 1 # T日信号,T+1日开盘成交
slippage_bp: 5
# 收盘价成交
close_execution:
delay: 0 # T日信号,T日收盘成交
slippage_bp: 3
# VWAP近似
vwap_execution:
delay: 1
slippage_model: "volume_weighted"
交易成本模型
def calculate_transaction_cost(amount, is_buy, config):
"""
计算完整交易成本
"""
commission = max(amount * config.commission.rate, config.commission.min)
stamp_tax = amount * config.stamp_tax.sell if not is_buy else 0
transfer_fee = amount * config.transfer_fee.rate
slippage = amount * config.slippage.get_rate(amount)
total_cost = commission + stamp_tax + transfer_fee + slippage
return {
"commission": commission,
"stamp_tax": stamp_tax,
"transfer_fee": transfer_fee,
"slippage": slippage,
"total": total_cost,
"cost_ratio": total_cost / amount
}
涨跌停与停牌处理
limit_constraints:
# 涨停处理
limit_up:
can_buy: false # 涨停不能买入
buy_probability: 0.0 # 或设置成交概率模型
# 跌停处理
limit_down:
can_sell: false # 跌停不能卖出
sell_probability: 0.0
# 停牌处理
suspension:
can_trade: false
position_handling: "frozen" # 持仓冻结
2.2 策略模板库
趋势跟踪策略
class TrendFollowingStrategy:
"""
双均线趋势跟踪策略
"""
params = {
"fast_ma": 20,
"slow_ma": 60,
"trend_filter": True
}
def generate_signals(self, data):
data["fast_ma"] = data["close"].rolling(self.params["fast_ma"]).mean()
data["slow_ma"] = data["close"].rolling(self.params["slow_ma"]).mean()
# 金叉买入,死叉卖出
data["signal"] = np.where(
data["fast_ma"] > data["slow_ma"], 1, -1
)
# 趋势过滤:只在趋势明确时交易
if self.params["trend_filter"]:
data["trend_strength"] = abs(data["fast_ma"] - data["slow_ma"]) / data["slow_ma"]
data["signal"] = np.where(data["trend_strength"] > 0.02, data["signal"], 0)
return data["signal"]
均值回归策略
class MeanReversionStrategy:
"""
布林带均值回归策略
"""
params = {
"window": 20,
"std_multiplier": 2.0,
"holding_period": 5
}
def generate_signals(self, data):
data["ma"] = data["close"].rolling(self.params["window"]).mean()
data["std"] = data["close"].rolling(self.params["window"]).std()
data["upper"] = data["ma"] + self.params["std_multiplier"] * data["std"]
data["lower"] = data["ma"] - self.params["std_multiplier"] * data["std"]
# 触及下轨买入,触及上轨卖出
data["signal"] = 0
data.loc[data["close"] < data["lower"], "signal"] = 1
data.loc[data["close"] > data["upper"], "signal"] = -1
return data["signal"]
因子选股策略
class FactorSelectionStrategy:
"""
多因子选股策略
"""
params = {
"rebalance_freq": "W", # 周度调仓
"top_n": 50,
"factors": {
"value": 0.3,
"quality": 0.3,
"momentum": 0.4
}
}
def generate_signals(self, data):
# 计算综合得分
data["score"] = (
data["value"] * self.params["factors"]["value"] +
data["quality"] * self.params["factors"]["quality"] +
data["momentum"] * self.params["factors"]["momentum"]
)
# 横截面排名,选前N
data["rank"] = data.groupby("date")["score"].rank(ascending=False)
data["signal"] = np.where(data["rank"] <= self.params["top_n"], 1, 0)
return data["signal"]
2.3 风控评估体系
核心风险指标
risk_metrics:
# 收益风险指标
total_return: "总收益率"
annualized_return: "年化收益率"
volatility: "年化波动率"
sharpe_ratio: "夏普比率"
sortino_ratio: "索提诺比率"
calmar_ratio: "卡玛比率"
# 回撤指标
max_drawdown: "最大回撤"
max_drawdown_duration: "最大回撤持续期"
avg_drawdown: "平均回撤"
recovery_time: "回撤恢复时间"
# 交易统计
win_rate: "胜率"
profit_loss_ratio: "盈亏比"
avg_holding_period: "平均持仓周期"
turnover: "换手率"
# 分布特征
skewness: "偏度"
kurtosis: "峰度"
var_95: "95% VaR"
cvar_95: "95% CVaR"
稳健性检查
robustness_tests:
walk_forward:
train_period: 252 # 1年训练
test_period: 63 # 3个月测试
step_size: 63
description: "走动回测,模拟真实上线节奏"
out_of_sample:
split_ratio: 0.7
description: "样本外验证,前70%训练,后30%测试"
parameter_perturbation:
perturbation_range: 0.2 # ±20%
description: "参数扰动测试"
stress_test:
cost_multiplier: 2.0
slippage_multiplier: 2.0
description: "成本和滑点加倍的压力测试"
归因分析
attribution_analysis:
# 行业归因
industry_contribution:
"电子": {"return": 0.05, "weight": 0.20}
"医药": {"return": -0.02, "weight": 0.15}
# 风格归因
style_contribution:
"size": {"exposure": 0.3, "return": 0.02}
"value": {"exposure": -0.1, "return": -0.01}
"momentum": {"exposure": 0.5, "return": 0.04}
# 市场状态归因
regime_contribution:
"bull": {"days": 300, "return": 0.40}
"bear": {"days": 150, "return": -0.15}
"sideways": {"days": 200, "return": 0.05}
# 回撤归因
drawdown_attribution:
- period: "2022-03-15 to 2022-04-26"
drawdown: -0.15
cause: "风格反转(成长→价值)"
contributing_factors: ["高动量暴露", "小盘暴露"]
2.4 回测报告输出
标准回测报告结构
backtest_report:
metadata:
strategy_name: "双均线趋势跟踪"
version: "1.0.0"
backtest_period: "2020-01-01 to 2024-12-31"
data_source: "本地数据"
created_at: "2025-01-15 10:30:00"
performance_summary:
total_return: "45.2%"
annualized_return: "8.1%"
max_drawdown: "-18.5%"
sharpe_ratio: 0.85
calmar_ratio: 0.44
win_rate: "42%"
profit_loss_ratio: 1.8
equity_curve:
# 日度净值序列
dates: [...]
values: [...]
drawdowns: [...]
monthly_returns:
# 月度收益热力图数据
matrix: [...]
trade_log:
- date: "2020-03-15"
action: "BUY"
code: "000001.SZ"
price: 12.5
shares: 1000
cost: 12.53
risk_analysis:
var_analysis: {...}
tail_risk: {...}
stress_test_results: {...}
robustness:
walk_forward_results: {...}
parameter_sensitivity: {...}
attribution:
industry: {...}
style: {...}
regime: {...}
conclusions:
strengths: ["趋势捕捉能力强", "牛市表现优异"]
weaknesses: ["震荡市回撤大", "换手率偏高"]
failure_modes: ["2022年3月风格反转导致15%回撤"]
recommendations: ["建议加入风格过滤器", "考虑加入波动率控制"]
模块3:预测与选股择时
3.1 预测目标定义
多任务预测框架
prediction_targets:
direction:
description: "未来N日涨跌概率"
horizon: [1, 5, 20] # 日度、周度、月度
output: "probability_up"
evaluation: "accuracy, precision, recall, f1, auc"
magnitude:
description: "未来N日收益分布"
horizon: [1, 5, 20]
output: "return_quantiles" # 分位数预测
quantiles: [0.1, 0.25, 0.5, 0.75, 0.9]
evaluation: "pinball_loss, coverage, sharpness"
risk:
description: "未来N日风险指标"
horizon: [1, 5, 20]
output: ["volatility", "max_drawdown_prob", "var"]
evaluation: "rmse, mae"
ranking:
description: "横截面收益排序"
horizon: [5, 20]
output: "rank_score"
evaluation: "ic, rank_ic, ndcg"
3.2 防未来函数与泄露规则
硬规则清单
anti_leakage_rules:
feature_construction:
- "所有特征必须使用t时刻及之前可获得的数据"
- "财务数据必须按披露日期对齐,不能用报告期日期"
- "不能使用未来信息(如下一日开盘价、未来财报)"
- "技术指标计算不能包含未来bar"
data_splitting:
- "必须按时间顺序切分,不能随机打乱"
- "训练集、验证集、测试集时间区间必须严格分离"
- "交叉验证必须使用TimeSeriesSplit,不能用KFold"
target_definition:
- "预测目标必须是未来值,不能用同期或过去值"
- "收益计算必须考虑复权和分红送转"
validation:
- "每个特征必须可追溯数据来源和计算时点"
- "必须提供特征时间戳清单"
时间切分规范
class TimeSeriesSplit:
"""
时间序列切分
"""
def __init__(self, n_splits=5, train_size=504, test_size=126):
self.n_splits = n_splits
self.train_size = train_size # 2年训练
self.test_size = test_size # 半年测试
def split(self, dates):
"""
生成时间切分索引
"""
splits = []
for i in range(self.n_splits):
train_end = self.train_size + i * self.test_size
test_end = train_end + self.test_size
train_dates = dates[:train_end]
test_dates = dates[train_end:test_end]
splits.append((train_dates, test_dates))
return splits
3.3 模型层配置
入门稳健模型
# LightGBM基准模型
lgb_params = {
"objective": "binary", # 或 "regression"
"metric": "auc", # 或 "rmse"
"boosting_type": "gbdt",
"num_leaves": 31,
"learning_rate": 0.05,
"feature_fraction": 0.8,
"bagging_fraction": 0.8,
"bagging_freq": 5,
"verbose": -1,
"max_depth": 6,
"min_child_samples": 50,
"reg_alpha": 0.1,
"reg_lambda": 0.1
}
# 逻辑回归(可解释性强)
from sklearn.linear_model import LogisticRegression
lr_model = LogisticRegression(
penalty='l2',
C=1.0,
class_weight='balanced',
max_iter=1000
)
# 岭回归
from sklearn.linear_model import Ridge
ridge_model = Ridge(alpha=1.0)
时间序列模型(谨慎使用)
# ARIMA基线
from statsmodels.tsa.arima.model import ARIMA
# Prophet(适合有季节性的宏观数据)
from prophet import Prophet
# LSTM(需要大量数据和正则化)
# 警告:LSTM容易过拟合,需要严格的正则化和早停
模型组合策略
ensemble_methods:
factor_plus_model:
description: "因子打分 + 简单模型校准"
steps:
- "计算多因子综合得分"
- "用LightGBM校准因子权重"
- "输出最终排序"
model_with_filter:
description: "模型信号 + 风控过滤 + 组合优化"
steps:
- "生成模型预测信号"
- "应用风控约束过滤"
- "组合优化确定权重"
3.4 可解释性输出
特征重要性
feature_importance:
global:
- feature: "momentum_20d"
importance: 0.15
description: "20日动量因子"
- feature: "turnover_ratio"
importance: 0.12
description: "换手率"
local_shap:
stock: "000001.SZ"
date: "2024-12-31"
top_positive:
- feature: "momentum_20d"
shap_value: 0.05
- feature: "roe_ttm"
shap_value: 0.03
top_negative:
- feature: "volatility_20d"
shap_value: -0.04
3.5 信号到交易落地
信号阈值设定
def signal_to_trade(signal, threshold_config, risk_config):
"""
将模型信号转换为交易决策
"""
# 置信度阈值
if signal["probability"] < threshold_config["min_probability"]:
return {"action": "HOLD", "reason": "置信度不足"}
# 期望收益门槛
expected_return = signal["probability"] * signal["up_return"] + \
(1 - signal["probability"]) * signal["down_return"]
if expected_return < threshold_config["min_expected_return"]:
return {"action": "HOLD", "reason": "期望收益不足覆盖成本"}
# 风险门槛
if signal["var_95"] > risk_config["max_var"]:
return {"action": "HOLD", "reason": "风险超限"}
return {
"action": "BUY" if signal["direction"] == 1 else "SELL",
"confidence": signal["probability"],
"expected_return": expected_return,
"risk": signal["var_95"]
}
仓位函数
def calculate_position(signal, confidence, current_equity, risk_config):
"""
基于置信度和风险确定仓位
"""
# 基础仓位
base_position = risk_config["max_single_position"]
# 置信度调整
confidence_scale = min(confidence / 0.6, 1.0) # 60%置信度为基准
# 风险调整
risk_scale = max(0, 1 - signal["var_95"] / risk_config["max_var"])
# 回撤约束
drawdown_scale = 1.0
if current_equity["drawdown"] > 0.10: # 回撤超10%降仓
drawdown_scale = 0.5
position = base_position * confidence_scale * risk_scale * drawdown_scale
return min(position, risk_config["max_single_position"])
冲突处理
conflict_resolution:
model_vs_news:
scenario: "模型看多但新闻重大利空"
resolution: "降权50%或禁入,标记为需人工复核"
signal_vs_risk:
scenario: "信号触发但已触及止损线"
resolution: "暂停新开仓,仅允许平仓"
concentration_limit:
scenario: "信号集中导致行业暴露超限"
resolution: "按信号强度排序,取前N只至行业上限"
模块4:新闻获取与事件驱动
4.1 新闻获取源
数据源配置
news_sources:
financial_media:
- name: "财联社"
type: "api"
update_freq: "realtime"
categories: ["快讯", "公告", "研报"]
- name: "东方财富"
type: "api/rss"
update_freq: "5min"
categories: ["要闻", "个股", "行业"]
- name: "同花顺"
type: "api"
update_freq: "realtime"
categories: ["7x24", "公告", "研报"]
exchange_announcements:
- name: "上交所公告"
type: "api"
categories: ["定期报告", "临时公告", "监管函"]
- name: "深交所公告"
type: "api"
categories: ["定期报告", "临时公告", "监管函"]
macro_policy:
- name: "央行"
type: "rss"
categories: ["货币政策", "利率调整"]
- name: "证监会"
type: "rss"
categories: ["政策发布", "监管动态"]
4.2 事件抽取与结构化
事件结构化输出
event_structure:
event_id: "EV202412310001"
timestamp: "2024-12-31 10:30:00"
source: "财联社"
entities:
stocks: ["000001.SZ", "600000.SH"]
industries: ["银行"]
concepts: ["金融科技", "数字化转型"]
event_type: "业绩预增"
event_subtype: "年报预增"
sentiment:
label: "positive" # positive/negative/neutral
confidence: 0.85
intensity: "high" # high/medium/low
content:
headline: "XX银行发布2024年业绩预增公告"
summary: "预计净利润同比增长15%-20%,主要受益于..."
keywords: ["业绩预增", "净利润", "增长"]
impact_pathway:
- channel: "盈利预期"
effect: "上调"
magnitude: "medium"
- channel: "估值水平"
effect: "提升"
magnitude: "small"
action_hint:
type: "关注" # 关注/规避/核实/无
urgency: "normal" # urgent/normal/low
rationale: "业绩预增为正面信号,但需核实增长可持续性"
事件类型清单
| 事件类型 | 子类型 | 情绪倾向 | 影响时效 |
|---|---|---|---|
| 业绩类 | 预增/预减/快报/正式报告 | 预增+ / 预减- | 1-5日 |
| 并购类 | 收购/被收购/重组/资产注入 | 视具体情况 | 5-20日 |
| 减持类 | 大股东减持/高管减持 | 负面 | 1-3日 |
| 监管类 | 问询函/监管函/立案调查 | 负面 | 1-5日 |
| 政策类 | 行业政策/宏观政策 | 视具体情况 | 5-60日 |
| 事故类 | 安全事故/质量事故 | 负面 | 1-3日 |
| 诉讼类 | 重大诉讼/仲裁 | 负面 | 1-5日 |
| 分红类 | 分红预案/除权除息 | 中性偏正 | 1-3日 |
4.3 事件回测
事件研究框架
def event_study(events, prices, window=(-10, 10)):
"""
事件研究法回测
Parameters:
-----------
events : DataFrame
事件数据,包含event_date, stock_code, event_type
prices : DataFrame
价格数据
window : tuple
事件窗口 (前N日, 后N日)
Returns:
--------
results : dict
事件效应统计结果
"""
results = {
"car_mean": [], # 累计异常收益均值
"car_std": [], # 累计异常收益标准差
"significance": [], # 统计显著性
"by_type": {} # 按事件类型分组
}
for event_type in events["event_type"].unique():
type_events = events[events["event_type"] == event_type]
# 计算异常收益
abnormal_returns = calculate_abnormal_returns(
type_events, prices, window
)
# 累计异常收益
car = abnormal_returns.cumsum(axis=1)
results["by_type"][event_type] = {
"car_mean": car.mean(),
"car_std": car.std(),
"t_statistic": car.mean() / (car.std() / np.sqrt(len(car))),
"sample_size": len(car)
}
return results
事件效应报告
event_backtest_report:
event_type: "业绩预增"
sample_period: "2020-01-01 to 2024-12-31"
sample_size: 1250
abnormal_return:
t0: 0.025 # 事件日异常收益 2.5%
t1: 0.015 # 事件后1日
t5: 0.008 # 事件后5日累计
statistical_significance:
t0_tstat: 3.5 # t统计量
t0_pvalue: 0.0004 # p值
conclusion: "事件日效应显著为正"
heterogeneity:
by_market_cap:
"小盘": {"car_t5": 0.012, "significance": "***"}
"中盘": {"car_t5": 0.008, "significance": "**"}
"大盘": {"car_t5": 0.003, "significance": "*"}
by_market_regime:
"牛市": {"car_t5": 0.015, "significance": "***"}
"熊市": {"car_t5": -0.002, "significance": "ns"}
"震荡": {"car_t5": 0.006, "significance": "*"}
tradability:
liquidity_impact: "事件日成交量放大2倍,冲击成本可控"
signal_decay: "事件后3日效应衰减50%"
recommendation: "适合事件日或次日开盘介入,持有3-5日"
4.4 预警与订阅
预警规则配置
alert_rules:
watchlist_alerts:
- name: "自选股重大事件"
trigger: "watchlist_stock has event_type in [业绩预减, 立案调查, 重大诉讼]"
urgency: "high"
action: "immediate_notify"
- name: "持仓风险事件"
trigger: "portfolio_stock has negative_event"
urgency: "high"
action: "immediate_notify + risk_assessment"
portfolio_alerts:
- name: "减持预警"
trigger: "portfolio_stock has 大股东减持"
urgency: "medium"
action: "daily_digest"
- name: "退市风险"
trigger: "portfolio_stock has ST风险 or 退市整理"
urgency: "urgent"
action: "immediate_notify + mandatory_review"
industry_alerts:
- name: "行业政策"
trigger: "industry_policy_change in watched_industries"
urgency: "medium"
action: "daily_digest + impact_analysis"
- name: "宏观拐点"
trigger: "macro_indicator_significant_change"
urgency: "medium"
action: "weekly_report"
预警输出格式
alert_output:
alert_id: "AL202412310001"
timestamp: "2024-12-31 14:30:00"
urgency: "high"
trigger:
rule: "持仓风险事件"
stock: "000001.SZ"
event: "业绩预减"
details:
headline: "XX银行业绩预减公告"
summary: "预计2024年净利润同比下降10%-15%"
source: "深交所公告"
link: "http://..."
impact_assessment:
sentiment: "negative"
estimated_impact: "-3% to -5%"
confidence: "medium"
action_hint:
type: "关注/复核"
suggested_actions: ["复核持仓逻辑", "评估止损位", "关注后续公告"]
disclaimer: "本提示仅供参考,不构成投资建议"
related_holdings:
- stock: "000001.SZ"
position: "5%"
unrealized_pnl: "+8%"
days_held: 45
工作流与交付物
每日收盘后工作流(10分钟模式)
daily_workflow:
schedule: "交易日 15:10"
steps:
- step: "数据更新"
actions:
- "更新行情数据"
- "更新财务数据"
- "更新新闻事件"
output: "data_quality_report"
- step: "候选池生成"
actions:
- "运行筛选模型"
- "应用风险过滤(ST、退市、流动性)"
- "应用事件过滤"
output: "candidate_pool"
- step: "明日观察清单"
actions:
- "生成触发条件清单"
- "标注风险点"
- "提供可替代标的"
output: "watchlist_tomorrow"
- step: "风险面板更新"
actions:
- "计算组合风险指标"
- "检查回撤预警"
- "检查集中度风险"
output: "risk_dashboard"
total_time: "~10分钟"
每周工作流(30-60分钟)
weekly_workflow:
schedule: "每周日"
steps:
- step: "模型更新(可选)"
actions:
- "走动训练更新"
- "特征重要性分析"
- "模型漂移检测"
output: "model_update_report"
condition: "每月第1周或漂移检测触发"
- step: "组合再平衡"
actions:
- "生成再平衡建议"
- "计算换手和成本"
- "优化权重分配"
output: "rebalance_proposal"
- step: "周报生成"
actions:
- "收益归因分析"
- "风险暴露回顾"
- "下周事件预览"
output: "weekly_report"
每月复盘工作流
monthly_workflow:
schedule: "每月最后一个交易日"
steps:
- step: "策略退化检查"
actions:
- "对比样本外表现"
- "分析漂移监控指标"
- "识别失效信号"
output: "strategy_health_report"
- step: "参数迭代"
actions:
- "回测参数敏感性"
- "根据证据调整参数"
- "记录变更理由"
output: "parameter_update_log"
- step: "风控规则复盘"
actions:
- "评估止损效果"
- "分析回撤归因"
- "优化风控参数"
output: "risk_review_report"
标准交付物清单
每日交付
| 交付物 | 内容 | 格式 |
|---|---|---|
| 候选股票清单 | 入选原因、触发信号、风险点、替代标的 | Markdown/表格 |
| 组合建议 | 权重、仓位上限、再平衡频率 | YAML/JSON |
| 风险面板 | 回撤预警、波动率、行业集中度、事件风险 | 可视化图表 |
| 新闻事件摘要 | 结构化事件、情绪、置信度、影响路径 | Markdown表格 |
回测报告交付
| 交付物 | 内容 |
|---|---|
| 收益曲线 | 日度净值、回撤曲线 |
| 绩效指标 | 收益、回撤、夏普、胜率、盈亏比 |
| 成本敏感性 | 不同成本假设下的表现 |
| 市场状态拆分 | 牛熊震荡市表现对比 |
| 稳健性检查 | 走动回测、参数扰动、压力测试 |
| 归因分析 | 行业、风格、市场状态贡献 |
| 失败归因 | 最大回撤原因、策略失效场景 |
反人性保护机制
强制披露规则
anti_bias_rules:
full_disclosure:
- "必须同时展示样本内和样本外结果"
- "必须展示压力测试结果"
- "必须展示最大回撤和回撤持续期"
- "必须说明策略失效场景"
overfitting_warnings:
- "参数数量 > 样本量/100 时警告"
- "样本内夏普 > 2.0 且样本外夏普 < 1.0 时警告"
- "特征数量 > 样本量/10 时警告"
- "检测到特征泄露嫌疑时警告"
probability_expression:
- "禁止给出确定性预测"
- "必须用概率和区间表达"
- "必须标注置信度"
- "必须说明不确定性来源"
一键降级策略
fallback_strategies:
model_failure:
trigger: "模型漂移检测触发或样本外表现显著恶化"
fallback: "simple_trend_filter"
description: "切换到简单趋势过滤+低换手因子"
high_volatility_regime:
trigger: "市场波动率超过历史90%分位"
fallback: "risk_off"
description: "降低仓位,增加现金比例"
drawdown_limit:
trigger: "回撤超过15%"
fallback: "stop_new_positions"
description: "暂停新开仓,仅允许平仓"
交易纪律提示
trading_discipline:
entry_rules:
- "信号必须满足所有触发条件才提示操作"
- "未满足条件时不提示,避免情绪干扰"
- "提示内容必须包含明确的入场理由和风控位"
exit_rules:
- "触及止损位必须提示平仓"
- "再平衡日必须提示调仓"
- "风险事件触发必须提示复核"
position_management:
- "单票仓位不得超过上限"
- "行业暴露不得超过上限"
- "日换手不得超过上限"
使用示例
示例1:快速回测一个策略
# 用户输入
"""
请帮我回测一个双均线策略:
- 股票池:沪深300成分股
- 时间:2020-01-01 到 2024-12-31
- 参数:快线20日,慢线60日
- 交易成本:佣金万2.5,印花税千1,滑点5bp
"""
# Skill执行流程
1. 加载沪深300成分股历史数据
2. 配置回测引擎(成本、滑点、涨跌停)
3. 运行双均线策略回测
4. 生成绩效报告和归因分析
5. 输出稳健性检查结果
示例2:生成明日观察清单
# 用户输入
"""
生成明天的观察清单,偏好稳健型,最大回撤容忍15%
"""
# Skill执行流程
1. 更新今日数据
2. 运行选股模型(稳健型配置)
3. 应用风险过滤(ST、退市、流动性)
4. 检查持仓风险事件
5. 生成带触发条件和风控位的观察清单
示例3:事件影响评估
# 用户输入
"""
分析最近一周半导体行业的新闻事件,评估对我的持仓影响
"""
# Skill执行流程
1. 获取半导体行业近一周新闻
2. 抽取结构化事件
3. 匹配用户持仓中的半导体股票
4. 评估事件对持仓的影响
5. 生成风险提示和应对建议
版本管理与复现
版本号规范
versioning:
format: "MAJOR.MINOR.PATCH"
major: "架构级变更,如新增模块"
minor: "功能增强,如新策略模板"
patch: "bug修复,参数微调"
current_version: "1.0.0"
复现清单
reproducibility_checklist:
data:
- "数据版本号"
- "数据来源"
- "数据时间范围"
- "清洗规则版本"
model:
- "模型版本"
- "特征清单"
- "训练配置"
- "随机种子"
backtest:
- "回测引擎版本"
- "交易成本配置"
- "滑点模型"
- "约束规则"
output:
- "报告生成时间"
- "执行环境"
- "依赖版本"
附录
A. 数据字典
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
stock_code |
string | 股票代码 | “000001.SZ” |
trade_date |
date | 交易日期 | “2024-12-31” |
open |
float | 开盘价 | 12.5 |
high |
float | 最高价 | 12.8 |
low |
float | 最低价 | 12.3 |
close |
float | 收盘价 | 12.6 |
volume |
int | 成交量 | 1000000 |
amount |
float | 成交额 | 12600000 |
adj_factor |
float | 复权因子 | 1.5 |
is_limit_up |
bool | 是否涨停 | true |
is_limit_down |
bool | 是否跌停 | false |
is_suspended |
bool | 是否停牌 | false |
B. 配置文件模板
# config.yaml
backtest:
start_date: "2020-01-01"
end_date: "2024-12-31"
initial_capital: 1000000
benchmark: "000300.SH"
data:
stock_pool: "沪深300"
price_data_path: "./data/prices"
financial_data_path: "./data/financial"
trading:
commission_rate: 0.00025
stamp_tax_rate: 0.001
slippage_bp: 5
risk:
max_drawdown: 0.20
max_single_position: 0.20
max_industry_exposure: 0.30
C. 常见问题
Q: 为什么我的回测结果和实盘差异很大?
A: 可能原因包括:1) 未充分考虑滑点和冲击成本;2) 未处理涨跌停和停牌;3) 使用了未来函数;4) 过拟合。请检查回测引擎配置和稳健性检查结果。
Q: 如何判断策略是否过拟合?
A: 关注以下信号:1) 样本内表现远好于样本外;2) 参数敏感性高;3) 特征数量过多;4) 换手率高但收益不稳定。建议进行走动回测和参数扰动测试。
Q: 新闻事件如何量化?
A: 本Skill提供事件研究框架,通过历史数据统计事件窗口内的异常收益来评估事件效应。注意区分统计显著性和经济显著性。
更新日志
v1.3.01 (2026-01-15)
- 初始版本发布
- 完成四大核心模块设计
- 建立完整工作流和交付物规范
- 集成反人性保护机制
本Skill持续迭代中,欢迎反馈使用体验和改进建议。
上述配置只作为个人学习参考示例,本文是作为本人技术学习记录,不代表本人投资建议,股市有风险投资需谨慎