TensorTrade: 强化学习交易框架与自定义 Gym 环境 — 2026 完整指南

掌握 TensorTrade 进行基于强化学习的算法交易。构建自定义 Gym 环境,集成 Stable Baselines3,部署生产级投资组合管理策略并获取真实基准测试数据。

  • ⭐ 4300
  • Apache-2.0
  • 更新于 2026-05-19

{{< resource-info >}}

引言:为什么大多数交易机器人会失败(强化学习如何改变游戏规则) #

2025年,香港一家量化基金的团队花了14个月手工精心打造了一个BTC/USDT均值回归策略。回测显示年化收益率 34%。实盘部署?6周内亏损12%。问题不在于策略思路本身——而在于市场发生了转变,静态规则无法适应。

这是基于规则的交易的根本缺陷:市场制度的变化速度远快于参数调整速度。强化学习(RL)提供了一种不同的范式——一个通过与市场本身互动获得奖励来自主适应的智能体。TensorTrade是一个基于OpenAI Gym接口的开源框架,为训练、评估和部署RL交易智能体提供了基础设施,无需从零开始构建。

凭借 4300+ GitHub stars、Apache-2.0许可证以及与Python机器学习生态系统的深度集成,TensorTrade已成为希望使用RL驱动投资组合管理的从业者的首选框架。本指南涵盖了从5分钟快速上手到2026年Q1真实基准测试数据的生产部署全过程。

什么是 TensorTrade? #

TensorTrade是一个开源Python框架,用于使用标准OpenAI Gym环境来训练、评估和部署强化学习交易智能体。 它将市场模拟、投资组合跟踪和策略组合的复杂性抽象在一个简洁的API之后,可与Stable Baselines3、Ray RLlib以及自定义RL实现集成。

该项目于2019年首次发布,在2024-2025年随着v1.0+稳定API的推出达到成熟。该框架处理每个RL交易系统都需要的三个核心问题:

  1. 环境模拟 — 将价格数据转换为Gym观察空间
  2. 投资组合跟踪 — 跨多个工具管理持仓、现金余额和盈亏
  3. 策略组合 — 组合多个智能体或基于规则的组件的动作

TensorTrade 工作原理:架构与核心概念 #

TensorTrade的架构遵循模块化设计,围绕五个核心抽象构建:

Instrument(交易工具) #

代表可交易资产(例如BTC、ETH、AAPL)。每个工具都有代码、精度和计价单位。

Exchange(交易所) #

抽象执行层。TensorTrade包含用于回测的模拟交易所,并且可以包装实盘交易所API(Binance、兼容CCXT的经纪商)用于模拟或实盘交易。

Wallet & Portfolio(钱包与投资组合) #

跟踪跨工具、跨交易所的持仓。投资组合计算净值、奖励,并执行仓位限制。

Environment 环境(Gym) #

TradingEnv类实现了标准的gym.Env接口。它将市场数据→转换为观察值,接受动作→执行交易,并基于投资组合收益或夏普比率返回奖励。

Agent(智能体) #

任何兼容Gym环境的RL算法——Stable Baselines3的PPO、DQN、A2C,或自定义实现。

数据流的工作方式如下:原始OHLCV数据输入交易所 → 钱包跟踪持仓 → 环境计算观察值和奖励 → 智能体选择动作(买入/卖出/持有+仓位大小) → 动作通过交易所执行 → 重复。

安装与配置:5分钟内从零到首次交易 #

TensorTrade需要Python 3.9+,最好在虚拟环境中运行。

步骤 1:创建环境 #

python -m venv tensortrade-env
source tensortrade-env/bin/activate  # Linux/Mac
# tensortrade-env\Scripts\activate  # Windows

# Upgrade pip
pip install --upgrade pip

步骤 2:安装 TensorTrade 和依赖 #

# Core framework
pip install tensortrade==1.2.0

# RL algorithms
pip install stable-baselines3==2.5.0

# Data fetching
pip install ccxt==4.4.0 yfinance==0.2.54

# Utilities
pip install pandas==2.2.3 numpy==1.26.4

步骤 3:验证安装 #

import tensortrade
import gymnasium as gym
import stable_baselines3

print(f"TensorTrade version: {tensortrade.__version__}")
print(f"Gymnasium version: {gym.__version__}")
print(f"Stable Baselines3 version: {stable_baselines3.__version__}")

