深度强化学习+金融投资的应用入门

news2025/8/12 0:08:28

原创文章第114篇,专注“个人成长与财富自由、世界运作的逻辑, AI量化投资”。

 

今天的核心工作是把强化学习环境整合进我们的AI量化平台中。

网上很多代码都把数据获取和预处理,都整合到强化学习的环境里,对于总体量化平台而言,这不利于代码的复用。我们之前已经实现好了dataloader。所以我们单独实现强化学习的gym即可。

01 金融强化学习的环境

一个强化学习的环境要定义四个东西:状态空间,动作空间,reward函数以及状态obseravtion。

状态空间与动作空间。

状态空间就是智能体可以观察到的环境的维度,对于金融强化学习环境而言,就是因子的维度(特征的维度)。

# 状态空间
class observation_space:
    def __init__(self, n):
        self.shape = (n,)


# 动作空间
class action_space:
    def __init__(self, n):
        self.n = n

    def seed(self, seed):
        pass

    def sample(self):
        return random.randint(0, self.n - 1)

动作空间是智能体针对观察到的状态,可以采用的动作的维度,比如“买入”和“平仓”就是两个动作。

环境初始化:

class FinanceEnv:
    def __init__(self, symbols, features, df_features):
        self.symbols = symbols
        self.features = features
        self.df_features = df_features

        self.observation_space = observation_space(4)
        self.rows = self.observation_space.shape[0]  # 一次取多少行
        self.action_space = action_space(2)  # 动作维度
        self.min_accuracy = 0.475  # 最低准确率

Reset是对环境进行重置:

 
def _get_state(self):
    state = self.df_features[self.features].iloc[
            self.index - self.rows:self.index]
    return state.values

def reset(self):
    self.treward = 0
    self.accuracy = 0
    self.index = self.rows

    # 返回状态空间的行数,features列数的初始状态
    state = self._get_state()
    return state.values

两个主要的工作方法:reset和step。

其中step是环境最重要的功能。智能体通过观察环境状态,选择相应的动作,执行动作后,从环境得到反馈。同时会检查总体的收益,任务是否失败等。

def step(self, action):
    # 根据传入的动作,计算奖励reward
    correct = action == self.df_features['label'].iloc[self.index]
    reward = 1 if correct else 0

    # 计算奖励值,准确率
    self.treward += reward
    self.index += 1
    self.accuracy = self.treward / (self.index - self.rows)

    # index>=总长度,则退出
    if self.index >= len(self.df_features):
        done = True
    elif reward == 1:
        done = False
    elif (self.accuracy < self.min_accuracy and
          self.index > self.rows + 10):
        done = True
    else:
        done = False

    state = self._get_state()
    info = {}
    return state, reward, done, info

02 深度强化网络DQLAgent

from collections import deque
import random

import numpy as np
from keras import Sequential
from keras.layers import Dense
from keras.optimizers import Adam


class DQLAgent:
    def __init__(self, env, gamma=0.95, hu=24, opt=Adam,
                 lr=0.001, finish=False):
        self.env = env

        self.finish = finish
        self.epsilon = 1.0
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        self.gamma = gamma
        self.batch_size = 32
        self.max_treward = 0
        self.averages = list()
        self.memory = deque(maxlen=2000)
        self.osn = env.observation_space.shape[0]
        self.model = self._build_model(hu, opt, lr)

    def _build_model(self, hu, opt, lr):
        model = Sequential()
        model.add(Dense(hu, input_dim=self.osn,
                        activation='relu'))
        model.add(Dense(hu, activation='relu'))
        model.add(Dense(self.env.action_space.n, activation='linear'))
        model.compile(loss='mse', optimizer=opt(lr=lr))
        return model

    def act(self, state):
        if random.random() <= self.epsilon:
            return self.env.action_space.sample()
        action = self.model.predict(state)[0]
        return np.argmax(action)

    def replay(self):
        batch = random.sample(self.memory, self.batch_size)
        for state, action, reward, next_state, done in batch:
            if not done:
                reward += self.gamma * np.amax(
                    self.model.predict(next_state)[0])
            target = self.model.predict(state)
            target[0, action] = reward
            self.model.fit(state, target, epochs=1,
                           verbose=False)
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay

    def learn(self, episodes):
        trewards = []
        for e in range(1, episodes + 1):
            state = self.env.reset()
            state = np.reshape(state, [1, self.osn])
            for _ in range(5000):
                action = self.act(state)
                next_state, reward, done, info = self.env.step(action)
                next_state = np.reshape(next_state,
                                        [1, self.osn])
                self.memory.append([state, action, reward,
                                    next_state, done])
                state = next_state
                if done:
                    treward = _ + 1
                    trewards.append(treward)
                    av = sum(trewards[-25:]) / 25
                    self.averages.append(av)
                    self.max_treward = max(self.max_treward, treward)
                    templ = 'episode: {:4d}/{} | treward: {:4d} | '
                    templ += 'av: {:6.1f} | max: {:4d}'
                    print(templ.format(e, episodes, treward, av,
                                       self.max_treward), end='\r')
                    break
            if av > 195 and self.finish:
                print()
                break
            if len(self.memory) > self.batch_size:
                self.replay()

    def test(self, episodes):
        trewards = []
        for e in range(1, episodes + 1):
            state = self.env.reset()
            for _ in range(5001):
                state = np.reshape(state, [1, self.osn])
                action = np.argmax(self.model.predict(state)[0])
                next_state, reward, done, info = self.env.step(action)
                state = next_state
                if done:
                    treward = _ + 1
                    trewards.append(treward)
                    print('episode: {:4d}/{} | treward: {:4d}'
                          .format(e, episodes, treward), end='\r')
                    break
        return trewards


