第27章 量化投资Agent的Skill体系设计

第27章 量化投资Agent的Skill体系设计

本章顾问:沈飞(量化策略)、龙马(Skill工程)
预估时长:6小时
本章前置检查

  • □ 已完成第26章的Agent化映射,理解各Agent的职责
  • □ 熟悉Hermes Skill开发流程(第10章)和OpenClaw Skill开发(第4章)
  • □ 掌握Python编程和Pandas数据处理基础

本章难点提示

  • 27.2节的因子挖掘Skill涉及金融统计学知识(IC、IR、分组回测),建议先理解概念再动手写代码。
  • 27.3节回测引擎的选择(Backtrader vs VectorBT)取决于数据规模和策略复杂度,本节提供轻量实现以便理解原理。
  • 27.3节的交易成本精细建模是决定回测真实性的关键,滑点参数不要使用过于乐观的估计(如0.01%)。
  • 27.4节的资金管理Skill涉及凯利公式等仓位计算方法,实盘建议使用半凯利或更保守的分数凯利。

🎯 本章教学目标:为量化投资Agent团队开发核心Skill,包括因子挖掘、回测验证、交易执行、交易成本分析、资金管理等,提供完整的SKILL.md模板和可运行Python代码,使读者能够直接复用并适配自己的策略。

图片[1]-量化投资Agent Skill体系完全教程:从因子挖掘到资金管理的生产级交付

27.1 量化投资核心Skill清单

🎯 本节目标:总览量化系统中需要开发的Skill全貌,确定优先级和依赖关系。

预计时长:0.5小时

27.1.1 Skill分类与优先级

类别Skill名称优先级归属Agent依赖
数据层Data Fetch & CleanP0Data Pipeline AgentTushare API
因子挖掘Factor GenerationP0Factor Mining Agent数据层Skill
Factor EvaluationP0Factor Evaluation AgentFactor Generation
Factor CorrelationP1Factor Evaluation AgentFactor Evaluation
策略研发Backtest EngineP0Strategy R&D Agent数据层Skill
Parameter OptimizationP1Strategy R&D AgentBacktest Engine
交易执行Trade ExecutionP0Trade Execution Agent行情数据
Slippage ModelP1Trade Execution AgentTrade Execution
Transaction Cost AnalysisP1Algorithm Optimizer AgentExecution日志
风险管理Risk Metrics (VaR/Drawdown)P0Risk Monitor Agent持仓+行情
Stop LossP1Risk Execution AgentRisk Metrics
资金管理Position Sizing (Kelly)P1Portfolio Manager Agent策略绩效
运维Health CheckP1Ops Agent

本章重点实现P0级别的Skill,P1可在后续扩展中自行开发。

龙马注:Skill的开发顺序应该遵循数据依赖关系。先开发Data Fetch & Clean,再开发Factor Generation,然后才是Backtest Engine。不要一上来就写复杂的资金管理Skill,没有前序结果它无法测试。

🛠️ 实践任务(本节):在项目根目录创建skills/文件夹,按上述清单建立子目录(如factor_generation/backtest_engine/等)。

💭 本节总结(不看书写3行):
1.
2.
3.

📊 用时记录:计划____min → 实际____min → 偏差原因:________

27.2 核心Skill深度拆解:因子挖掘Skill + 回测验证规范

🎯 本节目标:开发因子挖掘Skill,实现候选因子生成、IC/IR计算,并掌握回测验证规范,避免过拟合前视偏差。

预计时长:2小时

27.2.1 因子挖掘Skill(Hermes)

因子挖掘Agent的核心能力是从历史数据中自动发现与未来收益相关的信号。本Skill实现一种简单的因子挖掘方式:对给定的特征表达式(如close/ref(close,5)-1)计算IC和分组收益。

目录结构

~/.hermes/skills/factor_mining/
├── SKILL.md
├── scripts/
│   ├── factor_tools.py
│   └── requirements.txt
└── references/
    └── factor_ic_thresholds.md

SKILL.md

markdown

