利用OpenAI Gym和Anytrading环境进行交易
Open AI Gym Anytrading环境是一个定制的交易环境,你可以用它来交易一堆股票、外汇、加密货币、股票和证券。
前提条件
要跟上这个教程,你需要熟悉。
- 强化学习和其算法。
- 加密货币、股票、外汇、股票和证券的交易。
- 谷歌Colab或Jupyter笔记本。
我们将在本教程中使用谷歌Colab。
开始使用Gym Anytrading环境
Open AI的Gym Anytrading环境是一个定制的交易环境,你可以用它来交易一堆股票、外汇、加密货币、股票和证券。我们将利用该环境来进行以太坊加密货币数据的交易。
安装和导入依赖项
!pip install tensorflow-gpu==1.15.0 tensorflow==1.15.0 gym-anytrading gym stable-baselines
如果你运行上面的命令,它会去安装五个关键的依赖项。
tensorflow-gpu==1.15.0
给我们提供Tensorflow的GPU版本。我们选择了Tensorflow版本 ,因为 ,只适用于版本 。它不支持Tensorflow版本 及以上。1.15.0
stable-baselines
1.8.0 to 1.15.0
2.0.0
tensorflow==1.15.0
给我们提供非GPU版本的TensorFlow,以确保我们有两个基础。gym-anytrading
给我们的交易环境。stable-baselines
给我们提供不同的强化学习算法。gym
给我们OpenAI的Gym,这是Gym Anytrading建立的基础框架。
让我们继续前进,把它们导入我们的笔记本。我们首先导入我们的交易机器人将学习如何交易的环境。
import gym_anytrading
import gym
我们接下来的导入包括RL算法和从稳定基线导入的辅助工具。我们将使用的算法是A2C
。你可以尝试其他RL算法,即DQN
和PPO2
。要了解更多关于它们的信息,请参考这个链接。
from stable_baselines import A2C
from stable_baselines.common.vec_env import DummyVecEnv
接下来,我们导入我们的三个主要处理库。
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
Pandas
是用来读入我们的交易数据。Numpy
用于教程的评估阶段,进行数学运算。matplotlib
帮助我们可视化我们的交易。
从MarketWatch加载历史数据
我们将与来自Market Watch的以太坊数据一起工作。该数据包含以太坊的Open
、High
、Low
、Close
,在12/13/2021
和01/12/2022
之间的价格。
记住,运行时间回收后,上传的数据会被删除。
为了加载我们的历史数据,我们将依靠Pandas
库。
df = pd.read_csv('ETHUSD.csv')
这个命令将加载我们的数据。要查看它,我们键入以下命令。
df.head()
输出。
Date Open High Low Close
0 01/12/2022 3,231.84 3,412.64 3,208.15 3,370.80
1 01/11/2022 3,074.72 3,264.19 3,054.64 3,232.52
2 01/10/2022 3,188.77 3,199.13 2,933.19 3,073.50
3 01/09/2022 3,076.44 3,210.00 3,060.38 3,188.77
4 01/08/2022 3,216.12 3,245.65 2,999.08 3,080.64
让我们进行一些预处理,为交易设置这些数据。如果我们使用命令df.dtypes
,就可以看到数据类型。
Date object
Open object
High object
Low object
Close object
dtype: object
为了使我们的数据能够在Gym Anytrading环境下工作,我们需要将我们的Date
,从一个对象转换成一个日期类型的格式。我们将使用Pandasto_datetime
函数来进行转换。
df ['Date'] = pd.to_datetime(df ['Date'])
上面的命令应该可以实现这种转换。为了确认,你需要输入df.dtypes
。 此外,我们需要将这一列设置为索引。这是使用Gym Anytrading环境时的一个要求。要做到这一点,我们写下以下命令。
df.set_index('Date', inplace=True)
最后,我们需要将其他列从对象转换为浮点数。如果不进行这种转换,将给你一个TypeError
。
df['Open'] = df['Open'].apply(lambda x: float(x.replace(",", "")))
df['High'] = df['High'].apply(lambda x: float(x.replace(",", "")))
df['Low'] = df['Low'].apply(lambda x: float(x.replace(",", "")))
df['Close'] = df['Close'].apply(lambda x: float(x.replace(",", "")))
当你在终端上输入代码df ['Open'].unique()
,你会发现值是在一个字符串中,并且有逗号。上面的代码将这些逗号删除,用空的空格代替,并将这些值转换为浮点数类型。通过输入df.head()
,你可以确认逗号已经被替换。此外,df.dtypes
命令将帮助你确认所有列的转换,float64
。
这就是你需要做的所有预处理,将这些数据传递给Gym Anytrading环境。该环境还希望有Open
,High
,Close
, 和Close
列。
理想情况下,你使用的数据应该模仿你想交易的频率。例如,如果你想让RL代理交易每日的数据,就使用每日数据来训练代理,而不是每小时的数据。
让我们创建环境并将这些数据传入交易环境。
env = gym.make('stocks-v0', df=df, frame_bound=(5,30), window_size=5)
window_size
指定了我们的交易机器人在进行下一次交易时有多少个以前的时间段作为参考点。frame_bound
指定了我们的df
的开始和结束。frame_bound
上的第一个参数应始终等于window_size
,这样它就有五组以前的数据。对于第二个参数,你可以根据你的数据将其调整为你选择的任何值。
构建测试环境
如果我们看一下我们可以使用environment.action_space
,我们会发现我们只有两个动作可以做。我们只能Short
或Long
。在其他算法中,你可以Hold
。但是,这个算法只限于两个动作。
state = env.reset()
while True:
action = env.action_space.sample()
n_state, reward, done, info = env.step(action)
if done:
print("info", info)
break
如果你以前使用过OpenAI Gym,这第一部分的代码你一定很熟悉。它是你在构建测试环境时写的典型代码。
下面的代码使用matplotlib
,将这个环境可视化。
plt.figure(figsize=(20,10))
plt.cla()
env.render_all()
plt.show()
总结这一部分,我们在环境中采取一堆随机的步骤,并将其可视化。
现在,我们可以开始建立我们的RL代理,以尝试在这个环境中进行交易并获利。
训练RL代理使用Gym环境进行交易
我们首先将我们的环境包裹在假的矢量环境包装器中,DummyVecEnv
。
env_build = lambda: gym.make('stocks-v0', df=df, frame_bound=(5,30), window_size=5)
env = DummyVecEnv([env_build])
我们正在创建一个env_build
函数。我们把这个函数放在DummyVecEnv
里面。最后,我们把结果保存在env
变量里面,这样,当我们开始建立我们的训练模型时。我们现在将使用env
这个变量。
接下来,让我们设置我们的算法并启动我们的训练。
model_train = A2C('MlpLstmPolicy', env, verbose=1)
model_train.learn(total_timesteps=100000)
通过这两行代码,我们的模型将开始训练。
A2C
A2C
是一个首字母缩写,代表 。它是一种RL算法,结合了基于策略和基于价值的RL技术。
我们正在使用MlpLstmPolicy
,这是一个带有LSTM层的深度神经网络策略。这是一个重要的策略,因为它允许神经网络保持上下文,并在其神经元中学习以前的历史。
最后一行代码以100000
时间步数启动训练。理想情况下,你在训练时需要观察的是explained_variance
值。你希望它越高越好。我们正在寻找0
和1
之间的数值。接近1
的数字表示一个高值,而接近0
的数字表示一个低值。你也应该确保value_loss
尽可能的低。
当explained_variance
是0.966
,你可以停止模型训练。这应该给我们一个表现相当好的模型。然而,对于算法来说,找到一个完美的解决方案是永远不可能的事情。继续实验,直到你找到那个甜蜜点。
让我们测试一下,看看它的表现如何。
测试RL-agent
env = gym.make('stocks-v0', df=df, frame_bound=(25,35), window_size=5)
obs = env.reset()
while True:
obs = obs[np.newaxis, ...]
action, _states = model_train.predict(obs)
obs, rewards, done, info = env.step(action)
if done:
print("info", info)
break
上面的代码与我们上面写的代码相似。核心区别是,我们不是采取随机行动,而是用我们的模型来预测它应该采取的行动,即买入或卖出。
让我们把结果可视化。
plt.figure(figsize=(15,6))
plt.cla()
env.render_all()
plt.show()
这些是训练我们的代理从第25天到35天的操作结果。我们的模型已经预测了新的行动。我们可以注意到,它已经做了一些好的交易,也做了一些坏的交易。绿色的点代表买入,而红色的点代表卖出加密货币。
例如,在它的第六次交易中,它在价格低时买入是正确的。但是,它应该在第八次交易中卖出,但相反,它买了更多,这是一个错误。另外,在第十次交易中,它在以太坊的最低价格时卖出,造成了损失。这是一个错误的交易。
我们的利润是0.9861862828347474
,大约是8.6%。这并不多。但是,至少你得到了这个模型是如何工作的想法。
总结
这个模型并不完美。它已经做了一些多头和空头交易。一些好的和坏的交易。你可以玩玩这个代码,看看它的表现如何。通过一些调整,这个模型可以被训练成股票、外汇、股票和证券的交易。本教程中的所有代码仅用于教育目的。如果你要部署这样一个模型,请做好充分的研究。此外,这不是财务建议。它只是为了向你展示该技术的可能性。