交易策略理论

1. 交易策略定义

1.1 策略的核心组成

交易策略 = 信号生成 + 仓位管理 + 风险控制 + 执行规则

市场数据 → 特征工程 → 模型预测 → 信号生成
                            ↓
                        投资组合构建 → 交易执行 → 绩效评估

1.2 四个关键组成部分

1. 信号生成

定义:决定买什么、卖什么

常见方法

  • Top-K 策略:选择预测最好的 K 只股票
  • 回归预测:预测每只股票的收益率
  • 分类预测:预测股票的涨跌

输出:股票选择或买卖信号

def generate_signals(predictions, method='topk', k=20):
    """
    生成交易信号
    
    参数:
        predictions: 股票预测分数
        method: 策略方法 ('topk', 'regression', 'classification')
        k: 选择股票数量(Top-K策略)
    
    返回:
        signals: 交易信号
    """
    if method == 'topk':
        # 选择预测分数最高的K只股票
        topk = predictions.nlargest(k)
        signals = (predictions >= topk.min()).astype(int)
    elif method == 'regression':
        # 使用回归预测值作为信号
        signals = predictions
    elif method == 'classification':
        # 使用分类预测结果(1=买入, -1=卖出)
        signals = predictions
    
    return signals

2. 仓位管理

定义:决定买多少、卖多少

常见方法

  • 等权重:每只股票分配相同资金
  • IC加权:根据历史IC值分配权重
  • 风险平价:等风险贡献
  • MV优化:均值-方差优化

输出:每只股票的权重分配

3. 风险控制

定义:限制投资风险

常见方法

  • 最大单股权重限制
  • 行业分散要求
  • 止损策略
  • 风险平价

输出:仓位调整或平仓信号

4. 执行规则

定义:何时调仓、如何执行

常见方法

  • 定期调仓:每日、每周、每月调仓
  • 触发调仓:达到某个条件时调仓

输出:交易指令


2. 量化投资基础概念

2.1 信息系数(IC)

定义:预测分数与实际收益的秩相关系数

计算公式

IC = RankCorrelation(预测分数, 实际收益)

Python 实现

from scipy.stats import spearmanr
 
def calculate_ic(predictions, returns):
    """
    计算 IC(信息系数)
    
    参数:
        predictions: 预测分数
        returns: 实际收益率
    
    返回:
        ic: IC 值
    """
    ic, _ = spearmanr(predictions, returns)
    return ic
 
# 示例
predictions = pd.Series([0.05, 0.03, 0.01, -0.02, -0.05])
returns = pd.Series([0.06, 0.04, 0.02, -0.01, -0.04])
 
ic = calculate_ic(predictions, returns)
print(f"IC = {ic:.4f}")

IC 含义

  • IC > 0.05:模型有一定预测能力
  • IC > 0.1:模型预测能力较强
  • IC < 0:预测方向错误

ICIR(信息比率)

ICIR = mean(IC) / std(IC)
def calculate_icir(ic_series):
    """
    计算 ICIR(信息比率)
    
    参数:
        ic_series: IC 序列
    
    返回:
        icir: ICIR 值
    """
    icir = ic_series.mean() / ic_series.std()
    return icir

2.2 换手率

定义:衡量交易活跃程度的指标

计算公式

换手率 = 交易额 / 平均资产

Python 实现

def calculate_turnover(portfolio_changes, avg_value):
    """
    计算换手率
    
    参数:
        portfolio_changes: 持仓变化(绝对值)
        avg_value: 平均资产价值
    
    返回:
        turnover: 换手率
    """
    turnover = portfolio_changes.abs().sum() / avg_value
    return turnover
 
# 示例
# 假设某日持仓变化
portfolio_changes = pd.Series({
    '600000': 100000,   # 买入10万
    '600001': -50000,   # 卖出5万
    '600002': 80000,    # 买入8万
})
 
avg_value = 1000000  # 平均资产100万
turnover = calculate_turnover(portfolio_changes, avg_value)
print(f"换手率 = {turnover:.2%}")