---
name: factor_mining
description: 挖掘候选因子,计算IC/IR和分组收益。输入股票池和日期范围,输出所有候选因子的绩效指标。
author: hermes-agent
version: 1.0.0
tags: [quant, factor, alpha]
---

# 因子挖掘技能

## 触发器
- /factor mine [股票池] [开始日期] [结束日期]
- 定时任务(每日凌晨)

## 环境变量
- TUSHARE_TOKEN:Tushare API token(由全局.env提供)
- FACTOR_CANDIDATES_LIST:候选因子表达式配置文件路径

## 执行步骤
1. 读取候选因子表达式列表(可配置的表达式库)
2. 使用`scripts/factor_tools.py`中的`calculate_factor_ic`函数计算每个因子的IC序列、IR和分组收益
3. 筛选出IC绝对值>0.03、IR>0.5、分组单调性合格的因子
4. 输出JSON结果到共享记忆的`research.factor_candidates`键

## 输出格式
```json
{
  "factor_name": "momentum_5d",
  "ic_mean": 0.045,
  "ic_std": 0.12,
  "ir": 0.375,
  "group_returns": [0.001, 0.002, 0.005, 0.008, 0.012],
  "status": "candidate"
}

约束

  • 严格避免未来函数:计算因子值时只能使用截止到T日的历史数据,不包含T+1日信息
  • 因子数据与收益数据必须对齐(同一交易日期)
  • 至少需要24个月的历史数据才能保证IC稳定
**scripts/factor_tools.py**(核心代码片段):
```python
import tushare as ts
import pandas as pd
import numpy as np
from scipy import stats

def get_universe_returns(universe, start_date, end_date):
    """获取股票池的日收益率(对齐后)"""
    pro = ts.pro_api()
    # 获取所有股票的日线行情
    df = pro.daily(trade_date=end_date)  # 简化示例,实际应循环日期
    df['trade_date'] = pd.to_datetime(df['trade_date'])
    df = df[df['ts_code'].isin(universe)]
    df['ret'] = df['close'].pct_change()
    return df.pivot(index='trade_date', columns='ts_code', values='ret')

def calculate_factor(factor_expr, data):
    """根据表达式计算因子值"""
    # 示例:factor_expr = "close / ref(close, 5) - 1"
    # 实际应使用eval或更安全的方式(如自定义函数映射)
    # 这里简化为预先定义的函数
    if 'momentum' in factor_expr:
        period = int(factor_expr.split('_')[-1].replace('d',''))
        return data['close'].pct_change(period)
    else:
        raise NotImplementedError

def calculate_ic(factor_series, forward_returns):
    """
    计算IC(信息系数):因子值与下期收益的相关系数
    factor_series: Series, index=trade_date, values=factor_value
    forward_returns: Series, index=trade_date, values=1日收益
    """
    # 对齐时间索引
    common_idx = factor_series.index.intersection(forward_returns.index)
    factor = factor_series[common_idx]
    ret = forward_returns[common_idx]
    ic = factor.corr(ret)
    return ic

def calculate_ir(ic_series):
    """计算IR(信息比率)= IC均值 / IC标准差"""
    return ic_series.mean() / ic_series.std()

def group_returns(factor_series, forward_returns, n_groups=5):
    """
    分组收益:按因子值从小到大分成5组,计算每组的平均收益
    用于验证因子的单调性(高因子值组应获得更高收益)
    """
    # 按日期分组
    dates = factor_series.index.unique()
    group_ret = []
    for d in dates:
        f = factor_series.loc[d].dropna()
        r = forward_returns.loc[d].dropna()
        common = f.index.intersection(r.index)
        if len(common) < 5:
            continue
        f_aligned = f[common]
        r_aligned = r[common]
        # 分组
        labels = pd.qcut(f_aligned, n_groups, labels=False)
        group_mean = r_aligned.groupby(labels).mean()
        group_ret.append(group_mean)
    return pd.DataFrame(group_ret).mean().tolist()

27.2.2 回测验证规范(避免常见陷阱)

