gym-anytrading
参考:https://github.com/upb-lea/gym-electric-motor
AnyTrading 是一组基于 reinforcement learning (RL) 的 trading algorithms(交易算法)的 OpenAI Gym 环境集合。
该项目主要用于foreign exchange (FOREX) 和 stock markets (股票市场),并提供多个 Gym environments,以简化和改进基于reinforcement learning (RL) 的交易策略开发和测试。
该项目实现了三个主要 Gym environments:
• TradingEnv:一个抽象的 trading environment,可以支持所有类型的交易策略。
• ForexEnv:继承自 TradingEnv,用于外汇交易(FOREX)。
• StocksEnv:继承自 TradingEnv,用于股票交易(Stock trading)。
一、Installation
通过 PIP
pip install gym-anytrading
从仓库安装
git clone https://github.com/AminHP/gym-anytrading
cd gym-anytrading
pip install -e .
或者
pip install --upgrade --no-deps --force-reinstall https://github.com/AminHP/gym-anytrading/archive/master.zip
二、Environment Properties(环境属性)
在金融市场中,reinforcement learning (RL) agents 不能独立完成所有交易决策,因此需要简化问题,以便 RL agents 更快地学习交易策略。
以下两部分解释了如何简化 actions (交易动作) 和 positions (交易仓位),以提高学习效率。
1. Trading Actions(交易动作)
在传统交易市场中,交易者可能执行多种 actions,例如:
• Buy(买入)
• Sell(卖出)
• Hold(持有)
• Enter(进入市场)
• Exit(退出市场)
但对于 RL agents 而言,过多的 actions 可能导致:
1. 训练时间过长
2. 决策复杂度增加
3. 学习效率降低
因此,该环境仅支持以下两种 actions:
• Sell = 0(卖出)
• Buy = 1(买入)
📌 简化后的 benefits(优点):
• 交易策略变得更简单
• 训练时间减少
• 代理更容易学习到有效策略
2. Trading Positions(交易仓位)
Position 是交易市场中的一个关键概念,主要有两种:
• Long Position(多头仓位):买入资产(如股票、外汇)并持有,等待价格上涨后卖出获利。
• Short Position(空头仓位):借入资产并卖出,等待价格下跌后回购,以低价偿还借款并获利。
在某些交易环境中,你可能会看到更多 positions,例如:
• Flat Position(空仓)
• Hedging(对冲仓位)
但为了简化学习,该环境仅支持:
• Short = 0(空头)
• Long = 1(多头)
三、Trading Environments(交易环境)
该项目提供了多个 Gym environments,用于不同类型的交易市场。
在开发 gym-anytrading 之前,市面上大多数 trading environments 代码复杂、参数不透明,难以理解。因此,该项目的目标是:
1. 保持代码简单
2. 提供可扩展性
3. 适用于不同类型的交易市场
1. TradingEnv(抽象交易环境)
TradingEnv 继承自 gym.Env,是所有交易环境的基类。
核心属性(Attributes)