换手率含义

  • 高换手率:交易频繁,成本高
  • 低换手率:交易少,成本低
  • 过高换手可能损害收益

换手率范围

  • 低频策略:50%-100%
  • 中频策略:100%-300%
  • 高频策略:300%-1000%

2.3 回撤

定义:从历史最高点到当前点的跌幅

计算公式

回撤 = (当前净值 - 历史最高净值) / 历史最高净值

最大回撤

最大回撤 = min(回撤)  # 回撤的最小值

Python 实现

def calculate_drawdown(cumulative_returns):
    """
    计算回撤
    
    参数:
        cumulative_returns: 累计收益率序列
    
    返回:
        drawdown: 回撤序列
        max_drawdown: 最大回撤
    """
    # 计算累计净值
    cumulative_value = (1 + cumulative_returns).cumprod()
    
    # 计算历史最高点
    running_max = cumulative_value.expanding().max()
    
    # 计算回撤
    drawdown = (cumulative_value - running_max) / running_max
    
    # 最大回撤
    max_drawdown = drawdown.min()
    
    return drawdown, max_drawdown
 
# 示例
returns = pd.Series([0.01, 0.02, -0.01, 0.03, -0.02, 0.01, -0.03])
drawdown, max_drawdown = calculate_drawdown(returns)
 
print(f"最大回撤 = {max_drawdown:.2%}")
print(f"当前回撤 = {drawdown.iloc[-1]:.2%}")

3. Top-K 策略

3.1 核心思想

  1. 对所有股票的预测分数排序
  2. 选择预测最好的 K 只股票
  3. 按某种权重分配资金(通常等权重)
  4. 定期调仓

3.2 算法步骤

def top_k_strategy(predictions, k=20):
    """
    Top-K 投资组合策略
    
    参数:
        predictions: 股票预测分数
        k: 选择股票数量
    
    返回:
        weights: 股票权重,权重和为1
    """
    # 1. 按预测分数排序(降序)
    sorted_predictions = predictions.sort_values(ascending=False)
    
    # 2. 选择 Top-K
    top_k = sorted_predictions[:k]
    
    # 3. 计算等权重
    weight = 1.0 / k
    
    # 4. 分配权重
    weights = pd.Series(0, index=predictions.index)
    weights[top_k.index] = weight
    
    return weights
 
# 示例
predictions = pd.Series({
    '600000': 0.025,
    '600001': 0.023,
    '600002': 0.010,
    '600003': 0.009,
    '600004': -0.015,
})
 
weights = top_k_strategy(predictions, k=3)
print("Top-K 权重分配:")
print(weights)

示例输出

Top-K 权重分配:
600000    0.333333
600001    0.333333
600002    0.333333
600003    0.000000
600004    0.000000
dtype: float64

3.3 优势与风险

优势

  • ✅ 简单直观,易于实现
  • ✅ 集中投资在最有把握的股票
  • ✅ 自动分散风险(持有多只股票)
  • ✅ 管理成本低,易于维护

风险

  • ⚠️ 对预测质量敏感
  • ⚠️ 可能集中投资相似股票
  • ⚠️ 换手率可能较高
  • ⚠️ 没有考虑风险和相关性

3.4 参数选择

K 值的影响

  • K 小(如10):集中度高,风险大,潜在收益高
  • K 大(如50):分散度高,风险低,收益可能降低
  • K = 全市场:等权重市场组合,接近指数投资

实践建议

  • K 通常选择 20-50 之间
  • 根据流动性调整 K 值
  • 考虑市场环境调整 K 值

4. IC 权重策略

4.1 核心思想

根据历史 IC 值分配权重,预测能力强的股票获得更高权重

4.2 IC 计算方法

单期 IC

IC_t = RankCorrelation(预测分数_t, 实际收益_t)

滚动 IC

# 计算过去 N 期的平均 IC
IC_rolling = mean(IC_{t-N+1}, ..., IC_t)

Python 实现

