利用强化学习进行股票操作实战(三)

2023-11-04

与上一篇文章相同之处

对于交易策略,与上一篇文章相同,当发出买入指令时,一次性全部买入;当发出卖出指令时,一次性全部卖出。还没有添加加减仓操作。

模型仍然用的是DQN模型。

新增内容

  1. 在之前的基础上加入了交易手续费、印花税等。

  2. 在强化学习这个领域中,reward函数是一个需要精心设计的函数。目前暂时没有好的reward设计思路,但还是修改了之前的reward函数。(其实之前的reward的设计也是错的)

首先将第二天的股票价格的涨跌幅当做reward。

reward =(self.trend[self.t + 1] - self.trend[self.t]) / self.trend[self.t]

在股市的涨跌中,很多涨跌其实是无意义的涨跌(小幅度的上涨或小幅度的下跌回调),如果把这些因素考虑进去会造成模型难以提取到一些有效信息。因此,当涨跌幅较小时,我设置了reward进行一定程度的缩小。当涨跌程度较大时,我认为这个可能也会影响模型的判断,我同样设置了reward以一定程度缩小,核心代码如下:


       if np.abs(reward)<=0.015:
           self.reward = reward * 0.2
       elif np.abs(reward)<=0.03:
           self.reward = reward * 0.7
       elif np.abs(reward)>=0.05:
           if reward < 0 :
                self.reward = (reward+0.05) *0.1 - 0.05
           else:
                self.reward = (reward-0.05) *0.1 + 0.05

对于股票的买入卖出或不操作等策略,都会影响reward。当股票卖出,r如果未来上涨了会给一个负向的reward,迫使它下次要买入;类似如果卖出,第二天下跌了就给一个正向的reward。如果股票不进行操作同样会给一个reward,但是这个reward比较小,因为我这边认为模型难以判断未来情况。核心代码如下:


     if self.hold_num > 0 or action == 2:                               
         self.reward = reward   
         if action == 2:
              self.reward = -self.reward
     else:
         self.reward = -self.reward * 0.1
  1. 在制定交易策略时,经常需要将多个交易策略结合在一起,这样才能让交易策略稳定,风险降低。在进行回测时,我加入了均线策略。如果当日收盘价小于21日均线时,说明该股暂时有一定风险需要进行避险操作。(均线策略在模型训练时不使用)

定义了trick函数获取当日收盘价是否小于21日均线,核心代码如下:


   def trick(self):
       if self.df['close'][self.t] >= self.df['ma21'][self.t]:
           return True
       else:
           return False

如果模型发出买入指令并且收盘价大于21日均线,买入。如果模型发出不操作指令,但收盘价小于21日均线,卖出。核心代码如下:


       if action == 1 and self.hold_money >= (self.trend[self.t]*100 + \
           max(self.buy_min, self.trend[self.t]*100*self.buy_rate)) and self.t <(len(self.trend) - self.half_window):
           buy_ = True
           if my_trick and not self.trick():
                # 如果使用自己的触发器并不能出发买入条件,就不买
                buy_ = False
           if buy_ :
                self.buy_stock()
                if show_log:
                    print('day:%d, buyprice:%f, buy num:%d, hold num:%d, hold money:%.3f'% \
                          (self.t,self.trend[self.t], self.buy_num, self.hold_num, self.hold_money))
       
       elif action == 2 and self.hold_num > 0:
            # 卖出股票        
           self.sell_stock(self.hold_num)
           if show_log:
                print(
                    'day:%d, sell price:%f,total balance %f,'
                    % (self.t,self.trend[self.t], self.hold_money)
               )
       else:
           if my_trick and self.hold_num>0 and not self.trick():
                self.sell_stock(self.hold_num)
                if show_log:
                    print(
                        'day:%d, sell price:%f,total balance %f,'
                        % (self.t,self.trend[self.t], self.hold_money)
                    )

测试结果
用000065股票的前1500天数据训练,用后面296天的数据进行测试。
结果如下:
不加均线策略的回测结果:
交易情况
在这里插入图片描述
收益情况
在这里插入图片描述
从上图我们可以发现,虽然模型跑过了原股票的涨跌,但模型的回撤还是挺大的。

加均线策略的回测结果
交易情况
在这里插入图片描述
收益情况
在这里插入图片描述
从收益情况来看,虽然账户在前期收益不太好,但是能够抓住一波较大的上涨行情,并且回测比较小。可见加入了均线策略可以较好的控制风险,并且有一个不错的收益。