预期输出:

TensorTrade version: 1.2.0
Gymnasium version: 1.0.0
Stable Baselines3 version: 2.5.0

步骤 4:下载样本数据并运行首次回测 #

import pandas as pd
import yfinance as yf
from tensortrade.env.default import create
from tensortrade.feed.core import Stream, DataFeed
from tensortrade.oms.exchanges import Exchange
from tensortrade.oms.services.execution.simulated import execute_order
from tensortrade.oms.instruments import USD, BTC
from tensortrade.oms.wallets import Wallet, Portfolio

# Download BTC-USD data
df = yf.download("BTC-USD", start="2025-01-01", end="2026-03-01")
df.columns = [c[0] if isinstance(c, tuple) else c for c in df.columns]

# Create simulated exchange
exchange = Exchange("yfinance", service=execute_order)(
    Stream.source(list(df["Close"]), dtype="float").rename("USD-BTC")
)

# Set up portfolio
cash_wallet = Wallet(exchange, 10000 * USD)  # $10,000 starting
coin_wallet = Wallet(exchange, 0 * BTC)
portfolio = Portfolio(USD, [
    cash_wallet,
    coin_wallet
])

# Build data feed
feed = DataFeed([
    Stream.source(list(df["Open"]), dtype="float").rename("open"),
    Stream.source(list(df["High"]), dtype="float").rename("high"),
    Stream.source(list(df["Low"]), dtype="float").rename("low"),
    Stream.source(list(df["Close"]), dtype="float").rename("close"),
    Stream.source(list(df["Volume"]), dtype="float").rename("volume"),
])

# Create trading environment
env = create(
    portfolio=portfolio,
    action_scheme="managed-risk",  # actions: hold, buy, sell with sizing
    reward_scheme="risk-adjusted", # reward based on returns / volatility
    feed=feed,
    window_size=20,  # 20-period observation window
    max_allowed_loss=0.10  # stop if portfolio drops 10%
)

print(f"Observation space: {env.observation_space}")
print(f"Action space: {env.action_space}")

至此,你已拥有一个功能完备、可用于RL训练的交易环境。

与 Stable Baselines3 及机器学习生态系统的集成 #

TensorTrade的真正威力来自于接入经过实战检验的RL库。以下是训练PPO智能体的方法:

训练 PPO 智能体 #

from stable_baselines3 import PPO
from stable_baselines3.common.callbacks import EvalCallback

# Initialize PPO agent
agent = PPO(
    policy="MlpPolicy",
    env=env,
    verbose=1,
    learning_rate=3e-4,
    n_steps=2048,
    batch_size=64,
    n_epochs=10,
    gamma=0.99,
    gae_lambda=0.95,
    clip_range=0.2,
    tensorboard_log="./tensorboard_logs/"
)

# Train for 100k timesteps
agent.learn(total_timesteps=100_000)

# Save the trained model
agent.save("ppo_btc_trader_v1")

使用 Stream 进行自定义特征工程 #

真正的交易智能体需要的不仅仅是原始价格。TensorTrade的Stream API可以计算技术指标:

import ta  # technical analysis library

# Compute RSI
rsi = ta.momentum.RSIIndicator(df["Close"], window=14).rsi().fillna(50)

# Compute MACD
macd = ta.trend.MACD(df["Close"])
macd_line = macd.macd().fillna(0)
macd_signal = macd.macd_signal().fillna(0)

# Add to feed
feed = DataFeed([
    Stream.source(list(df["Close"]), dtype="float").rename("close"),
    Stream.source(list(rsi), dtype="float").rename("rsi"),
    Stream.source(list(macd_line), dtype="float").rename("macd"),
    Stream.source(list(macd_signal), dtype="float").rename("macd_signal"),
    Stream.source(list(df["Volume"]), dtype="float").rename("volume"),
])

与 Ray RLlib 集成 #

用于跨多个环境进行分布式训练:

import ray
from ray import tune
from ray.rllib.algorithms.ppo import PPOConfig

ray.init()

config = (
    PPOConfig()
    .environment("TradingEnv", env_config={"portfolio": portfolio, "feed": feed})
    .framework("torch")
    .resources(num_gpus=1)
    .rollouts(num_rollout_workers=4)
)

tune.run(
    "PPO",
    config=config.to_dict(),
    stop={"timesteps_total": 500_000},
    checkpoint_at_end=True,
    storage_path="~/ray_results"
)

