AI应用 量化交易强化学习DRLPython深度学习
云
云铭
进化之路 · 扫码阅读
微信 · 浏览器扫码
在手机上获得更好的阅读体验
强化学习在量化交易中的应用实践
如果说监督学习是”依葫芦画瓢”,强化学习就是”在摔打中成长”。让 AI 在模拟市场环境中反复试错,自主学习交易策略。
为什么强化学习适合交易
交易的RL本质
交易天然是强化学习问题:
Agent(交易者)
↓ action(买入/卖出/持有)
Environment(市场)
↓ reward(盈亏/夏普比率)
↓ state(价格/指标/持仓)
Agent ← 学习如何最大化累计收益
三大范式对比
| 范式 | 监督学习 | 无监督学习 | 强化学习 |
|---|---|---|---|
| 学习信号 | 标签(涨/跌) | 数据结构 | 奖励(收益) |
| 反馈时机 | 即时 | - | 延迟 |
| 探索利用 | 无 | 无 | 核心挑战 |
| 序列决策 | 不考虑 | 不考虑 | 天生支持 |
| 与交易匹配度 | ⭐⭐ | ⭐ | ⭐⭐⭐ |
强化学习基础回顾
核心要素
# RL的核心抽象
class TradingEnv:
"""交易环境 - RL的交互接口"""
def reset(self):
"""重置环境,返回初始状态"""
return initial_state
def step(self, action):
"""
执行动作,返回:
- next_state: 下一状态
- reward: 即时奖励
- done: 是否结束
- info: 额外信息
"""
return next_state, reward, done, info
@property
def action_space(self):
"""动作空间: 买入/卖出/持有 或 仓位比例[-1,1]"""
pass
@property
def observation_space(self):
"""状态空间: 价格、指标、持仓等"""
pass
常用算法速览
值函数方法:
Q-Learning → DQN → Double DQN → Dueling DQN
策略梯度方法:
REINFORCE → Actor-Critic → A2C/A3C → PPO
适合交易的:
PPO(稳定、样本效率高)
SAC(处理连续动作空间)
TD3(减少过估计)
实战:构建交易RL环境
自定义 Gym 环境
import gymnasium as gym
from gymnasium import spaces
import numpy as np
class StockTradingEnv(gym.Env):
"""单标的股票交易环境"""
def __init__(self, df, initial_balance=100000,
transaction_cost=0.001, max_position=1.0):
super().__init__()
self.df = df.reset_index(drop=True)
self.initial_balance = initial_balance
self.transaction_cost = transaction_cost
self.max_position = max_position
# 动作空间:仓位变化 [-1, 0, 1](全卖/不变/全买)
self.action_space = spaces.Box(
low=-1.0, high=1.0, shape=(1,), dtype=np.float32
)
# 状态空间:[价格比例, 收益率, RSI, MACD, 波动率, 仓位]
self.observation_space = spaces.Box(
low=-np.inf, high=np.inf, shape=(6,), dtype=np.float32
)
self.reset()
def reset(self, seed=None, options=None):
super().reset(seed=seed)
self.current_step = 0
self.balance = self.initial_balance
self.position = 0.0 # 当前持仓市值
self.portfolio_value = self.balance
return self._get_observation(), {}
def step(self, action):
# 解析动作
target_position = float(np.clip(action[0], -1.0, 1.0))
# 计算交易
current_price = self._get_price()
position_change = target_position - self.position
# 执行交易(含手续费)
cost = abs(position_change) * self.transaction_cost
self.position = target_position
self.balance -= position_change * current_price + cost
# 更新组合价值
new_portfolio_value = self.balance + self.position * current_price
reward = (new_portfolio_value - self.portfolio_value) / self.portfolio_value
self.portfolio_value = new_portfolio_value
# 移动到下一步
self.current_step += 1
done = self.current_step >= len(self.df) - 1
return self._get_observation(), reward, done, False, {
'portfolio_value': self.portfolio_value,
'position': self.position,
'reward': reward
}
def _get_observation(self):
row = self.df.iloc[self.current_step]
return np.array([
row['Close'] / row['sma_50'] - 1, # 价格偏离均线
row['returns_5d'], # 5日收益率
(row['rsi'] - 50) / 50, # RSI标准化
row['macd'] / row['Close'] * 100, # MACD比例
row['volatility_20d'], # 20日波动率
self.position / self.portfolio_value if self.portfolio_value > 0 else 0
], dtype=np.float32)
def _get_price(self):
return self.df.iloc[self.current_step]['Close']
奖励函数设计
def calculate_reward(portfolio_value, prev_value, position, returns):
"""复合奖励函数"""
# 基础收益
profit_reward = (portfolio_value - prev_value) / prev_value
# 风险惩罚(夏普比率风格)
risk_penalty = 0.1 * abs(position) * abs(returns)
# 交易频率惩罚(减少过度交易)
trade_penalty = 0.001 * abs(position_change)
# 回撤惩罚
drawdown_penalty = 0.1 * max(0, (peak_value - portfolio_value) / peak_value)
return profit_reward - risk_penalty - trade_penalty - drawdown_penalty
实战:PPO训练
使用 Stable-Baselines3
from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv
from stable_baselines3.common.callbacks import EvalCallback
import matplotlib.pyplot as plt
# 创建环境
def make_env(df_train, df_val):
def _init():
return StockTradingEnv(df_train)
return _init
env = DummyVecEnv([make_env(train_df, val_df)])
eval_env = DummyVecEnv([lambda: StockTradingEnv(val_df)])
# PPO模型配置
model = PPO(
'MlpPolicy',
env,
learning_rate=3e-4,
n_steps=2048,
batch_size=64,
n_epochs=10,
gamma=0.99, # 折扣因子
gae_lambda=0.95, # GAE参数
clip_range=0.2, # 裁剪范围
ent_coef=0.01, # 熵系数(鼓励探索)
verbose=1,
tensorboard_log="./ppo_trading_logs/"
)
# 评估回调
eval_callback = EvalCallback(
eval_env,
best_model_save_path='./best_model/',
log_path='./eval_logs/',
eval_freq=10000,
deterministic=True,
render=False
)
# 训练
model.learn(
total_timesteps=500_000,
callback=eval_callback,
progress_bar=True
)
# 保存模型
model.save("ppo_trading_model")
模型评估
def evaluate_model(model, env, n_episodes=100):
"""评估训练好的RL策略"""
returns = []
sharpes = []
max_drawdowns = []
for _ in range(n_episodes):
obs, _ = env.reset()
done = False
episode_returns = []
while not done:
action, _ = model.predict(obs, deterministic=True)
obs, reward, done, _, info = env.step(action)
episode_returns.append(reward)
daily_returns = np.array(episode_returns)
returns.append(np.sum(daily_returns))
sharpes.append(
np.mean(daily_returns) / np.std(daily_returns) * np.sqrt(252)
)
# 计算最大回撤
cumulative = np.cumprod(1 + daily_returns)
peak = np.maximum.accumulate(cumulative)
max_drawdowns.append(np.max((peak - cumulative) / peak))
print(f"=== 强化学习策略评估 ({n_episodes}回合) ===")
print(f"平均总收益: {np.mean(returns):.2%}")
print(f"平均夏普比率: {np.mean(sharpes):.2f}")
print(f"平均最大回撤: {np.mean(max_drawdowns):.2%}")
print(f"盈利比率: {np.mean([1 for r in returns if r > 0]):.1%}")
return returns, sharpes, max_drawdowns
RL量化的挑战与对策
核心挑战
| 挑战 | 说明 | 对策 |
|---|---|---|
| 过拟合 | 在历史数据上”背题” | 多资产交叉验证,合理正则化 |
| 非平稳性 | 市场特征持续变化 | 在线学习、定期重新训练 |
| 稀疏奖励 | 信号太少难以学习 | 设计密集的辅助奖励 |
| 样本效率 | 需要大量交互数据 | 优先使用PPO等高效算法 |
| 探索风险 | 探索可能导致大幅亏损 | 安全的探索策略、止损约束 |
实用建议
# 1. 添加动作平滑惩罚(减少剧烈调仓)
action_smoothness_penalty = 0.01 * (action - prev_action)**2
# 2. 使用奖励缩放(稳定训练)
reward_scaled = np.clip(reward / reward_std, -10, 10)
# 3. 多进程并行采样(加速训练)
from stable_baselines3.common.vec_env import SubprocVecEnv
env = SubprocVecEnv([make_env(df) for _ in range(8)])
# 4. 课程学习(从简单到复杂)
# 阶段1:只用少数技术指标
# 阶段2:逐步增加特征数量
# 阶段3:加入交易成本等现实约束
与监督学习结合
监督学习(方向预测)+ 强化学习(仓位管理)
ML模型预测方向概率 → RL决策仓位大小
↓ ↓
"会涨70%" "买60%仓位"
这种混合方法在实践中往往比纯RL更稳定。
RL量化交易的魅力在于:它不假设市场遵循什么规律,而是在尝试中学习。但也正因如此,它要求的验证比传统策略更加严格。永远在模拟环境中跑够足够长时间,再考虑真金白银。