• df:DataFrame 的缩写。这是一个 pandas 的 DataFrame,包含你的数据集,并在类的构造函数中传递。
• prices:随时间变化的真实价格。用于计算利润和渲染环境。
• signal_features:随时间提取的特征。用于创建 Gym 观测值。
方法:
• reset:重置环境状态,返回初始观测值。
• step:执行给定的动作,返回新的观测值、奖励、完成标志和信息字典。
• render:渲染当前环境状态,可视化交易过程。
• close:关闭环境,释放资源。
抽象方法:
• _process_data:在构造函数中调用,返回一个包含 prices 和 signal_features 的元组。不同的交易市场需要提取不同的特征,因此该方法使 TradingEnv 成为通用环境,特定市场(如外汇、股票等)可以实现各自的特征提取逻辑。
• _calculate_reward:为强化学习代理计算奖励的函数。
• _update_profit:计算并更新代理迄今为止获得的总利润。利润表示从初始资金 1.0 单位开始,当前所获得的货币单位数量(利润 = 最终资金 / 初始资金)。
• max_possible_profit:计算无视交易费用情况下,代理可以获得的最大可能利润。
• _process_data:处理输入数据,提取价格和信号特征。
• _calculate_reward:根据当前状态和动作计算奖励。
• _update_profit:更新当前利润。
• max_possible_profit:计算在理想情况下可能获得的最大利润。
ForexEnv 和 StocksEnv 是 TradingEnv 的具体实现,分别针对外汇和股票市场。它们实现了上述抽象方法,并具有各自的特定属性:
2. ForexEnv
ForexEnv 是一个继承自 TradingEnv 的环境,专门用于外汇交易。它实现了 _process_data、_calculate_reward 和 _update_profit 方法,以适应外汇市场的特定需求。
• frame_bound:一个元组,指定数据帧 (df) 的起始和结束索引,在构造函数中传递。
• unit_side:指定交易开始时所持货币对的哪一侧。取值为字符串 'left'(默认)或 'right'。例如,在 EUR/USD 货币对中,选择 'left' 表示以 EUR 开始交易,初始资金为 1 EUR。在构造函数中传递。
• trade_fee:每次交易时从实际价格中扣除的默认固定费用。
• frame_bound:一个元组,定义数据帧的起始和结束索引。
• unit_side:一个字符串,表示交易单位的方向,取值为 'left' 或 'right'。
• trade_fee:每笔交易的固定费用。
3. StocksEnv
StocksEnv 是一个继承自 TradingEnv 的环境,专门用于股票交易。它实现了 _process_data、_calculate_reward 和 _update_profit 方法,以适应股票市场的特定需求。
• frame_bound:与 ForexEnv 相同。
• trade_fee_bid_percent:卖出时的默认固定费用百分比。例如,trade_fee_bid_percent=0.01 表示每次卖出股票时损失 1% 的资金。
• trade_fee_ask_percent:买入时的默认固定费用百分比。例如,trade_fee_ask_percent=0.005 表示每次买入股票时损失 0.5% 的资金。
用户可以通过继承 TradingEnv、ForexEnv 或 StocksEnv,并根据需要实现自定义的奖励、利润、费用计算等策略,来创建自定义的交易环境。
Examples
1. Create an environment
以下是创建一个默认外汇交易环境的示例代码:
import gymnasium as gym
import gym_anytradingenv = gym.make('forex-v0')
# 或者创建股票交易环境
# env = gym.make('stocks-v0')
这将创建一个默认的交易环境。您可以根据需要更改数据集、frame_bound 等参数。
2. Create an environment with custom parameters
此外,您可以创建自定义环境,例如:
import gym
import gym_anytrading
import pandas as pd# 加载您的数据集
df = pd.read_csv('您的数据.csv')# 创建带有自定义参数的股票交易环境
env = gym.make('Stocks-v0', df=df, window_size=10, frame_bound=(10, len(df)))
在上述示例中,您可以根据自己的需求创建一个带有自定义参数的交易环境。示例展示如何使用自定义的数据集、窗口大小和帧范围来创建股票交易环境:your_dataframe 是包含市场数据的 pandas DataFrame。您可以根据需要调整 window_size 和 frame_bound 参数。
通过这种方式,您可以使用 gym-anytrading 提供的环境来开发和测试基于强化学习的交易算法。
3. 打印环境信息
done = False
state = env.reset()while not done:
action = env.action_space.sample() # 随机选择一个动作
next_state, reward, done, info = env.step(action)
print(f"State: {next_state}, Reward: {reward}, Done: {done}, Info: {info}")
在与环境交互时,您可能需要打印一些信息以了解当前状态、奖励等。以下是一个示例,展示如何在每个步骤中打印相关信息
4. Plot the environment
为了可视化交易过程,您可以使用环境的渲染功能来绘制价格曲线、买卖点等。以下是一个示例,展示如何绘制环境:
import matplotlib.pyplot as plt
env.render()
plt.show()
这将生成一个图表,显示价格走势以及代理的买卖操作。