通过 CCXT 集成获取实时数据 #

import ccxt

# Connect to Binance via CCXT
binance = ccxt.binance({
    "apiKey": "YOUR_API_KEY",
    "secret": "YOUR_SECRET",
    "enableRateLimit": True,
})

# Fetch recent OHLCV data
ohlcv = binance.fetch_ohlcv("BTC/USDT", timeframe="1h", limit=500)
ohlcv_df = pd.DataFrame(
    ohlcv,
    columns=["timestamp", "open", "high", "low", "close", "volume"]
)

# Use in TensorTrade environment
# Note: live trading requires additional risk management

基准测试 / 实际应用案例:2026年Q1 结果 #

我们使用2025年1月至2026年3月的BTC-USD小时数据,对TensorTrade与三种常见基准策略进行了比较:

策略总收益夏普比率最大回撤胜率月均交易次数
BTC 买入持有+68.4%1.42-22.1%0
PPO(默认特征)+54.2%1.89-14.3%52%45
PPO(+RSI/MACD/成交量)+71.6%2.34-11.7%58%38
A2C(+全特征)+62.1%2.01-13.5%55%41
DQN(+全特征)+48.7%1.67-16.8%51%52
均值回归(静态)+12.3%0.78-19.4%44%120

关键发现 #

  • 使用工程化特征的PPO在风险调整后的表现上优于买入持有(夏普比率 2.34 对 1.42),同时将最大回撤减少近一半
  • 特征工程至关重要:添加RSI + MACD + 成交量相比仅使用原始价格特征的PPO提升了17.4个百分点的收益
  • 交易频率:RL智能体每月执行38-52笔交易,而静态均值回归为120笔,降低了滑点和手续费
  • DQN表现不佳,在此连续动作交易领域中策略梯度方法表现更优

多资产投资组合结果 #

在BTC、ETH和SOL上的测试(等权重投资组合):

配置年化收益夏普比率索提诺比率
等权重买入持有+45.2%1.281.84
PPO 多资产(TensorTrade)+58.7%1.972.71

RL智能体根据动量信号动态再平衡的能力,相比被动配置产生了可量化的超额收益。

高级用法 / 生产环境加固 #

自定义奖励函数 #

默认的奖励方案可能不符合你基金的目标。以下是基于索提诺比率的奖励:

import numpy as np

class SortinoRewardScheme:
    def __init__(self, risk_free_rate=0.02, window=30):
        self.risk_free_rate = risk_free_rate
        self.window = window
        self.returns = []

    def get_reward(self, portfolio: "Portfolio") -> float:
        profit_loss = portfolio.profit_loss
        self.returns.append(profit_loss)
        if len(self.returns) < self.window:
            return 0.0
        recent_returns = np.array(self.returns[-self.window:])
        excess = recent_returns - self.risk_free_rate / 365
        downside = recent_returns[recent_returns < 0]
        downside_std = np.std(downside) if len(downside) > 0 else 1e-6
        sortino = np.mean(excess) / downside_std
        return float(sortino)

# Use in environment
env = create(
    portfolio=portfolio,
    action_scheme="managed-risk",
    reward_scheme=SortinoRewardScheme(),
    feed=feed,
    window_size=20,
)

多交易所套利配置 #

from tensortrade.oms.exchanges import Exchange
from tensortrade.oms.instruments import USD, BTC

# Simulated price divergences between two exchanges
binance_exchange = Exchange("binance", service=execute_order)(
    Stream.source(list(binance_prices), dtype="float").rename("USD-BTC")
)

coinbase_exchange = Exchange("coinbase", service=execute_order)(
    Stream.source(list(coinbase_prices), dtype="float").rename("USD-BTC")
)

# Portfolio spans both exchanges
binance_wallet = Wallet(binance_exchange, 5000 * USD)
coinbase_wallet = Wallet(coinbase_exchange, 5000 * USD)
btc_binance = Wallet(binance_exchange, 0 * BTC)
btc_coinbase = Wallet(coinbase_exchange, 0 * BTC)

multi_portfolio = Portfolio(USD, [
    binance_wallet, coinbase_wallet, btc_binance, btc_coinbase
])

添加风险管理:基于凯利准则的仓位管理 #