陷阱定义检验方法修复措施
前视偏差使用了未来数据计算因子值回测程序严格按时间顺序,当日因子值不可包含当日收盘价(除非是日内策略)使用Ref函数确保因子值基于历史切片。Tushare的adj_factor已包含未来复权信息,需注意。
过拟合因子在样本内表现好,样本外失效划分训练集(如前3年)和验证集(后1年)只在验证集上评估最终结果,若IC下降超过50%则拒绝
幸存者偏差回测中只包含当前存活的股票对比回测股票池与历史实际成分股(如剔除上市不足1年的股票)
剔除上市不足60天、退市前60天的股票
使用Tushare的stock_basic接口中的list_datedelist_date字段
数据挖掘偏差 测试了大量因子后,表现好的纯属偶然控制多重检验,记录测试总数,要求统计显著性(t-stat>3)对因子IC进行t检验,要求p值<0.01

回测引擎选择建议

引擎优点缺点适用场景
Backtrader功能全面,事件驱动,支持复杂策略学习曲线陡峭,速度较慢中低频日线策略
VectorBT向量化计算,极快,支持参数网格搜索对高频数据支持弱因子分析、参数优化
自研轻量灵活可控,易调试需要自己实现所有功能教学、简单策略

本章后续使用自研轻量引擎,便于展示逻辑。生产环境可迁移至VectorBT。

沈飞注:回测验证规范是区分业余和专业的核心。我曾见过一个团队因前视偏差导致回测年化50%、实盘却亏损20%的惨剧。请务必将上表中的检验方法自动化集成到你的回测Skill中,让Agent每次运行都自动检查这些陷阱。

🛠️ 实践任务(本节)

  1. 编写一个简单候选因子表达式(如5日动量),调用factor_tools.py计算其IC和分组收益
  2. 训练/验证集划分方式,观察样本内和样本外的IC差异
  3. 将上述逻辑封装为Hermes Skill,手动或Cron调度运行

💭 本节总结(不看书写3行):
1.
2.
3.

📊 用时记录:计划____min → 实际____min → 偏差原因:________

27.3 核心Skill深度拆解:交易执行Skill + 交易成本精细建模

🎯 本节目标:实现交易执行Skill,包括订单拆分、算法选择和滑点建模,并完成交易成本分析Skill,自动分解成本构成。

预计时长:2小时

27.3.1 交易执行Skill(OpenClaw)

交易执行Agent属于OpenClaw,因为它执行确定性规则,不需要学习进化。本Skill负责将信号转化为实际订单,管理滑点和算法选择。

目录结构(OpenClaw工作区下):

~/.openclaw/workspace/skills/trade_execution/
├── SKILL.md
├── scripts/
│   ├── execution.py
│   └── slippage_models.py
└── references/
    └── broker_config.yaml

SKILL.md

markdown

---
name: trade_execution
description: 执行交易信号,支持TWAP/VWAP拆单,动态滑点模型,支持模拟盘和实盘模式。
---

## 触发器
- 接收到`signal`事件(从共享记忆)
- 手动命令:/execute [signal_id]

## 环境变量
- TRADE_MODE: SIMULATE / PAPER / LIVE
- BROKER_API_KEY: 券商API密钥(仅LIVE模式)

## 执行步骤
1. 读取信号:从共享记忆的`management.tasks`队列获取待执行信号
2. 选择算法:根据订单大小(volume)和流动性,选择TWAP(默认)或VWAP(大盘股)
3. 估算滑点:调用`slippage_models.py`中的`estimate_slippage`函数
4. 生成子订单:将母单拆分为多个子单,发送到券商API(或模拟)
5. 更新共享记忆:写入`execution.orders`和`execution.positions`
6. 审批:若TRADE_MODE=LIVE,需等待人工审批(通过飞书按钮)后再执行

## 约束
- 单笔母单金额不得超过账户净值的10%(限制过度集中)
- 每天总交易次数不超过5次(防止过度交易)
- 实盘模式必须经过审批,且风险监控标志`risk.pause_trading`为false

scripts/execution.py(关键代码):

python