参数探讨

训练轮数(代码中的max_round这个参数),在进行模型训练时,因为没有加验证集,只能主观的设置训练轮数。(不加验证集的原因在于首先验证集的涨跌情况不一定是未来的涨跌情况,很难通过验证集来表现来调整模型参数,有点玄学)。训练轮数如果太大,模型会有较大的可能把历史涨跌完全记住而比较一般性的规则就会被抛弃。如果训练轮数太小,又学不到有效信息,比较纠结的一个参数。(可能数据多了就没这个顾虑)

Batch_size,在深度学习中batch_size是一个比较重要的参考,太小loss震荡厉害,模型难以学到有效信息,太大容易overfit,在以上实验中我设置了一个比较大的batch_size。

memory_size(DQN中用来存储历史操作的参数),当这个参数较大时会存比较多的历史参数,较小时存的历史参数也会少,在以上实验中,我设置了4000.

Learning_rate,学习率也是一个比较重要的参数,在学习率的设置上还得具体结合loss设计。

以上4个参数是我在调节时候比较纠结的几个参数,这些参数比较重要的(当然其他参数也重要,但是设置一个常规的合理值就行)。强化学习的参数调节目前我也不是特别会,不能给出太多经验。大家跑代码的时候可以调整一下几个参数,然后多多思考为什么会出现这些情况,这样就能对参数有更深的理解了。

未来改进

1、在reward设计上还需要多加考虑,目前,模型还存在这操作过于频繁的缺点,很容易被短期的涨跌影响。
2、没有加减仓操作,目前还是梭哈操作。这个会在未来添加进去。
3、数据太少了,特征也不够,神经网络也需要精心设计一下。(这点可能需要等到回学校再更新,自己的电脑跑不了太复杂的网络,电脑内存也不够)

结语

目前更新有点慢,因为目前主要还是在理论学习阶段,在看别人的文献寻找一些灵感。最近看到好多人说量化在股市上不太行,但我不太信,有些人做出来但是不跟别人说,而大部分人都做不出来,并且做的人比较少。由于受到疫情的影响没办法进行实盘操作(电脑跑不起来),大概在4月份左右就可以进行实盘操作了,对于证策略的实盘收益,敬请期待。

对量化、数据挖掘、深度学习感兴趣的可以关注公众号,本人不定期分享有关这些方面的研究。
在这里插入图片描述

个人知乎:
https://www.zhihu.com/people/e-zhe-shi-wo/activities

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用强化学习进行股票操作实战(三) 的相关文章

  • SQL实现日期自动填充

    SQL实现日期自动填充 在使用SQL进行数据处理时 经常会遇到需要补齐日期的需求 今天聊一聊几个主流数据库的实现方式 下面以生成2021 09 01到2021 09 30之间所有日期为例进行说明 Oracle connect by的递归查询