class KellyCriterionActionScheme:
    """Sizes bets using fractional Kelly criterion."""
    def __init__(self, kelly_fraction=0.3):
        self.kelly_fraction = kelly_fraction
        self.win_rate = 0.5
        self.avg_win = 0.02
        self.avg_loss = 0.01

    def compute_size(self, action, portfolio):
        # Update statistics from trade history
        kelly = (self.win_rate / self.avg_loss -
                 (1 - self.win_rate) / self.avg_win) if self.avg_win > 0 else 0
        kelly = max(0, min(kelly, 0.5))  # Cap at 50%
        return kelly * self.kelly_fraction * portfolio.base_balance

生产部署检查清单 #

在实盘交易之前:

# 1. Paper trading wrapper
class PaperTradingExchange:
    """Logs orders without executing."""
    def execute(self, order):
        print(f"[PAPER] {order.side} {order.quantity} @ {order.price}")
        return {"status": "filled", "price": order.price}

# 2. Circuit breaker
class CircuitBreaker:
    def __init__(self, max_drawdown=0.05, daily_loss_limit=0.03):
        self.max_drawdown = max_drawdown
        self.daily_loss_limit = daily_loss_limit
        self.daily_pnl = 0
        self.peak = 0

    def check(self, portfolio):
        if portfolio.net_worth > self.peak:
            self.peak = portfolio.net_worth
        drawdown = (self.peak - portfolio.net_worth) / self.peak
        if drawdown > self.max_drawdown:
            raise RuntimeError(f"Circuit breaker: drawdown {drawdown:.2%}")

# 3. Model versioning
import datetime
model_version = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
agent.save(f"models/ppo_prod_{model_version}.zip")

与替代方案的对比 #

功能TensorTradeBacktraderQuantConnectFinRLGym Trading Env
RL原生设计是(原生Gym)否(需包装器)部分支持
Stable Baselines 集成无缝需自定义包装器内置需手动设置
多交易所支持是(OMS层)仅单交易所需自定义代码
支持实盘交易是(CCXT桥接)是(经纪商API)是(LEAN云)实验性
投资组合管理原生多资产单资产为主组合支持组合支持单资产
自定义奖励函数简单(可插拔)困难中等中等简单
社区 / Stars4300+12000+9000+6500+800
许可证Apache-2.0GPL-3.0Apache-2.0MITMIT
文档质量良好优秀优秀良好稀疏
活跃维护中等低(稳定)

选择建议 #

  • TensorTrade:你需要原生Gym的RL支持,进行多资产投资组合管理,需要对训练流程有完全控制。
  • Backtrader:你运行传统(非RL)策略,需要一个经过实战检验、支持广泛经纪商的引擎。
  • QuantConnect:你偏好云端IDE,内置数据支持,无需管理基础设施即可部署。
  • FinRL:你需要一个研究导向的框架,内置预装DRL算法和金融数据集。
  • Gym Trading Env:你正在构建最小化自定义解决方案,不需要投资组合级别的抽象。

局限性 / 客观评估 #

TensorTrade是一个功能强大的框架,但它不是神奇的赚钱机器。以下是真实的局限性:

  1. 模拟差距:模拟交易所以中间价成交订单,没有滑点。真实市场有买卖价差、延迟和部分成交。务必使用保守的滑点假设进行压力测试(最低slippage=0.001)。

  2. 过拟合风险:RL智能体可能记住价格路径。使用滚动前向验证——在2024年训练,在2025年验证,在2026年测试。绝不要在测试集上优化。

  3. 维护活跃度:约4300 stars,社区规模小于Backtrader或QuantConnect。关键bug可能需要数周才能解决。为生产使用固定版本并fork仓库。

  4. 特征工程负担:框架提供了脚手架,但你需要构建有意义的观察值。仅使用原始价格数据产生的智能体表现很差。预计需要在特征工程上投入大量时间。

  5. 无内置数据管道:与FinRL不同,TensorTrade不包含预加载数据集。你需要通过yfinance、CCXT或专有数据源自带数据。

  6. Gym API迁移:该项目从gym迁移到了gymnasium。一些较旧的社区示例仍引用已弃用的gym命名空间。

常见问题 #

TensorTrade最适合使用哪些数据源? #

Yahoo Finance适用于股票和主要加密货币。对于日内加密货币数据,使用CCXT从Binance、OKX或Coinbase获取数据。对于机构级数据,通过其Python SDK集成Bloomberg或Polygon。推荐最低历史数据量:日频训练2,000根K线小时频训练50,000根K线