小结:

今天是走通了深度强化学习在金融上的应用,搭建了金融交易环境。

后续还需要针对性的优化。

代码就上传至星球。

ETF轮动+RSRS择时,加上卡曼滤波:年化48.41%,夏普比1.89

我的开源项目及知识星球

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/33661.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python搭建沙箱环境

python搭建沙箱环境 文章目录python搭建沙箱环境一&#xff0c;下载virtualenv模块1.1 在线状态的下载1.2 离线状态的下载二&#xff0c;创建沙箱环境&#xff08;虚拟环境&#xff09;三&#xff0c;激活以及退出沙箱环境一&#xff0c;下载virtualenv模块 1.1 在线状态的下载…

JAVA异常

目录JAVA异常1.初识异常2.异常的处理2.1 捕获异常的基本语法2.2 捕获异常2.3 finally的使用2.4 异常的执行流程2.5 抛出异常3.JAVA异常体系4.自定义异常类JAVA异常 1.初识异常 异常指的就是程序在 运行时 出现错误时通知调用者的一种机制. 我们在编写代码的过程中,遇到过许多…

模态贡献量在汽车NVH分析中的案例应用

作者 | 蓝枫 导读&#xff1a;模态贡献量分析是基于结构模态的频响分析&#xff0c;一般被用来分析诊断低频振动问题&#xff0c;如方向盘抖动、地板抖动以及整车振动等的低频NVH问题&#xff0c;也可以诊断中频问题&#xff0c;如NTF优化问题&#xff0c;但NTF优化一般用GPA…

[附源码]java毕业设计疫情背景下叮当买菜管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

171-178-Hadoop-源码

171-Hadoop-源码&#xff1a; 以了解有印象&#xff0c;动手debug为主。大致流程和思想。 RPC 通信原理解析 1&#xff09;需求&#xff1a; 模拟 RPC 的客户端、服务端、通信协议三者如何工作的 https://gitee.com/HaoZhouRS/bigdata-study-code/tree/master/big-data-stud…

视频转换软件哪个好?万兴优转-支持超过1000种格式转换和输出

想必大家都知道&#xff0c;视频的格式分为很多种&#xff0c;而且不同设备能够播放的视频格式也各不相同&#xff0c;就比如PC端和mac端&#xff0c;其就有很大的不兼容问题。在日常工作中&#xff0c;我们往往将一个视频发给了对方&#xff0c;但对方却因为设备的差异而无法直…

023.二叉树的最近公共祖先

题目链接&#xff1a; 236. 二叉树的最近公共祖先 大概思路&#xff1a; 题目要求&#xff1a; 给定一个二叉树, 找到该树中两个指定节点q&#xff0c;p的最近公共祖先x。&#xff08;q、p一定存在且值不同&#xff09; 最近公共祖先&#xff1a; 两个节点共同的祖先&…

为什么浏览器控制台(Console)运行JavaScript代码有时会出现“undefined”?

为什么浏览器控制台&#xff08;Console&#xff09;运行JavaScript代码有时会出现“undefined”&#xff1f; 浏览器“控制台”&#xff08;console&#xff09;使用简介 about:blank是打开浏览器空白页的命令——内置在浏览器中的命令&#xff0c;可以打开浏览器空白页&…

SpringAMQP WorkQueue消息队列模型的理解与使用

原理分析 Work Queue&#xff0c;故名思意&#xff0c;工作队列&#xff0c;互相配合工作。适用于消息密集型消息队列的场景&#xff0c;如下图所示&#xff0c;queue中存在着大量的消息&#xff0c;而消费者有续配合工作&#xff0c;消息队列有阅后即焚的特点&#xff0c;所以…