随机推荐

  • 十分钟搞定pandas

    本文是对pandas官方网站上 10 Minutes to pandas 的一个简单的翻译 原文在这里 这篇文章是对pandas的一个简单的介绍 详细的介绍请参考 Cookbook 习惯上 我们会按下面格式引入所需要的包 一 创建对象 可以
  • YOLOV5轻量化改进-MobileNetV3替换骨干网络

    1 ymal文件修改 将models文件下yolov5s py复制重命名如下图所示 2 接着将如下代码替换 diamagnetic如下所示 YOLOv5 by Ultralytics GPL 3 0 license Parameters n
  • C语言笔记——基本格式、数组

    基本格式 include
  • oracle exp 00006,Oracle 12.1新特性----使用RMAN从备份中实现recover table

    Oracle 12 1新特性 使用RMAN从备份中实现recover table 发布时间 2020 06 26 19 41 44 来源 51CTO 阅读 4750 作者 hbxztc 在Oracle12c版本之前 使用RMAN能恢复的级别
  • 自学STM32---GPIO

    1 STM32有5组GPIO引脚 分别是GPIOA GPIOB GPIOC GPIOD GPIOE 每组GPIO有16个引脚 2 每个引脚都有4个位来配置其端口 可以配置出不同的输入 输出模式 表1配置IO口输出方式 配置模式 CNF1 C
  • linux连接交换机命令,linux服务器查看网卡连接的交换机IP和PORT

    cdpr命令 安装 yum y install cdpr 安装epel库 21 53 07 root localhost cdpr h cdpr Cisco Discovery Protocol Reporter Version 2 4 C
  • 常见分类模型:决策树、随机森林、GBDT、XGB

    涉及到的指标 信息熵 其中是一件事情发生的概率 发生的概率越大信息量越小 对于2个独立事件 发生概率是 二者的信息量是 因为 具有可加性的性质 因此一般用来衡量某件事的信息量 负号是因为信息量与概率成反比 信息量度量的是一个具体事件发生了所
  • mysql断线重连_Yii2实现Mysql断线重连

    缘由 大家都知道我们做一个客服系统 是基于websocket长连接服务的 在这些长连接服务进程中 会对数据库有些操作 建议尽量在这些长连接服务中 少查询数据 能用缓存都用缓存 我们都知道数据库服务保持连接是有时间限制的 过了时间在操作数据库
  • cxf的web service服务,包含client端、service端

    1 下载需要的客户端 服务端Jar 客户端jar包链接 https github com zhangliqingyun jarlist tree master webserviceclient 服务端jar包链接 https github
  • MySQL 存储过程查询远程数据库的方法

    这几天有个任务 需要在存储过程中读取远程数据库一个表的数据存到本地表 然后进行计算 在网上查找了资料 Oracle和SQL Server查询远程数据库是比较方便的 MySQL麻烦一些 需要在本地建立一个需要查询的远程的表结构完全一样的表 并
  • Java单链表中的元素互换位置_java实现单链表及倒置单链表中的元素

    单链表的结构比较简单 图示如下 单链表有很多个节点构成 每个节点由指针域和数值域构成 指针指向下一个节点的数值域 最后一个节点的指针指向的是NULL java实现单链表的一些基本的操作 package test import javax x
  • RabbitMQ系列(二)VirtualHost作用及角色权限管理实战

    VirtualHost 作用及用法 Virtual Hosts的使用场景 多租户的使用场景 比如主机资源紧缺情况下开发和测试共用一个RabbitMQ 可以使用Virtual Hosts将开发和测试隔离开 1 管理界面 2 VirtualHo
  • rust学习网站

    https photino gitbooks io rust notes content programming paradigms html rutst学习网站 https kaisery gitbooks io rust book ch
  • 线性表定义--线性表的顺序存储结构+链式存储结构+循环链表+双向链表

    线性表 一 线性表定义 1 线性表的定义 通过一个例子来体验什么是线性表的定义 小朋友出游排队 谁在谁的前面 谁在谁的后面 保证不会有人丢失 定义 线性表 List 零个或多个数据元素的有限序列 注意 1 线性表是一个序列 也就是说 线性表
  • 【自然语言处理】关系抽取 —— SimpleRE 讲解

    SimpleRE 论文信息 标题 An Embarrassingly Simple Model for Dialogue Relation Extraction 作者 Fuzhao Xue 期刊 ICASSP 2022 发布时间与更新时间
  • 【Ubuntu】安装免费版Typora

    下载deb包 wget https file babudiu com f yXCL Typora Linux 0 11 18 amd64 deb 安装 sudo dpkg i Typora Linux 0 11 18 amd64 deb 参
  • 【蓝桥杯题解】特殊日期(判断合法日期模板)

    对于一个日期 我们可以计算出年份的各个数位上的数字之和 也可以分别计算月和日的各位数字之和 请问从 19001900 年 11 月 11 日至 99999999 年 1212 月 3131 日 总共有多少天 年份的数位数字之和等于月的数位数
  • centos 卸载程序

    1 查询软件列表 rpm qa grep 软件名 2 卸载软件 sudo yum remove 软件名
  • SQLite安装配置详细教程2023版

    前言 SQLite 是一款轻型的数据库 是遵守ACID的关系型数据库管理系统 它的设计目标是嵌入式的 而且已经在很多嵌入式产品中使用了它 它占用资源非常的低 它能够支持Windows Linux Unix等等主流的操作系统 同时能够跟很多程
  • 利用强化学习进行股票操作实战(三)

    与上一篇文章相同之处 对于交易策略 与上一篇文章相同 当发出买入指令时 一次性全部买入 当发出卖出指令时 一次性全部卖出 还没有添加加减仓操作 模型仍然用的是DQN模型 新增内容 在之前的基础上加入了交易手续费 印花税等 在强化学习这个领域