def twap_split(volume, start_time, end_time, total_minutes=30):
    """时间加权平均价格(Time-Weighted Average Price)拆分
    Args:
        volume: 总股数
        start_time, end_time: 交易时间段
        total_minutes: 拆单总时长(分钟)
    Returns:
        子订单列表,每个元素为{'time': datetime, 'volume': int}
    """
    interval = total_minutes / 10   # 拆分成10份
    sub_volume = volume / 10
    timestamps = pd.date_range(start=start_time, end=end_time, periods=10)
    return [{'time': t, 'volume': int(sub_volume)} for t in timestamps]

def estimate_slippage(volume, avg_volume_15min, price):
    """
    简单滑点模型:假定滑点与订单量占市场15分钟成交量的比例成正比
    slippage = base_slippage + coeff * (volume / avg_volume_15min)
    """
    BASE_SLIPPAGE = 0.0005   # 0.05%基础滑点
    COEFF = 0.01
    ratio = volume / max(avg_volume_15min, 1)
    return price * (BASE_SLIPPAGE + COEFF * ratio)

27.3.2 交易成本精细建模(Hermes Skill)

交易成本分析Agent定期从共享记忆的execution.orders中读取实际成交记录,分解成本构成,并生成优化建议。

SKILL.md

markdown

---
name: transaction_cost_analysis
description: 分析实盘或模拟交易的成本构成,包括佣金、印花税、冲击成本、延迟成本、机会成本,生成优化报告。
author: hermes-agent
---

## 触发器
- Cron每日收盘后触发
- 用户请求:/tca [日期范围]

## 执行步骤
1. 从共享记忆读取指定日期范围内的订单记录和成交明细
2. 计算各成本项:
   - 佣金 = 成交金额 * 券商费率(如万2.5)
   - 印花税 = 成交金额 * 0.001(仅在卖出时收取,A股)
   - 冲击成本 = (实际成交均价 - 信号价格) * 成交股数(买入时为正)
   - 延迟成本 = 信号发出时间到第一笔成交的时间 * 价格波动率
   - 机会成本 = 未成交部分的预期收益(采用信号价格与收盘价差估算)
3. 汇总产生报告,输出到`management.tasks`供人查阅
4. 如果冲击成本过大,建议修改执行算法或拆单策略

## 输出格式示例

交易成本分析报告(2025-01-01 至 2025-01-31)
总交易金额:1,000,000 元
佣金:250.00 (0.025%)
印花税:500.00 (0.05%)
冲击成本:1,200.00 (0.12%)
延迟成本:300.00 (0.03%)
机会成本:0.00 (0.00%)
总成本占比:0.22%
优化建议:冲击成本偏高,建议将拆单时长从30分钟延长到60分钟。

scripts/cost_analysis.py

python

def compute_impact_cost(order_records):
    """计算冲击成本(假设signal_price为信号发出时的价格,exec_price为成交均价)"""
    impact = sum((order['exec_price'] - order['signal_price']) * order['volume'] for order in order_records if order['side'] == 'BUY')
    impact += sum((order['signal_price'] - order['exec_price']) * order['volume'] for order in order_records if order['side'] == 'SELL')
    return impact

def compute_latency_cost(order_records, volatility_per_second=0.0001):
    """延迟成本估算,假设每延迟一秒,价格波动一个标准差"""
    latency_seconds = (order['first_exec_time'] - order['signal_time']).total_seconds()
    return sum(latency_seconds * price * volatility_per_second * volume for price, volume, latency)

沈飞注:交易成本模型是量化中常被忽视却极其重要的环节。我见过很多策略在回测中没考虑冲击成本,实盘时因流动性差导致严重滑点而亏损。建议你在模拟盘中启用impact_cost监控,观察不同拆单策略的效果差异,找到适合你策略的最优参数。

🛠️ 实践任务(本节)

  1. 编写交易执行Skill,在模拟盘中执行一次信号拆分(例如买入1000股),记录成交记录
  2. 手动触发交易成本分析Skill,查看成本构成
  3. 尝试调整拆单参数(如改为VWAP),对比冲击成本的变化

