代码的部署

本文介绍了一个结合深度Q学习的交易机器人OandaTradingBot的部署过程,通过Python代码实现自动交易决策和执行,强调了在实际应用中需要考虑的扩展性和生产环境中的问题,如数据持久化、连接监控和安全性等。
摘要由CSDN通过智能技术生成

本节会结合前面几节的主要内容,以自动化方式部署经过训练的交易机器人。这与准备在 街道上部署自动驾驶汽车的方式相当。以下代码中提供的 OandaTradingBot 类继承自 tpqoa 类,并添加了一些辅助函数和交易逻辑。 In [76]: import tpqoa In [77]: class OandaTradingBot(tpqoa.tpqoa): def __init__(self, config_file, agent, granularity, units, verbose=True): super(OandaTradingBot, self).__init__(config_file) self.agent = agent self.symbol = self.agent.learn_env.symbol self.env = agent.learn_env self.window = self.env.window if granularity is None: self.granularity = agent.learn_env.granularity else: self.granularity = granularity 图灵社区会员 cxc_3612(17665373813) 专享 尊重版权执行与部署 | 301 self.units = units self.trades = 0 self.position = 0 self.tick_data = pd.DataFrame() self.min_length = (self.agent.learn_env.window + self.agent.learn_env.lags) self.pl = list() self.verbose = verbose def _prepare_data(self): self.data['r'] = np.log(self.data / self.data.shift(1)) self.data.dropna(inplace=True) self.data['s'] = self.data[self.symbol].rolling( self.window).mean() self.data['m'] = self.data['r'].rolling(self.window).mean() self.data['v'] = self.data['r'].rolling(self.window).std() self.data.dropna(inplace=True) # self.data_ = (self.data - self.env.mu) / self.env.std ➊ self.data_ = (self.data - self.data.mean()) / self.data.std() ➊ def _resample_data(self): self.data = self.tick_data.resample(self.granularity, label='right').last().ffill().iloc[:-1] ➋ self.data = pd.DataFrame(self.data['mid']) ➋ self.data.columns = [self.symbol,] ➋ self.data.index = self.data.index.tz_localize(None) ➋ def _get_state(self): state = self.data_[self.env.features].iloc[-self.env.lags:] ➌ return np.reshape(state.values, [1, self.env.lags, self.env.n_features]) ➌ def report_trade(self, time, side, order): self.trades += 1 pl = float(order['pl']) ➍ self.pl.append(pl) ➍ cpl = sum(self.pl) ➎ print('\n' + 75 * '=') print(f'{time} | *** GOING {side} ({self.trades}) ***') print(f'{time} | PROFIT/LOSS={pl:.2f} | CUMULATIVE={cpl:.2f}') print(75 * '=') if self.verbose: pprint(order) print(75 * '=') def on_success(self, time, bid, ask): df = pd.DataFrame({'ask': ask, 'bid': bid, 'mid': (bid + ask) / 2}, index=[pd.Timestamp(time)]) self.tick_data = self.tick_data.append(df) ➋ self._resample_data() ➋ if len(self.data) > self.min_length: self.min_length += 1 self._prepare_data() state = self._get_state() ➏ prediction = np.argmax( self.agent.model.predict(state)[0, 0]) ➏ position = 1 if prediction == 1 else -1 ➏ if self.position in [0, -1] and position == 1: ➐ order = self.create_order(self.symbol, 302 | 第 12 章 units=(1 - self.position) * self.units, suppress=True, ret=True) self.report_trade(time, 'LONG', order) self.position = 1 elif self.position in [0, 1] and position == -1: ➑ order = self.create_order(self.symbol, units=-(1 + self.position) * self.units, suppress=True, ret=True) self.report_trade(time, 'SHORT', order) self.position = -1 ➊ 为了便于演示,用实时数据统计进行了标准化处理。1 ➋ 收集逐笔数据并将其重新采样到所需的粒度。 ➌ 返回金融市场的当前状态。 ➍ 收集每笔交易的损益数据。 ➎ 计算所有交易的累计损益。 ➏ 预测市场方向并得出信号(头寸)。 ➐ 检查是否满足多头头寸(买入单)的条件。 ➑ 检查是否满足空头头寸(卖出单)的条件。 这个类的应用非常简单。首先,实例化一个对象,将上一节中训练过的交易机器人 agent 作为主要输入。然后,启动待交易工具的流数据。每当新的逐笔数据到达时,都会调 用 .on_success() 方法,该方法包含处理逐笔数据和安排交易的主要逻辑。为了加快速度, 部署示例依赖于 30 秒间隔数据,就像之前的回测一样。在生产环境中,当管理实际资金 时,如果只是为了减少交易数量和交易成本,则更长的时间间隔可能是更好的选择。 In [78]: otb = OandaTradingBot('../aiif.cfg', agent, '30s', 25000, verbose=False) ➊ In [79]: otb.tick_data.info() Index: 0 entries Empty DataFrame In [80]: otb.stream_data(agent.learn_env.symbol, stop=1000) ➋ ========================================================================== 2020-08-13T12:19:32.320291893Z | *** GOING SHORT (1) *** 2020-08-13T12:19:32.320291893Z | PROFIT/LOSS=0.00 | CUMULATIVE=0.00 ========================================================================== ========================================================================== 2020-08-13T12:20:00.083985447Z | *** GOING LONG (2) *** 2020-08-13T12:20:00.083985447Z | PROFIT/LOSS=-6.80 | CUMULATIVE=-6.80 ========================================================================== 注 1: 鉴于所使用的数据,这个小技巧可以更快地在这种特定环境下进行交易。对于实际部署,将使用来自 学习环境数据的统计信息进行标准化。执行与部署 | 303 ========================================================================== 2020-08-13T12:25:00.099901587Z | *** GOING SHORT (3) *** 2020-08-13T12:25:00.099901587Z | PROFIT/LOSS=-7.86 | CUMULATIVE=-14.66 ========================================================================== In [81]: print('\n' + 75 * '=') print('*** CLOSING OUT ***') order = otb.create_order(otb.symbol, units=-otb.position * otb.units, suppress=True, ret=True) ➌ otb.report_trade(otb.time, 'NEUTRAL', order) ➌ if otb.verbose: pprint(order) print(75 * '=') ========================================================================== *** CLOSING OUT *** ========================================================================== 2020-08-13T12:25:16.870357562Z | *** GOING NEUTRAL (4) *** 2020-08-13T12:25:16.870357562Z | PROFIT/LOSS=-3.19 | CUMULATIVE=-17.84 ========================================================================== ========================================================================== ➊ 实例化 OandaTradingBot 对象。 ➋ 启动实时数据流和交易。 ➌ 在检索到一定数量交易数据后平仓最终头寸。 在部署过程中,损益数据被收集在 pl 属性中,pl 属性是一个 list 对象。一旦交易停止, 就可以分析损益数据了。 In [82]: pl = np.array(otb.pl) ➊ In [83]: pl ➊ Out[83]: array([ 0. , -6.7959, -7.8594, -3.1862]) In [84]: pl.cumsum() ➋ Out[84]: array([ 0. , -6.7959, -14.6553, -17.8415]) ➊ 所有交易的损益数据。 ➋ 累计损益数据。 这个简单的部署示例表明,我们可以用不到 100 行的 Python 代码以算法和自动化的方式 与深度 Q 学习交易机器人进行交易。主要的先决条件是训练有素的交易机器人(比如, tradingbot 类的实例)。这里有意忽略了许多重要的方面。例如,在生产环境中,我们可 能既想持久化数据,又想持久化 order 对象。确保套接字连接仍然活跃的措施也很重要 (比如,通过监视心跳)。总的来说,安全性、可靠性、日志记录和监视并没有得到真正的 解决。Hilpisch(2020)提供了这方面的更多细节。304 | 第 12 章 12.7.3 节的 Python 脚本展示了 OandaTradingBot 类的独立可执行版本。与交互式环境(比 如 Jupyter Notebook 或 Jupyter Lab)相比,这是朝着更稳健的部署选项迈出的重要一步。 该脚本还包括为执行添加止损单、跟踪止损单或止盈单的功能。该脚本期望当前工作目录 中的 agent 对象是 pickle 版本。下面的 Python 代码会对对象进行 pickle 处理,以供脚本 以后使用。 In [85]: import pickle In [86]: pickle.dump(agent, open('trading.bot', 'wb'))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值