【Spring Cloud实战】Spring Cloud Alibaba Sentinel熔断与限流 (最全讲解,附源码)

gitee地址&#xff1a;https://gitee.com/javaxiaobear/spring-cloud_study.git 在线阅读地址&#xff1a;https://javaxiaobear.gitee.io/ 1、简介 Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从流量控制、熔断降级、系统自适应保…

【车载开发系列】CAN总线知识入门篇

【车载开发系列】CAN总线知识入门篇 【车载开发系列】CAN总线知识入门篇【车载开发系列】CAN总线知识入门篇一.总线是什么二.CAN总线是什么三.CAN总线的传输介质四.CAN协议的特性有哪些五.CAN出现的背景六.CAN通信总线的作用七.CAN协议柔软性体现在哪里八.CAN总线的仲裁机制九.…

11月24日:fastadmin根目录下其他文件

addons下的两个文件 其一&#xff1a;.gitkeep 其二&#xff1a;.htaccess application中的common文件 pubilc文件中的uploads runtime中的文件解析 vendor和composer.json的关系 根目录下.gitgnore中的相关标准 composer.json和composer.lock之间的关系 主要是承接之前的fast…

面向对象之抽象类的认识 - (java语法)

文章目录前言1. 什么是抽象类1.1 抽象类与普通类的不同&#xff1a;1.2 子类继承抽象类总结✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来&#xff01; 编程真是一件很奇妙的东西。你只是浅尝辄止&#xff0c;那么只会觉得枯燥乏味&#xff0c;像对待任务似的应付它…

基于JSP的民宿酒店预约管理系统【数据库设计、源码、开题报告】

数据库脚本下载地址&#xff1a; https://download.csdn.net/download/itrjxxs_com/86466879 主要使用技术 SpringStruts2HibernateJSPCSSJSMysql 功能介绍 后台管理&#xff1a; 修改密码&#xff1a;修改个人密码&#xff1b; 会员信息管理&#xff1a;查看会员基本信息并…

C# 学习之路(C# 编程概述)

C# 学习之路&#xff08;C# 编程概述&#xff09; 前记&#xff1a;C# 学习之路&#xff0c;是我跟着 C# 图解教程(第五版) 学习的笔记&#xff0c;每一章都会有一篇笔记发出&#xff0c;小标题会对应书本的章节标题。 .NET 6 和之前的版本相比在顶级语句方面有很大的变化&…

【内网渗透】记一次靶机实战

一、信息收集 1.端口扫描 使用nmap进行端口扫描&#xff0c;发现其开放了22、80、8080、9000端口。 访问其8080端口&#xff0c;发现是一个web界面。 浏览页面内容&#xff0c;提升有一些提示。 【一一帮助安全学习&#xff0c;所有资源获取处一一】 ①网络安全学习路线…

vue2升级vue3的新变化

目录1、组合式API和setup语法糖definePropsdefineEmitsdefineExpose其他2、响应式原理ref和reactiverefreactivetoReftoRefs3、computed和watchcomputedwatchwatchEffect4、v-modelv-model参数v-model修饰符5、key6、v-if和v-for的优先级对比7、异步组件vue 作者&#xff08;尤…

天宇优配|医药股反弹受阻 公募乐观态度不改

历经前期继续反弹后&#xff0c;医药板块11月23日呈现大幅回调&#xff0c;相关细分赛道指数均有所下行&#xff0c;跌幅超越9%的相关个股更是不在少数。 国庆以来这轮医药反弹行情是否就此结束&#xff1f;对此&#xff0c;公募最新预判指出&#xff0c;23日医药板块回调与商场…

mp4视频格式转换器工具,万兴优转-多功能视音频处理软件

MP4是一种大众熟知的视频格式其优势在于在所有的播放器上都能够基本适用因此对于一些较为特殊的视频格式往往都需要将其转换为MP4视频格式才能够在播放器上正常播放。 那么怎样才能将这些特殊的视频格式转换为常用的mp4视频格式呢&#xff1f;这就需要用到mp4视频格式转换器工具…

用于useradd创建用户的规则文件-尚文网络xUP楠哥

~~全文共1026字&#xff0c;阅读需约5分钟。 进Q群11372462&#xff0c;领取专属报名福利&#xff0c;包含云计算学习路线图代表性实战训练大厂云计算面试题资料! # Linux创建普通用户 找来一台Linux系统&#xff0c;首先&#xff0c;执行useradd命令&#xff0c;不加任何参数…