用深度强化学习玩atari游戏_如何用深度强化学习自动炒股

ddc2ac06318382878bddf34e15a2f030.png

初衷

最近一段时间,受到新冠疫情的影响,股市接连下跌,作为一棵小白菜兼小韭菜,竟然产生了抄底的大胆想法,拿出仅存的一点私房钱梭哈了一把。

第二天,暴跌,俺加仓

第三天,又跌,俺加仓

第三天,又跌,俺又加仓...

d293287d37f4f4302eedcb1a3d2904ae.png

一番错误操作后,结果惨不忍睹,第一次买股票就被股市一段暴打,受到了媳妇无情的嘲讽。痛定思痛,俺决定换一个思路:如何用深度强化学习来自动模拟炒股? 实验验证一下能否获得收益。

监督学习与强化学习的区别

监督学习(如 LSTM)可以根据各种历史数据来预测未来的股票的价格,判断股票是涨还是跌,帮助人做决策。

333091a07dab559321df968423f491b3.png
监督学习

而强化学习是机器学习的另一个分支,在决策的时候采取合适的行动 (Action) 使最后的奖励最大化。与监督学习预测未来的数值不同,强化学习根据输入的状态(如当日开盘价、收盘价等),输出系列动作(例如:买进、持有、卖出),使得最后的收益最大化,实现自动交易。

0a94f723168181f4a99f103f356916f6.png
强化学习

OpenAI Gym 股票交易环境

观测 Observation

策略网络观测的就是一只股票的各项参数,比如开盘价、收盘价、成交数量等。部分数值会是一个很大的数值,比如成交金额或者成交量,有可能百万、千万乃至更大,为了训练时网络收敛,观测的状态数据输入时,必须要进行归一化,变换到 [-1, 1] 的区间内。

8362e535f422b161656a2d3fddeecc12.png

动作 Action

假设交易共有买入卖出保持 3 种操作,定义动作(action)为长度为 2 的数组

  • action[0] 为操作类型;
  • action[1] 表示买入或卖出百分比;

f95c08fb389a7e70ceac06d693474d3d.png

注意,当动作类型 action[0] = 3 时,表示不买也不抛售股票,此时 action[1] 的值无实际意义,网络在训练过程中,Agent 会慢慢学习到这一信息。

奖励 Reward

奖励函数的设计,对强化学习的目标至关重要。在股票交易的环境下,最应该关心的就是当前的盈利情况,故用当前的利润作为奖励函数。即当前本金 + 股票价值 - 初始本金 = 利润

# profits
reward = self.net_worth - INITIAL_ACCOUNT_BALANCE
reward = 1 if reward > 0 else reward = -100

为了使网络更快学习到盈利的策略,当利润为负值时,给予网络一个较大的惩罚 (-100)。

策略梯度

因为动作输出的数值是连续,因此使用基于策略梯度的优化算法,其中比较知名的是 PPO 算法,OpenAI 和许多文献已把 PPO 作为强化学习研究中首选的算法。PPO 优化算法 Python 实现参考 stable-baselines。

️‍♀️ 模拟实验

环境安装

# 虚拟环境
virtualenv -p python3.6 venv
source ./venv/bin/activate
# 安装库依赖
pip install -r requirements.txt

股票数据获取

股票证券数据集来自于 baostock,一个免费、开源的证券数据平台,提供 Python API。

>> pip install baostock -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn

数据获取代码参考 get_stock_data.py

>> python get_stock_data.py

将过去 20 多年的股票数据划分为训练集,和末尾 1 个月数据作为测试集,来验证强化学习策略的有效性。划分如下

88f8f8289204d4aa5fa1943f397ebd6f.png

验证结果

单只股票

  • 初始本金 10000
  • 股票代码:sh.600036(招商银行)
  • 训练集: stockdata/train/sh.600036.招商银行.csv
  • 测试集: stockdata/test/sh.600036.招商银行.csv
  • 模拟操作 20 天,最终盈利约 400

08e77892c45f161b56b8b5cff2bc1b88.png

多只股票

选取 1002 只股票,进行训练,共计

  • 盈利: 44.5%
  • 不亏不赚: 46.5%
  • 亏损:9.0%

5cc86b671e8f1a487d0d92fbacd7d59a.png
盈利百分比

f728eb7a2fbfe02ac404a545b9dcd253.png
盈利分布

最后

  • 股票 Gym 环境主要参考 Stock-Trading-Environment,对观测状态、奖励函数和训练集做了修改。
  • 俺完全是股票没入门的新手,难免存在错误,欢迎指正!
  • 数据和方法皆来源于网络,无法保证有效性!
  • 一只股票价格受到多种复杂的因素影响,仅做参考 ~

参考资料

  • Y. Deng, F. Bao, Y. Kong, Z. Ren and Q. Dai, "Deep Direct Reinforcement Learning for Financial Signal Representation and Trading," in IEEE Transactions on Neural Networks and Learning Systems, vol. 28, no. 3, pp. 653-664, March 2017.
  • Yuqin Dai, Chris Wang, Iris Wang, Yilun Xu, "Reinforcement Learning for FX trading"
  • Chien Yi Huang. Financial trading as a game: A deep reinforcement learning approach. arXiv preprint arXiv:1807.02787, 2018.
  • Create custom gym environments from scratch — A stock market example
  • notadamking/Stock-Trading-Environment
  • Welcome to Stable Baselines docs! - RL Baselines Made Easy

项目源码

https://github.com/wangshub/RL-Stock​github.com