💭 本节总结(不看书写3行):
1.
2.
3.

📊 用时记录:计划____min → 实际____min → 偏差原因:________

27.4 量化资金管理方法论

🎯 本节目标:开发资金管理Skill,实现凯利公式、风险平价、波动率目标等仓位计算方法。

预计时长:1.5小时

27.4.1 资金管理Skill(Portfolio Manager Agent)

资金管理决定每次交易下多少仓位。本Skill实现三种经典方法,可根据策略特征选用。

SKILL.md

markdown

---
name: position_sizing
description: 根据策略历史绩效和当前市场状态,计算最优仓位比例。
author: hermes-agent
---

## 触发器
- 策略发出信号前
- 每日盘前重新校准

## 计算方式

### 1. 凯利公式 (Kelly Criterion)
用于具有明确胜率和盈亏比的策略。  
公式:f = (p * b - q) / b  
其中:p = 胜率,b = 平均盈亏比,q = 1-p  
**风险控制**:使用半凯利(f_half = f / 2)或分数凯利(如0.25倍),避免过度冒险。

### 2. 风险平价 (Risk Parity)
用于多资产组合,使每个资产对组合风险的贡献相等。  
实现方式:优化权重使得资产的风险贡献(权重*边际风险)相等。

### 3. 波动率目标 (Volatility Targeting)
根据当前波动率动态调整仓位,使策略波动率稳定在目标水平。  
公式:仓位 = 目标波动率 / 当前波动率(截断在0~1之间)

## 执行步骤
1. 读取策略的历史信号和收益序列(从共享记忆)
2. 计算胜率、盈亏比、波动率
3. 选择资金管理方法(可通过参数指定)
4. 计算本笔交易的建议仓位比例(0~1)
5. 写入`execution.position_sizing`键,供交易Agent使用

## 约束
- 单策略仓位上限:绝对不超过30%(防止黑天鹅)
- 组合总仓位上限:不超过100%(无杠杆)

scripts/kelly.py

python

def kelly_fraction(win_rate, avg_win, avg_loss):
    """
    win_rate: 胜率(0~1)
    avg_win: 平均盈利金额
    avg_loss: 平均亏损金额(正值)
    """
    b = avg_win / avg_loss
    f = (win_rate * (b + 1) - 1) / b
    # 限制最大仓位50%
    return min(max(f, 0), 0.5)

def half_kelly(win_rate, avg_win, avg_loss):
    return kelly_fraction(win_rate, avg_win, avg_loss) / 2

def volatility_targeting(df_returns, target_vol=0.15, lookback=20):
    """目标波动率:根据历史波动率调整仓位"""
    current_vol = df_returns['strategy_returns'].tail(lookback).std() * np.sqrt(252)
    if current_vol == 0:
        return 0
    raw_weight = target_vol / current_vol
    return min(raw_weight, 1.0)

27.4.2 实盘中的保守建议

方法理论仓位建议实盘仓位理由
凯利公式可能高达100%不超过10%胜率和盈亏比估计有误差,需极大安全边际
风险平价根据风险贡献总仓位≤80%保留现金应对黑天鹅
波动率目标动态0~1上限50%杠杆易放大亏损

沈飞注:资金管理是决定长期存活的关键,比策略选择更重要。我强烈建议初学者从固定仓位(如每笔2%)开始,熟悉后再引入动态资金管理。不要一开始就用凯利公式全押——那会加速毁灭。

🛠️ 实践任务(本节)

  1. 生成一组模拟策略绩效(胜率55%,盈亏比1.5),计算凯利和半凯利仓位
  2. 编写波动率目标计算函数,并用历史沪深300指数日收益测试
  3. 将资金管理Skill集成到Portfolio Manager Agent,在发出信号前自动输出建议仓位

💭 本节总结(不看书写3行):
1.
2.
3.

📊 用时记录:计划____min → 实际____min → 偏差原因:________

27.5 🚨 常见误解:资金管理中“凯利公式直接满仓”的危险性