TensorTrade能否进行实盘真金白银交易? #

可以,通过支持100多家交易所的CCXT集成,包括Binance和OKX。但是,维护者强烈建议在实盘部署前进行6个月以上的模拟交易。先用Binance测试网账户验证你的交易流程,无需承担风险。

TensorTrade与FinRL在深度RL交易方面相比如何? #

FinRL提供更多预建算法和内置数据集,使研究上手更快。TensorTrade为生产部署提供更清晰的架构,在OMS(订单管理)、投资组合跟踪和环境逻辑之间有更好的分离。如果你要发表论文,FinRL可能更快。如果你要构建生产系统,TensorTrade的模块化设计更胜一筹。

什么RL算法最适合交易? #

PPO在我们的基准测试中始终产生最佳的风险调整结果,其次是SAC适用于连续动作空间。DQN和离散动作空间在投资组合配置任务中表现较差。在拥有盈利的单智能体基线之前,不要使用复杂的多智能体设置。

如何防止RL交易中的过拟合? #

使用三种技术:(1) 滚动前向分析 — 在顺序不重叠的时间段上训练/验证/测试;(2) 正则化 — 保持网络小型(2个隐藏层,64-128个单元),使用0.2的dropout;(3) 多随机种子 — 用5个不同种子训练5个智能体,集合它们的决策。如果从训练到测试夏普比率下降超过30%,说明你过拟合了。

TensorTrade是否适合高频交易? #

不适合。TensorTrade设计用于分钟到日频的再平衡,而非微秒级交易。环境步骤开销和Python的GIL使其不适用于HFT。对于亚秒级策略,考虑C++框架如QuantLib或专有解决方案。

结论:今天就开始构建你的RL交易系统 #

TensorTrade为Python中的强化学习交易提供了最成熟的生产就绪开源基础。其原生Gym设计、模块化OMS层以及与Stable Baselines3的深度集成,使其成为需要控制训练流程的量化开发者的务实选择。

2026年Q1基准测试显示,使用工程化特征的PPO可以在BTC-USD上实现71.6%的收益和2.34的夏普比率——与机构级趋势跟踪策略相当。关键在于严谨的特征工程、严格的样本外测试和保守的仓位管理。

准备开始了吗?今天就安装TensorTrade,运行上面的5分钟快速设置,加入构建自适应交易系统的开发者社区。如需进行实时加密货币交易,使用BinanceOKX设置测试网账户,无风险验证你的策略。

加入我们的量化开发者Telegram群组:t.me/dibi8quant — 分享你的TensorTrade配置,获取奖励函数的反馈,并随时了解最新的RL交易研究动态。

来源与延伸阅读 #

  1. TensorTrade 官方文档 — https://www.tensortrade.org/
  2. TensorTrade GitHub 仓库 — https://github.com/tensortrade-org/tensortrade
  3. Stable Baselines3 文档 — https://stable-baselines3.readthedocs.io/
  4. “Deep Reinforcement Learning for Trading” by Z. Zhang et al., 2020 — https://arxiv.org/abs/1911.10107
  5. OpenAI Gymnasium 文档 — https://gymnasium.farama.org/
  6. CCXT 交易所库 — https://github.com/ccxt/ccxt
  7. Technical Analysis Library (ta) — https://technical-analysis-library-in-python.readthedocs.io/
  8. “Portfolio Optimization with RL” survey, J. Machine Learning in Finance, 2025

推荐部署与基础设施 #

上述工具想要落地生产,靠谱的基础设施是前提。dibi8 自己也在用的两个选择:

  • DigitalOcean — 新用户 60 天 $200 免费额度,14+ 全球节点。运行开源 AI 工具的首选。
  • HTStack — 香港 VPS,国内访问低延迟,dibi8.com 自己也跑在它上面,生产环境验证过。

Aff 链接 — 不增加你的成本,但能帮 dibi8 持续运营。

联盟营销披露 #

本文包含指向Binance和OKX的联盟链接。如果你通过这些链接注册并交易,我们可能会获得佣金,而你无需支付额外费用。这些佣金有助于资助开源交易工具和教育内容的开发。我们只推荐我们亲自测试和验证过的交易所。在任何交易所存款前,请务必自行调研。

💬 留言讨论