Just For Fun!

PyTorch是一个开源的Python机器学习库,它提供了强大的工具来进行深度学习和强化学习。在这篇文章中,我们将使用PyTorch来构建一个深度强化学习模型,让AIAtari游戏。 Atari游戏是一系列经典的电子游戏,如Pong、Space Invaders和Breakout。这些游戏简单易懂,但是对于人类家来说仍然有挑战性。我们将使用Atari游戏作为我们的强化学习环境,以训练我们的AI代理。 我们将使用Deep Q-Networks(DQN)算法来训练我们的AI代理。DQN是一种基于深度学习的强化学习算法,它将神经网络与Q学习相结合,使得AI代理可以学习如何最大化其预期回报。 首先,我们需要安装PyTorch和OpenAI Gym。OpenAI Gym是一个用于开发和比较强化学习算法的工具包。您可以在这里找到有关安装方法的说明:https://pytorch.org/get-started/locally/ 和 https://gym.openai.com/docs/#installation。 在安装完成后,我们可以开始编写我们的代码。 首先,我们需要导入必要的库: ```python import random import math import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F import numpy as np import gym ``` 接下来,我们定义我们的Agent类。Agent类负责与环境交互并学习如何游戏。 ```python class Agent: def __init__(self, env, gamma, epsilon, lr): self.env = env self.gamma = gamma self.epsilon = epsilon self.lr = lr self.memory = [] self.model = Net(env.observation_space.shape[0], env.action_space.n) self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr) def act(self, state): if random.random() < self.epsilon: return self.env.action_space.sample() else: state = torch.FloatTensor(state).unsqueeze(0) q_values = self.model(state) return q_values.max(1)[1].item() def remember(self, state, action, next_state, reward): self.memory.append((state, action, next_state, reward)) def learn(self, batch_size): if len(self.memory) < batch_size: return transitions = random.sample(self.memory, batch_size) batch = Transition(*zip(*transitions)) state_batch = torch.FloatTensor(batch.state) action_batch = torch.LongTensor(batch.action) reward_batch = torch.FloatTensor(batch.reward) next_state_batch = torch.FloatTensor(batch.next_state) q_values = self.model(state_batch).gather(1, action_batch.unsqueeze(1)) next_q_values = self.model(next_state_batch).max(1)[0].detach() expected_q_values = (next_q_values * self.gamma) + reward_batch loss = F.smooth_l1_loss(q_values, expected_q_values.unsqueeze(1)) self.optimizer.zero_grad() loss.backward() self.optimizer.step() ``` 我们的Agent类具有几个方法: 1. `__init__`方法初始化代理。我们传递的参数包括环境,折扣因子(gamma),ε贪心策略中的ε值和学习率(lr)。我们还创建了一个神经网络模型和Adam优化器。 2. `act`方法根据当前状态选择一个动作。我们使用ε贪心策略,在一定概率下随机选择动作,否则选择当前状态下具有最高Q值的动作。 3. `remember`方法将经验元组(state,action,next_state,reward)添加到内存中。 4. `learn`方法从内存中随机选择一批经验元组,然后使用这些经验元组进行训练。我们计算当前状态下的Q值和下一个状态下的最大Q值,然后使用这些值计算预期Q值。我们使用平滑L1损失函数计算损失,并使用Adam优化器更新我们的模型。 接下来,我们定义我们的神经网络模型。 ```python class Net(nn.Module): def __init__(self, input_size, output_size): super(Net, self).__init__() self.fc1 = nn.Linear(input_size, 128) self.fc2 = nn.Linear(128, 128) self.fc3 = nn.Linear(128, output_size) def forward(self, x): x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x ``` 我们的模型是一个简单的前馈神经网络,具有三个全连接层。我们使用ReLU激活函数,并且输出层的大小等于动作空间的大小。 最后,我们定义我们的主函数,用于实际运行我们的代理。 ```python if __name__ == '__main__': env = gym.make('Breakout-v0') agent = Agent(env, gamma=0.99, epsilon=1.0, lr=1e-4) batch_size = 32 num_episodes = 1000 for i_episode in range(num_episodes): state = env.reset() total_reward = 0 done = False while not done: action = agent.act(state) next_state, reward, done, _ = env.step(action) agent.remember(state, action, next_state, reward) agent.learn(batch_size) total_reward += reward state = next_state agent.epsilon = max(0.01, agent.epsilon * 0.995) print("Episode: {}, total reward: {}, epsilon: {}".format(i_episode, total_reward, agent.epsilon)) ``` 我们使用OpenAI Gym中的Breakout游戏来测试我们的代理。在每个训练周期中,我们重置环境并运行一个周期,直到游戏结束。我们将每个状态、动作、下一个状态和奖励作为经验元组传递给我们的Agent,并使用这些经验元组进行训练。我们使用逐步减小的ε值来平衡探索和利用。我们打印出每个训练周期的总奖励以及当前的ε值。 现在我们已经编写了我们的代码,我们可以开始训练我们的代理。运行主函数,我们将看到我们的代理在游戏中逐渐变得更加熟练。我们可以尝试调整参数来进一步优化我们的代理的性能。 总结: 在本文中,我们使用PyTorch和OpenAI Gym构建了一个深度强化学习代理,让它Atari游戏。我们使用Deep Q-Networks算法和ε贪心策略来训练我们的代理,并逐步减小ε值来平衡探索和利用。我们的代理在游戏中逐渐变得更加熟练,展示了PyTorch在深度强化学习中的强大功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值