🎯 本节目标:警示读者对凯利公式的误用,强调风险控制。

预计时长:0.2小时

误解

“凯利公式告诉我应该下注50%的仓位,这样长期收益最大。我照做!”

真相

  • 输入误差敏感:胜率和盈亏比都是估计值,微小误差会导致仓位偏离最优。
  • 破产风险:即使凯利最优,仍有可能连续亏损导致账户大幅缩水。
  • 非高斯分布:市场收益具有肥尾特征,黑天鹅事件远超正态分布假设。

正确用法

  • 采用分数凯利(如半凯利、四分之一凯利)。
  • 设置绝对仓位上限(如单策略不超过10%)。
  • 将资金管理视为“生存第一,增长第二”的工具。

沈飞注:我在实盘中只用半凯利,而且只用于经过至少两年实盘验证的策略。对于新策略,固定仓位1%直到有足够信心。

🛠️ 实践任务(本节):模拟一个胜率60%、盈亏比1的策略,分别用全凯利和半凯利运行1000次蒙特卡洛模拟,对比最终的权益曲线和最大回撤。

💭 本节总结(不看书写3行):
1.
2.
3.

📊 用时记录:计划____min → 实际____min → 偏差原因:________

第27章 参考资料与扩展阅读

  1. Backtrader官方文档 https://www.backtrader.com/
  2. VectorBT快速入门 https://github.com/polakowo/vectorbt
  3. 凯利公式在投资中的应用(《凯利资本增长模型》) https://www.investopedia.com/articles/trading/04/091504.asp
  4. 交易成本分析的最佳实践(QuantConnect) https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/alpha/alpha-model
  5. Tushare因子数据接口 https://tushare.pro/document/2?doc_id=143

第五篇综合任务(第27章完成后)

任务:完成以下所有检查项。

  • 实现因子挖掘Skill,对一种技术因子(如RSI)计算IC和分组收益
  • 编写回测验证规范检查清单,并集成到回测脚本中
  • 实现交易执行和交易成本分析Skill,在模拟盘上测试一笔交易的成本分解
  • 实现资金管理Skill,为双均线策略计算建议仓位
  • (可选)将上述Skill部署到对应的Agent中,通过飞书命令触发执行

完成后,打包所有Skill的代码和配置文件,命名为chapter27_skills.zip

顾问审校意见

沈飞:

“第27章涵盖了量化系统最核心的三个技能:因子挖掘、交易执行和资金管理。其中因子挖掘的IC计算和分组收益是体系内标准流程,本章给出的代码可以直接使用。交易成本精细建模是很多书会忽略的部分,本章明确给出了冲击成本、延迟成本的计算方法,值得称赞。

资金管理部分,凯利公式的极端危险性必须反复强调。建议在实盘中永远只用半凯利,并且结合波动率目标来限制总仓位。另外,本章缺少对跨策略资金分配的讨论,例如当你有多个策略时,如何分配资金给每个策略(可以基于均值-方差优化)。这个留作后续扩展。”

龙马:

“本章的Skill代码结构清晰,可以直接放到~/.hermes/skills/~/.openclaw/workspace/skills/中使用。有几个实用建议:

因子挖掘Skill中,候选因子表达式通常很多,建议在Skill外部配置一个factor_candidates.json文件,Skill读取它循环计算。

交易执行Skill中的滑点模型,可以使用更精确的基于订单簿的模型(需Level2数据),本章提供的线性模型已足够入门。

资金管理计算中,凯利函数要注意avg_loss为0的情况(如从未亏损),应设置默认最小亏损值避免除零。

此外,建议读者在scripts/目录中为每个Skill写单元测试,例如测试kelly_fraction在极端输入下的表现。这能避免在生产环境中因除零或NaN导致的Agent崩溃。”

下一章预告:第28章 量化投资Agent系统的完整配置与实现 —— 你将整合前27章的所有成果,配置Portfolio Manager、Risk Management等核心Agent的完整配置文件,搭建ACP通信、共享记忆和Cron调度,最终形成一个可运行的一人量化投资平台。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容