def calculate_rolling_ic(predictions, returns, window=20):
    """
    计算滚动 IC
    
    参数:
        predictions: 预测分数 DataFrame (index: date, columns: stock)
        returns: 实际收益率 DataFrame (index: date, columns: stock)
        window: 滚动窗口大小
    
    返回:
        rolling_ic: 滚动 IC DataFrame
    """
    rolling_ic = pd.DataFrame(index=predictions.index, columns=predictions.columns)
    
    for stock in predictions.columns:
        for date in predictions.index[window:]:
            # 获取窗口期数据
            pred_window = predictions.loc[date - window + 1: date, stock]
            ret_window = returns.loc[date - window + 1: date, stock]
            
            # 计算 IC
            ic, _ = spearmanr(pred_window, ret_window)
            rolling_ic.loc[date, stock] = ic
    
    return rolling_ic

4.3 权重分配方法

方法 1:直接 IC 权重

def ic_weight_direct(rolling_ic, min_ic=0.02):
    """
    直接 IC 权重分配
    
    参数:
        rolling_ic: 滚动 IC
        min_ic: 最小 IC 阈值
    
    返回:
        weights: 股票权重
    """
    # 只选择 IC > min_ic 的股票
    valid_stocks = rolling_ic[rolling_ic > min_ic]
    
    # 根据 IC 分配权重
    weights = valid_stocks / valid_stocks.sum()
    
    return weights

方法 2:IC 绝对值权重

def ic_weight_absolute(rolling_ic, min_ic=0.02):
    """
    IC 绝对值权重分配
    
    参数:
        rolling_ic: 滚动 IC
        min_ic: 最小 IC 阈值
    
    返回:
        weights: 股票权重
    """
    # 取 IC 的绝对值
    abs_ic = rolling_ic.abs()
    
    # 只选择 IC > min_ic 的股票
    valid_stocks = abs_ic[abs_ic > min_ic]
    
    # 根据 IC 绝对值分配权重
    weights = valid_stocks / valid_stocks.sum()
    
    return weights

方法 3:平滑 IC 权重

def ic_weight_smooth(rolling_ic, min_ic=0.02, alpha=1.0):
    """
    平滑 IC 权重分配(softmax)
    
    参数:
        rolling_ic: 滚动 IC
        min_ic: 最小 IC 阈值
        alpha: 平滑系数
    
    返回:
        weights: 股票权重
    """
    # 只选择 IC > min_ic 的股票
    valid_stocks = rolling_ic[rolling_ic > min_ic]
    
    # Softmax 归一化
    weights = np.exp(alpha * valid_stocks) / np.sum(np.exp(alpha * valid_stocks))
    
    return weights

4.4 优势与风险

优势

  • ✅ 考虑预测能力差异
  • ✅ 动态调整权重
  • ✅ 对历史表现好的股票给予更高权重

风险

  • ⚠️ 需要足够历史数据
  • ⚠️ IC 可能不稳定
  • ⚠️ 换手率可能较高
  • ⚠️ 过度拟合历史数据

4.5 实践建议

  • 使用滚动窗口计算 IC(如 20 期)
  • 设置最小 IC 阈值
  • 对 IC 进行平滑处理
  • 限制单股权重最大值

5. 均值-方差优化(MVO)

5.1 理论基础

马科维茨现代投资组合理论:在给定风险水平下最大化收益

5.2 数学模型

优化问题

max: μ^T w - λ w^T Σ w

s.t.:
    Σw_i = 1        (权重和为1)
    w_i ≥ 0         (不允许做空)
    w_i ≤ w_max     (最大单股权重)

变量说明

  • w:权重向量
  • μ:期望收益向量
  • Σ:协方差矩阵
  • λ:风险厌恶系数

5.3 有效前沿

定义:在不同风险水平下获得最大期望收益的投资组合集合

意义

  • 有效前沿上的组合都是最优的
  • 投资者根据风险偏好选择组合
  • 有效前沿是凸的

5.4 参数估计

期望收益估计

mu = returns.mean()

协方差矩阵估计

sigma = returns.cov()

正则化(防止过拟合):

sigma_reg = sigma + lambda_reg * np.eye(len(returns.columns))