5. A complete example
import gym
import gym_anytrading
import pandas as pd
import matplotlib.pyplot as plt# 加载数据集
df = pd.read_csv('您的数据.csv')# 创建股票交易环境
env = gym.make('Stocks-v0', df=df, window_size=10, frame_bound=(10, len(df)))# 重置环境
state = env.reset()# 与环境交互
while True:
action = env.action_space.sample() # 随机选择一个动作
next_state, reward, done, info = env.step(action)
if done:
break# 绘制结果
env.render()
plt.show()
以下是对 gym-anytrading 中 A Complete Example(完整示例) 及相关部分的详细讲解,包括代码解析、渲染优化、自定义环境、扩展方法和相关项目。
完整示例
该示例展示了如何使用 gym-anytrading 运行 FOREX(外汇) 或 Stocks(股票) 交易环境,并输出交易信息。
代码解析
import numpy as np
import matplotlib.pyplot as pltimport gymnasium as gym
import gym_anytrading
from gym_anytrading.envs import TradingEnv, ForexEnv, StocksEnv, Actions, Positions
from gym_anytrading.datasets import FOREX_EURUSD_1H_ASK, STOCKS_GOOGL
• gymnasium → 现代化的 Gym 版本,提供强化学习环境的标准接口。
• gym_anytrading → 交易市场的 RL 环境。
• ForexEnv & StocksEnv → 外汇和股票交易环境类。
• Actions & Positions → 定义交易操作(Buy/Sell)和仓位(Long/Short)。
• FOREX_EURUSD_1H_ASK & STOCKS_GOOGL → 预定义的市场数据集(外汇 & 股票)。
创建环境
env = gym.make('forex-v0', frame_bound=(50, 100), window_size=10)
# env = gym.make('stocks-v0', frame_bound=(50, 100), window_size=10)
• frame_bound=(50, 100) → 数据帧范围,表示仅使用 df[50:100] 作为训练数据。
• window_size=10 → 代理每次观察 10 个数据点,类似于滑动窗口。
运行环境
observation = env.reset(seed=2023)
while True:action = env.action_space.sample() # 随机选择动作observation, reward, terminated, truncated, info = env.step(action)done = terminated or truncated# env.render() # 每步渲染(不推荐,会浪费时间)if done:print("info:", info)break
• env.reset(seed=2023) → 复位环境,并设定随机种子,确保实验可复现。
• env.step(action) → 执行 action,返回:
• observation → 代理的新观测值
• reward → 交易奖励
• terminated → 是否达到终止状态
• truncated → 是否提前终止
• info → 交易信息(total_reward, total_profit, position)
• env.render() → 渲染每步(但会浪费时间,推荐 render_all())
优化渲染
plt.cla()
env.unwrapped.render_all()
plt.show()
• env.unwrapped.render_all() → 只在最后一步渲染,而不是每个 step 后渲染(提高运行速度)。
• plt.show() → 显示交易图表,包含价格曲线、买卖点、持仓情况。
示例输出
info: {'total_reward': 27.89, 'total_profit': 0.9898, 'position': <Positions.Long: 1>}
• total_reward → 代理获得的总奖励
• total_profit → 交易回报率
• position → 代理最终的持仓状态(Long/Short)
渲染图像分析
你会注意到,在图表上,前 10 个点(window_size=10)没有 position(持仓)。
• 这是因为它们仅用于初始化代理的观测值,不影响 reward 和 profit。
• 环境的 _start_tick = 10,_last_trade_tick = 9,表示交易从第 10 个数据点开始。
自定义数据处理
如果你想在环境外部处理数据,可以使用两种方法:
方法 1(推荐)
在 环境外 处理数据,然后覆盖 _process_data 方法:
def my_process_data(env):
start = env.frame_bound[0] - env.window_size
end = env.frame_bound[1]
prices = env.df.loc[:, 'Low'].to_numpy()[start:end]
signal_features = env.df.loc[:, ['Close', 'Open', 'High', 'Low']].to_numpy()[start:end]
return prices, signal_features
class MyForexEnv(ForexEnv):
_process_data = my_process_data # 直接替换默认数据处理方法
env = MyForexEnv(df=FOREX_EURUSD_1H_ASK, window_size=12, frame_bound=(12, len(FOREX_EURUSD_1H_ASK)))
• 适用于快速修改数据提取逻辑,不需要更改 ForexEnv 本身。
方法 2(自定义类)
完全继承 StocksEnv 并手动传入 prices 和 signal_features:
def my_process_data(df, window_size, frame_bound):
start = frame_bound[0] - window_size
end = frame_bound[1]
prices = df.loc[:, 'Low'].to_numpy()[start:end]
signal_features = df.loc[:, ['Close', 'Open', 'High', 'Low']].to_numpy()[start:end]
return prices, signal_features
class MyStocksEnv(StocksEnv):
def __init__(self, prices, signal_features, **kwargs):
self._prices = prices
self._signal_features = signal_features
super().__init__(**kwargs)def _process_data(self):
return self._prices, self._signal_features
prices, signal_features = my_process_data(df=STOCKS_GOOGL, window_size=30, frame_bound=(30, len(STOCKS_GOOGL)))
env = MyStocksEnv(prices, signal_features, df=STOCKS_GOOGL, window_size=30, frame_bound=(30, len(STOCKS_GOOGL)))
• 适用于完全自定义数据处理逻辑,并且想在 StocksEnv 基础上扩展更多功能。
相关项目
如果你希望使用更高级的交易环境,可以尝试以下项目:
1️⃣ DI-engine
• 一个 mid-level 工具,介于 gym-anytrading 和 gym-mtsim 之间。
• 功能:
• 5 种交易动作(Buy, Sell, Hold 等)
• 3 种仓位(Long, Short, Flat)
• 改进的 Reward function
• 适用人群: 半专业(Semi-expert)交易策略开发者。
2️⃣ gym-mtsim
• 适用于真实交易环境(MetaTrader 5)
• 更复杂的市场建模
• 适用于真实外汇交易者
📌 如果你是初学者,推荐 gym-anytrading
📌 如果你是进阶用户,可以尝试 DI-engine 或 gym-mtsim
相关文章:
gym-anytrading
参考:https://github.com/upb-lea/gym-electric-motor AnyTrading 是一组基于 reinforcement learning (RL) 的 trading algorithms(交易算法)的 OpenAI Gym 环境集合。 该项目主要用于foreign exchange (FOREX) 和 stock markets (股票市场)…...
如何自定义软件安装路径及Scoop包管理器使用全攻略
如何自定义软件安装路径及Scoop包管理器使用全攻略 一、为什么无法通过WingetUI自定义安装路径? 问题背景: WingetUI是Windows包管理器Winget的图形化工具,但无法直接修改软件的默认安装路径。原因如下: Winget设计限制…...
私有化部署 DeepSeek + Dify,构建你的专属私人 AI 助手
私有化部署 DeepSeek Dify,构建你的专属私人 AI 助手 概述 DeepSeek 是一款开创性的开源大语言模型,凭借其先进的算法架构和反思链能力,为 AI 对话交互带来了革新性的体验。通过私有化部署,你可以充分掌控数据安全和使用安全。…...
Java 进阶 01 —— 5 分钟回顾一下 Java 基础知识
Java 进阶 01 —— 5 分钟回顾一下 Java 基础知识 Java 生态圈Java 跨平台的语言 Java 虚拟机规范JVM 跨语言的平台多语言混合编程两种架构 举例 JVM 的生命周期 虚拟机的启动虚拟机的执行虚拟机的退出 JVM 发展历程 Sun Classic VMExact VMHotSpotBEA 的 JRockitIBM 的 J9 …...
V103开发笔记1-20250113
2025-01-13 一、应用方向分析 应用项目: PCBFLY无人机项目(包括飞控和手持遥控器); 分析移植项目,应用外设资源包括: GPIO, PWM,USART,GPIO模拟I2C/SPI, ADC,DMA,USB等; 二、移植项目的基本…...
在 Spring Boot 项目中,bootstrap.yml 和 application.yml文件区别
在 Spring Boot 项目中,bootstrap.yml 和 application.yml 是两个常用的配置文件,它们的作用和加载顺序有所不同。以下是它们的详细说明: 1. bootstrap.yml 作用: bootstrap.yml 是 Spring Cloud 项目中的配置文件,用于…...
DeepSeek研究员在线爆料:R1训练仅用两到三周,春节期间观察到R1 zero强大进化
内容提要 刚刚我注意到DeepSeek研究员Daya Guo回复了网友有关DeepSeek R1的一些问题,以及接下来的公司的计划,只能说DeepSeek的R1仅仅只是开始,内部研究还在快速推进,DeepSeek 的研究员过年都没歇,一直在爆肝推进研究…...
Java进阶文件输入输出实操(图片拷贝)
Java进阶文件输入输出实操(图片拷贝) 把某个目录下的全部图片,全部拷贝到另外一个目录 package test; import domee.chapter6_7.B; import java.io.*; public class Ex10_10 { public static void main(String[] args) throws IOException { …...
Spring Boot统一异常拦截实践指南
Spring Boot统一异常拦截实践指南 一、为什么需要统一异常处理 在Web应用开发中,异常处理是保证系统健壮性和用户体验的重要环节。传统开发模式中常见的痛点包括: 异常处理逻辑分散在各个Controller中错误响应格式不统一敏感异常信息直接暴露给客户端…...
LLM推理--vLLM解读
主要参考: vLLM核心技术PagedAttention原理 总结一下 vLLM 的要点: Transformer decoder 结构推理时需要一个token一个token生成,且每个token需要跟前序所有内容做注意力计算(包括输入的prompt和该token之前生成的token…...
vscode软件操作界面UI布局@各个功能区域划分及其名称称呼
文章目录 abstract检查用户界面的主要区域官方文档关于UI的介绍 abstract 检查 Visual Studio Code 用户界面 - Training | Microsoft Learn 本质上,Visual Studio Code 是一个代码编辑器,其用户界面和布局与许多其他代码编辑器相似。 界面左侧是用于访…...
PyQt6/PySide6 的 QTreeView 类
QTreeView 是 PyQt6 或 PySide6 库中用于显示分层数据的控件。它适用于展示树形结构的数据,如文件系统、组织结构等。QTreeView 也是基于模型-视图架构的,通常与 QAbstractItemModel 的子类(如 QStandardItemModel 或自定义模型)一…...
一键开启/关闭deepseek
一键开启/关闭 Deepseek对应下载的模型一键开启 Deepseek,一键关闭Deepseek双击对应的bat,就可以启动https://mbd.pub/o/bread/Z56YmpZvbat 下载:https://mbd.pub/o/bread/Z56YmpZv 可以自己写下来,保存成bat文件,也可…...
单纯接入第三方模型就无需算法备案了么?
随着人工智能技术的快速发展,越来越多的企业开始接入第三方模型以提升自身业务能力。然而,关于算法备案的问题也引发了诸多讨论,尤其是单纯接入第三方模型是否需要备案这一问题,更是让不少企业感到困惑。 一、明确算法备案的主体…...
实现一个 LRU 风格的缓存类
实现一个缓存类 需求描述豆包解决思路:实现代码:优化11. std::list::remove 的时间复杂度问题2. 代码复用优化后的代码优化说明 优化21. 边界条件检查2. 异常处理3. 代码封装性4. 线程安全优化后的代码示例优化说明 DeepSeek(深度思考R1&…...
DS图(中)(19)
文章目录 前言一、图的遍历广度优先遍历深度优先遍历 二、最小生成树Kruskal算法Prim算法两种方法对比 总结 前言 承上启下,我们来学习下图的中篇!!! 一、图的遍历 图的遍历指的是遍历图中的顶点,主要有 广度优先遍历 …...
YK人工智能(六)——万字长文学会基于Torch模型网络可视化
1. 可视化网络结构 随着深度神经网络做的的发展,网络的结构越来越复杂,我们也很难确定每一层的输入结构,输出结构以及参数等信息,这样导致我们很难在短时间内完成debug。因此掌握一个可以用来可视化网络结构的工具是十分有必要的…...
使用 Swift 完成FFmpeg音频录制、播放和视频格式转换应用
使用 Swift 构建音频录制、播放和视频格式转换应用 在这篇博客中,我们介绍如何用ffmpeg在swift上实现音频录制、音频播放、通过ffmpeg命令实现视频格式转换 音频录制:通过 AVAudioRecorder 实现音频录制功能。音频播放:通过 AVAudioPlayer …...
Gitea+Gridea 创建个人博客
历史文档存档,该方法目前已经无法使用,部署方法可供参考 Gitea部分 1.关于Gitea Gitea 是一个面向开源及私有软件项目的托管平台,是全球最大的代码托管平台之一。它采用 Git 分布式版本控制系统,为开发者提供了代码托管、版本控…...
【Linux】一文带你入门了解线程和虚拟地址空间中页表映射的秘密(内附手绘底层逻辑图 通俗易懂)
绪论 每日激励:“努力去做自己该做的,但是不要期待回报,不是付出了就会有回报的,做了就不要后悔,不做才后悔。—Jack” 绪论: 本章是LInux中非常重要的线程部分,通过了解线程的基本概念&am…...
js面试some和every的区别
1.基础使用 some和every 都是数组的一个方法let num [1,2,3,4,5,6] let flag1 num.some((item,index,array)> item > 2)let flag2 num.every((item,index, array)> item > 2)1.some 遍历判断中是符合条件的值 一旦找到则不会继续迭代下去 直接返回 2.every 遍历…...
缓存类为啥使用 unordered_map 而不是 map
性能考虑: std::unordered_map 是基于哈希表实现的,而 std::map 是基于红黑树实现的。对于查找操作,std::unordered_map 的平均查找时间复杂度是 O ( 1 ) O(1) O(1),而 std::map 的查找时间复杂度是 O ( l o g n ) O(log n) O(l…...
ollama linux下载
实验室服务器(A6000)执行curl -fsSL https://ollama.com/install.sh | sh太慢了。 而sudo snap install ollama,容易爆cudalibrt.so12无法正常使用的bug。 发现 https://www.modelscope.cn/models/modelscope/ollama-linux 使用modelscope进…...
k8s服务发现有哪些方式?
在 Kubernetes 中,服务发现是指如何让应用程序在集群内互相找到并通信。Kubernetes 提供了多种服务发现的方式,适应不同的使用场景。以下是 Kubernetes 中常见的服务发现方式: 1. 环境变量(Environment Variables) 概…...
Flash Attention与Attention
原始Attention是: Flash Attention: 伪代码:4d(分别代表Q\K\V\O) Flash Attention2优化了...
vue 使用fetch-event-source 处理sse,实现ChatGpt逐字输出效果
1. 安装 npm install microsoft/fetch-event-source 2. 引用 import { fetchEventSource } from "microsoft/fetch-event-source"; 3. 使用 fetchEventSource(/api/chat, { method: POST,headers: {Content-Type: application/json,Accept: */*,Token: this.toke…...
JAVA进阶之线程
为神马有线程?这玩意儿在干嘛??? 回答这个问题,就先要知道一点点计算机的工作方式。 总所周知,计算机有五部分:输入输出、计算器、存储器、控制器。而在计算机内,CPU、内存、I/O之…...
机器学习专业毕设选题推荐合集 人工智能
目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光,一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整理…...
C++ 中的 `string` 类型:全面解析与高效操作
C 中的 string 类型:全面解析与高效操作 在 C 中,string 类型是对字符数组的高级封装,它提供了大量内置函数,使得字符串的处理变得更为简便和高效。与 C 风格的字符数组不同,string 类型不仅自动管理内存,…...
go语言中的Stringer的使用
Go 语言中的 Stringer 是一个非常有用的接口,它在标准库的 fmt 包中定义。Stringer 接口允许类型定义它们的字符串表示方式,这在格式化输出时特别有用。让我们深入了解一下: Stringer 接口定义: type Stringer interface {Strin…...