5.5 CVXPY 求解

import cvxpy as cp
 
def mv_optimization(returns, risk_aversion=1.0, max_weight=0.1):
    """
    均值-方差优化
    
    参数:
        returns: 历史收益率
        risk_aversion: 风险厌恶系数
        max_weight: 最大单股权重
    
    返回:
        weights: 最优权重
    """
    n = len(returns.columns)
    
    # 定义变量
    w = cp.Variable(n)
    
    # 定义参数
    mu = returns.mean().values
    sigma = returns.cov().values
    
    # 正则化
    sigma_reg = sigma + 1e-6 * np.eye(n)
    
    # 定义目标函数
    objective = cp.Maximize(mu @ w - risk_aversion * cp.quad_form(w, sigma_reg))
    
    # 定义约束
    constraints = [
        cp.sum(w) == 1,  # 权重和为1
        w >= 0,         # 不允许做空
        w <= max_weight # 最大单股权重
    ]
    
    # 求解
    problem = cp.Problem(objective, constraints)
    problem.solve()
    
    # 获取解
    optimal_weights = pd.Series(w.value, index=returns.columns)
    
    return optimal_weights
 
# 示例
import numpy as np
import pandas as pd
 
# 生成示例数据
np.random.seed(42)
n_stocks = 10
n_days = 252
stocks = [f'stock_{i}' for i in range(n_stocks)]
dates = pd.date_range('2020-01-01', periods=n_days, freq='D')
 
returns = pd.DataFrame(np.random.randn(n_days, n_stocks) * 0.02, 
                      index=dates, columns=stocks)
 
# MV 优化
weights = mv_optimization(returns, risk_aversion=1.0, max_weight=0.2)
 
print("MV 优化权重:")
print(weights)

5.6 优势与风险

优势

  • ✅ 理论基础扎实(诺贝尔奖理论)
  • ✅ 考虑风险和相关性
  • ✅ 科学化资产配置
  • ✅ 可以量化风险

风险

  • ⚠️ 依赖参数估计(μ 和 Σ)
  • ⚠️ 估计误差影响大
  • ⚠️ 可能集中投资少数股票
  • ⚠️ 对异常值敏感

5.7 实践建议

  • 使用稳健的估计方法
  • 对协方差矩阵进行正则化
  • 添加约束条件(行业、流动性等)
  • 定期重新估计参数

6. 三种方法对比

维度Top-K 等权IC 权重MV 优化
复杂度
数据需求
理论支撑经验统计理论
计算速度
换手率
风险控制
适合新手⚠️

7. 实践建议

7.1 策略选择原则

新手建议

  1. 从 Top-K 策权开始
  2. 使用较小的 K 值(20-30)
  3. 定期调仓(周频或月频)
  4. 严格风险控制

进阶建议

  1. 尝试 IC 权重策略
  2. 学习 MV 优化方法
  3. 进行参数敏感性分析
  4. 做样本外验证

7.2 风险控制建议

  1. 分散化

    • 持有多只股票(至少 10 只)
    • 考虑行业分散
    • 避免过度集中
  2. 仓位控制

    • 限制单股权重(< 20%)
    • 限制行业权重(< 30%)
    • 设置止损机制
  3. 成本控制

    • 控制换手率(< 300%)
    • 使用低佣金券商
    • 选择高流动性股票

7.3 参数优化建议

  1. 避免过拟合

    • 使用样本外验证
    • 限制参数数量
    • 参数有经济学含义
  2. 参数稳定性

    • 在不同时间段表现稳定
    • 对数据变化不过敏
    • 定期重新评估参数

总结

交易策略的核心是:

  1. 信号生成:选择股票
  2. 仓位管理:分配权重
  3. 风险控制:限制风险
  4. 执行规则:何时调仓

三种主要方法:

  • Top-K 等权:简单可靠,适合新手
  • IC 权重:动态调整,适合有历史数据
  • MV 优化:科学配置,适合追求风险调整后收益

建议从简单的 Top-K 策略开始,逐步学习更复杂的方法。