EarnHFT 项目迁移计划:BTC → SHFE.ru2605(橡胶期货)

项目概述

将 EarnHFT 分层强化学习高频交易系统从加密货币 BTCUSDT 迁移到上期所橡胶期货 ru2605 合约。

数据范围:2026-01-05 至 2026-01-28(约24天数据)

开发环境conda activate py396,Python 3.9.6


一、橡胶期货RU2605合约规格

参数 说明
交易单位 10吨/手 1手=10吨
最小变动价位 5元/吨 1个点位=50元/手
数据频率 500ms快照 无需resample,直接使用
交易时间 见下方 有夜盘
开仓手续费 3.5元/手 固定费用
平仓手续费 0元/手 平今免费

橡胶期货交易时间(含夜盘)

时段 时间 说明
夜盘 21:00 - 23:00 前一日夜盘
日盘上午 09:00 - 10:15
日盘中场休息 10:15 - 10:30
日盘上午 10:30 - 11:30
午休 11:30 - 13:30
日盘下午 13:30 - 15:00

每日交易时长:5.75小时 = 20700秒 = 41400个500ms快照

  • 夜盘21:00-23:00:2小时
  • 日盘上午09:00-11:30:2小时15分钟(含15分钟休息)
  • 日盘下午13:30-15:00:1.5小时

二、核心配置变更

参数 BTCUSDT 原值 SHFE.ru2605 新值 说明
dataset_name “BTCUSDT” “ru_mm” 数据集名称
max_holding_number 0.01 5.0 最大持仓量(手)
transcation_cost 0.00(比例) 3.5(固定开仓) 开仓3.5元/手,平仓0元
action_dim 5 5 动作维度(0%, 25%, 50%, 75%, 100%)
reward_scale 30 (低层) / 10 (高层) 待调优 奖励缩放因子
gamma 1.0 0.9 折扣因子
data_frequency 1秒 500ms 数据快照频率
chunk_length 14400 41400 数据块大小(每日500ms快照数,5.75小时)

数据处理说明

项目 BTCUSDT SHFE.ru2605
原始数据 1秒快照 500ms快照
Resample 需要处理 无需resample
订单簿数据 1秒级别 直接使用500ms
分钟OHLC 从1秒合成 从500ms合成

三、目录结构规划

D:\quant\earn_hft\
├── ru2605_tick.csv                      # 原始tick数据(2026-01-05 ~ 2026-01-28)
│
├── ru_mm/                               # 新增:ru_mm项目目录
│   ├── data_preprocess/                 # 数据预处理模块
│   │   └── preprocess/
│   │       ├── concat_clean_ru.py       # 新增:ru数据清洗
│   │       ├── create_feature.py        # 复用:特征工程(从原项目复制)
│   │       └── merge_new.py             # 复用:数据合并(从原项目复制)
│   │
│   ├── EarnHFT_Algorithm/              # 算法模块(从原项目复制/修改)
│   │   ├── env/
│   │   │   ├── low_level_env.py         # 修改:固定手续费、gamma=0.9
│   │   │   └── high_level_env.py        # 修改:更新model_path配置
│   │   │
│   │   ├── model/
│   │   │   └── net.py                   # 复用:网络定义
│   │   │
│   │   ├── tool/
│   │   │   └── demonstration.py         # 修改:固定手续费
│   │   │
│   │   ├── RL/
│   │   │   ├── agent/
│   │   │   │   ├── low_level/
│   │   │   │   │   └── ddqn_pes_risk_aware.py  # 复用:低层训练
│   │   │   │   └── high_level/
│   │   │   │       ├── dqn_position.py  # 修改:添加ru_mm配置
│   │   │   │       ├── test_dqn_position.py  # 复用
│   │   │   │       └── test_single_agent.py  # 复用
│   │   │   └── util/
│   │   │       ├── replay_buffer_DQN.py # 复用
│   │   │       ├── episode_selector.py  # 复用
│   │   │       └── graph.py             # 复用
│   │   │
│   │   ├── data/
│   │   │   ├── split_data.py            # 复用:数据分割
│   │   │   └── feature/
│   │   │       ├── second_feature.npy   # 需生成:秒级特征列表
│   │   │       └── minitue_feature.npy  # 需生成:分钟级特征列表
│   │   │
│   │   ├── analysis/
│   │   │   ├── pick_agent/
│   │   │   │   ├── pick_agent.py        # 复用
│   │   │   │   └── pick_agent_position.py # 复用
│   │   │   └── calculate_metric/
│   │   │       └── calculate_metric.py # 复用
│   │   │
│   │   ├── script/                     # 训练脚本
│   │   │   └── ru_mm/                  # 新增:ru_mm训练脚本目录
│   │   │       ├── low_level/
│   │   │       │   ├── train.bat       # 低层训练(Windows批处理,4个beta顺序)
│   │   │       │   └── valid_multi.bat # 验证与选择
│   │   │       └── high_level/
│   │   │           ├── train.bat       # 高层训练
│   │   │           └── test.bat        # 测试
│   │   │
│   │   └── requirements.txt            # Python依赖
│   │
│   ├── data/                           # 数据目录
│   │   └── ru_mm/                      # 新增:ru_mm数据目录
│   │       ├── train/                  # 训练数据块(df_0.feather...)
│   │       ├── train.feather           # 完整训练集
│   │       ├── valid.feather           # 验证集
│   │       └── test.feather            # 测试集
│   │
│   ├── log/                            # 日志目录
│   │   └── train/
│   │       └── ru_mm/
│   │           ├── low_level/          # 低层训练日志
│   │           └── high_level/         # 高层训练日志
│   │
│   └── result_risk/                    # 模型保存目录
│       └── ru_mm/
│           ├── potential_model/        # 低层模型池
│           │   ├── initial_action_0/   # 初始持仓0%
│           │   │   ├── model_0.pth     # beta=100
│           │   │   ├── model_1.pth     # beta=30
│           │   │   ├── model_2.pth     # beta=-10
│           │   │   ├── model_3.pth     # beta=-90
│           │   │   └── model_4.pth     # 选择出的最佳模型
│           │   ├── initial_action_1/   # 初始持仓25%
│           │   ├── initial_action_2/   # 初始持仓50%
│           │   ├── initial_action_3/   # 初始持仓75%
│           │   └── initial_action_4/   # 初始持仓100%
│           └── high_level/             # 高层模型
│               └── seed_12345/
│                   └── trained_model.pkl
│
└── detail.md                          # 原项目文档(参考)

四、实施步骤

阶段1:项目初始化

1.1 创建目录结构
cd D:\quant\earn_hft

# 激活conda环境
conda activate py396

# 创建ru_mm项目目录结构
mkdir ru_mm
cd ru_mm

# 创建子目录
mkdir data_preprocess\preprocess
mkdir data\ru_mm
mkdir data\ru_mm\train
mkdir log\train\ru_mm\low_level
mkdir log\train\ru_mm\high_level
mkdir result_risk\ru_mm

# 复制原有代码文件到ru_mm目录
xcopy ..\EarnHFT_Algorithm EarnHFT_Algorithm\ /E /I
1.2 安装依赖
cd ru_mm\EarnHFT_Algorithm
pip install -r requirements.txt
# 主要依赖:torch, gym, pandas, numpy, pyarrow(feather), tensorboard

阶段2:数据预处理

2.1 数据格式转换脚本

新建文件ru_mm/data_preprocess/preprocess/concat_clean_ru.py

功能

  • 读取 ../ru2605_tick.csv(2026-01-05 ~ 2026-01-28)
  • 字段映射转换:
    SHFE.ru2605.last_price → close(用于生成OHLC)
    SHFE.ru2605.highest → high
    SHFE.ru2605.lowest → low
    SHFE.ru2605.bid_price1-5 → bid1_price-5_price
    SHFE.ru2605.bid_volume1-5 → bid1_size-5_size
    SHFE.ru2605.ask_price1-5 → ask1_price-5_price
    SHFE.ru2605.ask_volume1-5 → ask1_size-5_size
    datetime → timestamp
    
  • 过滤交易时间段(夜盘21:00-23:00 + 日盘)
  • 直接使用500ms快照数据,无需resample
  • 生成 trade_500ms.feather(500ms级别订单簿数据
  • 生成 trade_minitue.feather(从500ms合成分钟级OHLC

输出路径ru_mm/data_preprocess/preprocess/processed_data/ru_mm/2026-01-05-2026-01-28/

执行命令

cd ru_mm\data_preprocess\preprocess
python concat_clean_ru.py

关键代码要点

# 500ms数据直接使用,无需resample
# df已经是500ms快照数据,直接过滤交易时间即可
df = df[df['timestamp'].dt.time.between(...)]  # 过滤交易时段

# 分钟级OHLC从500ms数据合成
minute_ohlc = df.resample('1T').agg({
    'close': 'first',     #开盘
    'high': 'max',        #最高
    'low': 'min',         #最低
    'close': 'last',      #收盘
    'volume': 'sum'
})
2.2 特征工程

文件ru_mm/data_preprocess/preprocess/create_feature.py(从原项目复制)

执行命令

cd ru_mm\data_preprocess\preprocess
python create_feature.py \
    --data_path processed_data/ru_mm/2026-01-05-2026-01-28 \
    --save_path create_features \
    --beat_fee 1e-4

输出:生成带技术指标的特征文件(订单簿特征 + Alpha158类因子)

2.3 数据合并

文件ru_mm/data_preprocess/preprocess/merge_new.py(从原项目复制)

执行命令

python merge_new.py \
    --data_path create_features/ru_mm/2026-01-05-2026-01-28/beatrate_1e-4 \
    --save_path merge

输出ru_mm/data_preprocess/preprocess/merge/ru_mm/2026-01-05-2026-01-28/df.feather

2.4 数据分割

文件ru_mm/EarnHFT_Algorithm/data/split_data.py(从原项目复制,修改chunk_length)

修改内容

# 第18-19行,更新默认参数
parser.add_argument("--chunk_length", type=int, default=41400)  # 原:14400,改为500ms快照数
parser.add_argument("--future_sight", type=int, default=7200)   # 1小时 = 7200个500ms

执行命令

cd ..\..\EarnHFT_Algorithm
python data\split_data.py \
    --data_path ..\data_preprocess\preprocess\merge\ru_mm\2026-01-05-2026-01-28 \
    --chunk_length 41400 \
    --future_sight 7200

输出:60%训练集 / 20%验证集 / 20%测试集

数据量估算

  • 24天 × 41400个500ms快照/天 ≈ 993,600个快照
  • 训练集:60% ≈ 596,160个快照 ≈ 14.4天 ≈ 14个chunk
  • 验证集:20% ≈ 198,720个快照 ≈ 4.8天 ≈ 5个chunk
  • 测试集:20% ≈ 198,720个快照 ≈ 4.8天 ≈ 5个chunk
2.5 生成特征列表

需要运行IC分析或手动创建特征列表文件:

# 创建秒级特征列表(从原始特征中筛选)
# 保存到:EarnHFT_Algorithm/data/feature/second_feature.npy

# 创建分钟级特征列表
# 保存到:EarnHFT_Algorithm/data/feature/minitue_feature.npy

阶段3:代码修改

3.1 低层环境修改(固定手续费)

文件ru_mm/EarnHFT_Algorithm/env/low_level_env.py

修改内容

# 第19-22行,更新默认参数
transcation_cost = 3.5      # 原:0.00(固定开仓费用3.5元/手)
max_holding_number = 5.0    # 原:0.01

关键修改sell_valuebuy_value 方法需要改为固定手续费

# 第63-86行,修改sell_value方法
def sell_value(self, price_information, position):
    # ...(原有计算逻辑)
    # 平仓手续费为0
    self.comission_fee_history.append(0)  # 平仓不收费
    return value, actual_changed_position

# 第88-110行,修改buy_value方法
def buy_value(self, price_information, position):
    # ...(原有计算逻辑)
    # 开仓手续费为3.5元/手 × 手数
    self.comission_fee_history.append(3.5 * (actual_changed_position / self.max_holding_number * 5))
    return value * (1 + 0), actual_changed_position  # 不使用比例费用
3.2 高层环境配置

文件ru_mm/EarnHFT_Algorithm/env/high_level_env.py

修改内容

  • 第29-32行,更新默认参数:
transcation_cost = 3.5      # 固定开仓费用
max_holding_number = 5.0    # 最大持仓量
  • 第41-77行,修改 model_path_list_dict 配置:
model_path_list_dict = {
    0: ["result_risk/ru_mm/potential_model/initial_action_0/model_0.pth", ...],
    1: ["result_risk/ru_mm/potential_model/initial_action_1/model_0.pth", ...],
    2: ["result_risk/ru_mm/potential_model/initial_action_2/model_0.pth", ...],
    3: ["result_risk/ru_mm/potential_model/initial_action_3/model_0.pth", ...],
    4: ["result_risk/ru_mm/potential_model/initial_action_4/model_0.pth", ...],
}
3.3 动态规划Q表计算(固定手续费)

文件ru_mm/EarnHFT_Algorithm/tool/demonstration.py

修改内容

  • make_q_table_reward 函数中的 commission_fee 参数改为固定费用逻辑
  • 开仓时使用3.5元/手,平仓时使用0元
3.4 高层训练脚本

文件ru_mm/EarnHFT_Algorithm/RL/agent/high_level/dqn_position.py

修改内容

  • 第207行附近,添加 ru_mm 到 dataset_name 断言:
assert args.dataset_name in ["BTCUSDT", "ETHUSDT", "GALAUSDT", "BTCTUSD", "ru_mm"]
  • 第360行附近,添加 ru_mm 的 model_path_list_dict 配置:
elif args.dataset_name == "ru_mm":
    model_path_list_dict = {
        0: ["result_risk/ru_mm/potential_model/initial_action_0/model_0.pth", ...],
        1: ["result_risk/ru_mm/potential_model/initial_action_1/model_0.pth", ...],
        2: ["result_risk/ru_mm/potential_model/initial_action_2/model_0.pth", ...],
        3: ["result_risk/ru_mm/potential_model/initial_action_3/model_0.pth", ...],
        4: ["result_risk/ru_mm/potential_model/initial_action_4/model_0.pth", ...],
    }
3.5 gamma参数更新

low_level_env.pyddqn_pes_risk_aware.py 中更新 gamma 默认值为 0.9:

# low_level_env.py Training_Env类
def __init__(self, ..., gamma=0.9, ...):  # 原:gamma=1

# ddqn_pes_risk_aware.py
parser.add_argument("--gamma", type=float, default=0.9, help="the learning rate")

阶段4:训练脚本创建

4.1 低层训练脚本

新建文件ru_mm/EarnHFT_Algorithm/script/ru_mm/low_level/train.bat

@echo off
REM 激活conda环境
call conda activate py396

REM 单GPU顺序训练4个不同beta值的低层代理
REM Beta 100: 高度偏好好行情
echo Training low_level agent with beta=100...
python RL/agent/low_level/ddqn_pes_risk_aware.py ^
    --beta 100 --train_data_path ../../data/ru_mm/train --dataset_name ru_mm ^
    --max_holding_number 5.0 --transcation_cost 3.5 ^
    --reward_scale 30 --num_sample 200 --gamma 0.9 ^
    --buffer_size 100000 --batch_size 256 ^
    >../../log/train/ru_mm/low_level/beta_100.log 2>&1

REM Beta 30: 温和偏好好行情
echo Training low_level agent with beta=30...
python RL/agent/low_level/ddqn_pes_risk_aware.py ^
    --beta 30 --train_data_path ../../data/ru_mm/train --dataset_name ru_mm ^
    --max_holding_number 5.0 --transcation_cost 3.5 ^
    --reward_scale 30 --num_sample 200 --gamma 0.9 ^
    --buffer_size 100000 --batch_size 256 ^
    >../../log/train/ru_mm/low_level/beta_30.log 2>&1

REM Beta -10: 略微风险厌恶
echo Training low_level agent with beta=-10...
python RL/agent/low_level/ddqn_pes_risk_aware.py ^
    --beta -10 --train_data_path ../../data/ru_mm/train --dataset_name ru_mm ^
    --max_holding_number 5.0 --transcation_cost 3.5 ^
    --reward_scale 30 --num_sample 200 --gamma 0.9 ^
    --buffer_size 100000 --batch_size 256 ^
    >../../log/train/ru_mm/low_level/beta_-10.log 2>&1

REM Beta -90: 高度风险厌恶
echo Training low_level agent with beta=-90...
python RL/agent/low_level/ddqn_pes_risk_aware.py ^
    --beta -90 --train_data_path ../../data/ru_mm/train --dataset_name ru_mm ^
    --max_holding_number 5.0 --transcation_cost 3.5 ^
    --reward_scale 30 --num_sample 200 --gamma 0.9 ^
    --buffer_size 100000 --batch_size 256 ^
    >../../log/train/ru_mm/low_level/beta_-90.log 2>&1

echo All low_level training completed!
pause
4.2 验证与代理选择脚本

新建文件ru_mm/EarnHFT_Algorithm/script/ru_mm/low_level/valid_multi.bat

@echo off
call conda activate py396

REM 验证所有训练好的低层模型并选择最佳模型
REM 需要先创建 pick_agent 脚本或手动运行

echo Validating and selecting best models for each initial action...
REM TODO: 实现验证逻辑

echo Validation completed!
pause
4.3 高层训练脚本

新建文件ru_mm/EarnHFT_Algorithm/script/ru_mm/high_level/train.bat

@echo off
call conda activate py396

echo Training high_level agent...
python RL/agent/high_level/dqn_position.py ^
    --train_data_path ../../data/ru_mm/train.feather --dataset_name ru_mm ^
    --max_holding_number 5.0 --transcation_cost 3.5 ^
    --reward_scale 10 --num_sample 100 --gamma 0.9 ^
    --buffer_size 100000 --batch_size 256 ^
    >../../log/train/ru_mm/high_level/log.log 2>&1

echo High_level training completed!
pause
4.4 测试脚本

新建文件ru_mm/EarnHFT_Algorithm/script/ru_mm/high_level/test.bat

@echo off
call conda activate py396

echo Testing complete system...
python RL/agent/high_level/test_dqn_position.py ^
    --test_data_path ../../data/ru_mm/test.feather --dataset_name ru_mm ^
    --max_holding_number 5.0 --transcation_cost 3.5 ^
    --model_path ../../result_risk/ru_mm/high_level/seed_12345/trained_model.pkl
pause

阶段5:执行流程

# ========== 步骤1:项目初始化 ==========
cd D:\quant\earn_hft
conda activate py396
mkdir ru_mm
cd ru_mm

# 复制代码框架
xcopy ..\EarnHFT_Algorithm EarnHFT_Algorithm\ /E /I
mkdir data\ru_mm\train
mkdir log\train\ru_mm\low_level
mkdir log\train\ru_mm\high_level
mkdir result_risk\ru_mm

# ========== 步骤2:数据预处理 ==========
cd data_preprocess
mkdir preprocess
cd preprocess

# 运行数据清洗脚本
python concat_clean_ru.py

# 运行特征工程
python create_feature.py --data_path processed_data/ru_mm/2026-01-05-2026-01-28

# 运行数据合并
python merge_new.py --data_path create_features/ru_mm/2026-01-05-2026-01-28/beatrate_1e-4

# ========== 步骤3:数据分割 ==========
cd ..\..\EarnHFT_Algorithm
python data\split_data.py --data_path ..\data_preprocess\preprocess\merge\ru_mm\2026-01-05-2026-01-28

# ========== 步骤4:低层代理训练 ==========
cd script\ru_mm\low_level
train.bat

# ========== 步骤5:验证与选择 ==========
# 手动检查训练结果,选择最佳模型
# 复制模型到 result_risk/ru_mm/potential_model/initial_action_X/

# ========== 步骤6:高层代理训练 ==========
cd ..\high_level
train.bat

# ========== 步骤7:系统测试 ==========
test.bat

五、固定手续费实现细节

5.1 手续费规则

操作 费用 计算
开仓 3.5元/手 3.5 × 手数
平仓 0元/手 0

5.2 代码实现要点

原项目使用比例手续费,需要修改为固定手续费

原代码(比例):

# 开仓
value = value * (1 + commission_fee)  # commission_fee = 0.00
# 平仓
value = value * (1 - commission_fee)

新代码(固定):

# 开仓:添加固定费用
fixed_cost = 3.5 * num_contracts
self.comission_fee_history.append(fixed_cost)
return value + fixed_cost, actual_changed_position

# 平仓:无费用
self.comission_fee_history.append(0)
return value, actual_changed_position

六、数据时间处理

6.1 夜盘跨日处理

橡胶期货夜盘(21:00-23:00)在日历上属于"前一日",但交易逻辑上属于"当日":

  • 建议按交易日划分:夜盘+日盘为同一个交易日
  • 时间戳统一使用 datetime 类型,方便后续处理

6.2 非交易时段处理

需要过滤的时间段:

  • 00:00 - 09:00(休息)
  • 10:15 - 10:30(中场休息)
  • 11:30 - 13:30(午休)
  • 15:00 - 21:00(休市)

七、需要修改/创建的文件清单

文件路径 操作 说明
ru_mm/data_preprocess/preprocess/concat_clean_ru.py 新建 ru数据清洗与格式转换
ru_mm/data_preprocess/preprocess/create_feature.py 复制 特征工程
ru_mm/data_preprocess/preprocess/merge_new.py 复制 数据合并
ru_mm/EarnHFT_Algorithm/env/low_level_env.py 修改 固定手续费、gamma=0.9、max_holding=5.0
ru_mm/EarnHFT_Algorithm/env/high_level_env.py 修改 更新model_path配置
ru_mm/EarnHFT_Algorithm/tool/demonstration.py 修改 固定手续费逻辑
ru_mm/EarnHFT_Algorithm/RL/agent/high_level/dqn_position.py 修改 添加ru_mm配置
ru_mm/EarnHFT_Algorithm/data/split_data.py 修改 chunk_length=17100
ru_mm/EarnHFT_Algorithm/script/ru_mm/low_level/train.bat 新建 低层训练脚本
ru_mm/EarnHFT_Algorithm/script/ru_mm/high_level/train.bat 新建 高层训练脚本
ru_mm/EarnHFT_Algorithm/script/ru_mm/high_level/test.bat 新建 测试脚本
ru_mm/EarnHFT_Algorithm/data/feature/second_feature.npy 生成 秒级特征列表
ru_mm/EarnHFT_Algorithm/data/feature/minitue_feature.npy 生成 分钟级特征列表

八、验证检查点

8.1 数据检查

  • ru2605_tick.csv 读取正常,数据时间范围正确
  • 字段映射正确(bid/ask price/volume)
  • 交易时间段过滤正确(含夜盘)
  • 降采样后数据无缺失

8.2 特征检查

  • 特征工程无报错
  • second_feature.npy 和 minitue_feature.npy 已生成
  • 特征数量合理(建议50-200个)

8.3 环境检查

  • low_level_env 可正常实例化
  • 固定手续费计算正确
  • gamma=0.9 正确设置
  • high_level_env 可正常加载低层模型

8.4 训练检查

  • 4个beta的训练均正常启动
  • TensorBoard日志正常记录
  • 模型保存路径正确

8.5 结果检查

  • 低层模型收敛(loss下降)
  • 高层模型训练完成
  • 回测收益率合理
  • 手续费计算正确

九、预期工作量

阶段 工作内容 预计时间
项目初始化 创建目录、复制代码、安装依赖 30分钟
数据预处理 开发concat_clean_ru.py、特征工程 2-3小时
代码修改 修改手续费逻辑、gamma配置 1-2小时
训练脚本 创建bat脚本 30分钟
训练执行 低层+高层训练 数小时
调试优化 根据结果调参 根据实际情况
总计 约半天到1天

十、风险与注意事项

  1. 数据量限制:24天数据可能不够充分,建议监控训练效果,必要时补充更多历史数据
  2. 手续费影响:固定手续费可能使高频策略成本较高,建议降低交易频率
  3. 夜盘跨日:需正确处理夜盘与日盘的日期归属
  4. 过拟合风险:数据量有限,需注意模型泛化能力
  5. reward_scale调优:橡胶价格波动与BTC不同,可能需要调整奖励缩放

EarnHFT 项目详解:分层强化学习高频交易系统

一、项目概述

EarnHFT 是发表在 AAAI 2024 的一篇论文的实现项目,标题为 “Efficient Hierarchical Reinforcement Learning for High Frequency Trading”(高频交易的高效分层强化学习)。

论文链接:https://arxiv.org/pdf/2309.12891.pdf

官方GitHub:https://github.com/qinmoelei/EarnHFT

核心创新点

本项目提出了**分层强化学习(HRL)**框架来解决高频交易问题:

  • 高层代理(High-level Agent):在分钟级别运行,负责选择合适的低级代理
  • 低层代理(Low-level Agent):在秒级别运行,负责具体的仓位管理决策

这种分层设计解决了高频交易中的两个核心挑战:

  1. 高维状态空间:每秒的市场状态变化剧烈
  2. 长期信用分配:交易决策的收益需要较长时间才能体现

二、整体架构图

┌─────────────────────────────────────────────────────────────────┐
│                        高级环境 (Minute Level)                    │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  High-Level DQN Agent                                    │   │
│  │  - 输入:分钟级特征 + 当前持仓                            │   │
│  │  - 输出:选择哪个低层代理 (5个选择)                        │   │
│  │  - 奖励:1分钟内所有低层代理的累积收益                     │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
                              │
                    选择低层代理池中的某个代理
                              │
┌─────────────────────────────────────────────────────────────────┐
│                        低级环境 (Second Level)                    │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  Low-Level DDQN Agent (多个,不同beta偏好)               │   │
│  │  - 输入:秒级特征 + 上一动作 + 可用动作掩码               │   │
│  │  - 输出:5维动作 (持仓比例 0%, 25%, 50%, 75%, 100%)       │   │
│  │  - 奖励:即时收益 + 未来价值 (Q-Table引导)                │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

三、论文核心逻辑详解

3.1 问题建模

将高频交易建模为马尔可夫决策过程(MDP):

  • 状态空间 S:市场状态特征(订单簿 + 技术指标)
  • 动作空间 A:持仓比例调整(0%, 25%, 50%, 75%, 100%)
  • 奖励函数 R:基于持仓价值变化
  • 转移函数 P:市场动态

3.2 分层强化学习的必要性

为什么需要分层?

  1. 时间尺度分离

    • 低层:秒级决策,需要快速响应市场变化
    • 高层:分钟级决策,关注市场趋势
  2. 信用分配缓解

    • 低层代理的奖励由动态规划Q-Table预计算引导
    • 高层代理关注长期的代理选择决策
  3. 策略多样性

    • 训练多个具有不同风险偏好的低层代理
    • 高层学习在不同市场环境下选择合适的代理

3.3 动态规划Q-Table初始化(核心创新)

论文使用动态规划预计算Q值作为RL训练的引导:

数学公式

Q[t][prev_action][curr_action] = 即时奖励 + γ × max(Q[t+1][curr_action][:])

核心思想

  • 从最后一个时间步开始倒推
  • 每个Q值表示:在t时刻,给定前一动作prev_action,选择当前动作curr_action的期望累积收益
  • 这相当于"作弊"地告诉智能体最优策略应该是什么样的

作用

  1. 加速收敛:智能体从"好的起点"开始学习
  2. 解决信用分配:即时奖励可能很小,但长期来看是最优的决策
  3. 提供演示信号:通过KL散度让智能体模仿最优策略

论文逻辑:数据从 Tardis 下载,包含5档订单簿快照和交易记录

代码实现 (data_preprocess/):

# 数据预处理流程
1. download_code/download.sh - 从Tardis下载原始数据
2. preprocess/concat_clean.sh - 数据清洗和降采样
3. preprocess/create_feature.sh - 创建特征
4. preprocess/merge_new.sh - 合并特征
5. ic_analysis/calculate_ic.sh - 计算IC选择优质特征

数据流程详解

  1. 订单簿快照 (book_snapshot_5):包含5档买卖挂单详情
  2. 交易记录 (trades):实时成交记录

经过预处理后生成:

  • orderbook.feather:秒级订单簿数据
  • trade_second.feather:秒级OHLC数据
  • trade_minitue.feather:分钟级OHLC数据

2. 低层环境(Second-level Trading)

论文逻辑:低层代理在每秒级别做决策,学习在特定市场环境下如何调整仓位

代码实现 (EarnHFT_Algorithm/env/low_level_env.py):

class Testing_env(gym.Env):
    def __init__(self, df, tech_indicator_list, transcation_cost,
                 back_time_length, max_holding_number, action_dim):
        self.action_dim = action_dim  # 5个离散动作
        self.action_space = spaces.Discrete(action_dim)  # 0-4
        self.max_holding_number = max_holding_number  # 最大持仓
        self.observation_space = spaces.Box(
            low=-np.inf, high=+np.inf,
            shape=(back_time_length * len(self.tech_indicator_list),))

关键函数

def sell_value(self, price_information, position):
    """计算卖出价值 - 考虑订单簿深度"""
    value = 0
    for i in range(1, 6):
        if position < price_information["bid{}_size".format(i)]:
            break
        value += price_information["bid{}_price".format(i)] * \
                 price_information["bid{}_size".format(i)]
    return value * (1 - self.comission_fee)

def buy_value(self, price_information, position):
    """计算买入成本 - 考虑订单簿深度"""
    value = 0
    for i in range(1, 6):
        if position < price_information["ask{}_size".format(i)]:
            break
        value += price_information["ask{}_price".format(i)] * \
                 price_information["ask{}_size".format(i)]
    return value * (1 + self.comission_fee)

3. 动态规划 Q-Table 初始化(论文创新点)

论文逻辑:使用动态规划预计算Q值作为RL训练的引导,加速收敛

代码实现 (EarnHFT_Algorithm/tool/demonstration.py):

def make_q_table_reward(df, num_action, max_holding, reward_scale,
                        gamma, commission_fee, max_punish):
    """
    使用动态规划预计算 Q-Table
    Q[t][prev_action][curr_action] = 即时奖励 + γ × max(Q[t+1][curr_action][:])
    """
    q_table = np.zeros((len(df), num_action, num_action))

    # 从后往前倒推计算Q值
    for t in range(2, len(df) + 1):
        current_price = df.iloc[-t]
        future_price = df.iloc[-t + 1]

        for previous_action in range(num_action):
            for current_action in range(num_action):
                # 买入情况
                if current_action > previous_action:
                    position_change = (current_action - previous_action) / scale_factor * max_holding
                    reward = future_value - (current_value + buy_money)
                # 卖出/持仓情况
                else:
                    position_change = (previous_action - current_action) / scale_factor * max_holding
                    reward = future_value + sell_money - current_value

                # Q值 = 即时奖励 × 奖励缩放 + γ × 下一时刻最大Q值
                q_table[len(df)-t][previous_action][current_action] = \
                    reward * reward_scale + gamma * np.max(q_table[len(df)-t+1][current_action][:])
    return q_table

4.4 低层代理训练(DDQN + PES + KL散度)

代码实现 (EarnHFT_Algorithm/RL/agent/low_level/ddqn_pes_risk_aware.py):

核心特性

  1. DDQN(双DQN):使用当前网络选动作,目标网络算Q值
  2. PES(优先级经验回放):根据收益分布选择训练样本
  3. KL散度约束:模仿动态规划Q-Table的最优策略
class DQN(object):
    def __init__(self, args):
        # PES优先级转换函数
        self.beta = args.beta
        self.type = args.type  # "even", "sigmoid", "boltzmann"
        if self.type == "even":
            self.priority_transformation = get_transformation_even_risk
        elif self.type == "sigmoid":
            self.priority_transformation = get_transformation_even_based_sigmoid_risk
        elif self.type == "boltzmann":
            self.priority_transformation = get_transformation_even_based_boltzmann_risk
        
        # 网络结构
        self.eval_net = Qnet(self.n_state, self.action_dim, self.hidden_nodes).to(self.device)
        self.target_net = copy.deepcopy(self.eval_net)
    
    def update(self, states, info, actions, rewards, next_states, info_, dones):
        """DDQN更新 + KL散度约束"""
        b = states.shape[0]
        
        # 1. DDQN:计算当前网络选动作的Q值
        q_eval = self.eval_net(
            states.reshape(b, -1),
            info["previous_action"].float().unsqueeze(1),
            info["avaliable_action"],
        ).gather(1, actions)
        
        # 2. 目标网络计算Q值(detach不计算梯度)
        q_next = self.target_net(
            next_states.reshape(b, -1),
            info_["previous_action"].float().unsqueeze(1),
            info_["avaliable_action"],
        ).detach()
        
        # 3. Q目标 = 即时奖励 + γ × 下一状态最大Q值
        q_target = rewards + torch.max(q_next, 1)[0].view(self.batch_size, 1) * (1 - dones)
        
        # 4. TD误差
        td_error = self.loss_func(q_eval, q_target)
        
        # 5. KL散度:让智能体模仿动态规划的最优策略
        demonstration = info["q_value"]  # 预计算的Q-Table值
        predict_action_distrbution = self.eval_net(...)
        
        KL_div = F.kl_div(
            (predict_action_distrbution.softmax(dim=-1) + 1e-8).log(),
            (demonstration.softmax(dim=-1) + 1e-8),
            reduction="batchmean",
        )
        
        # 6. 总损失 = TD误差 + KL散度 × ada系数
        loss = td_error + KL_div * self.ada
        
        # 7. 反向传播 + 梯度裁剪
        self.optimizer.zero_grad()
        loss.backward()
        torch.nn.utils.clip_grad_norm_(self.eval_net.parameters(), self.grad_clip)
        self.optimizer.step()
        
        # 8. 软更新目标网络
        for param, target_param in zip(self.eval_net.parameters(), self.target_net.parameters()):
            target_param.data.copy_(self.tau * param.data + (1-self.tau) * target_param.data)

训练流程

def train(self):
    # 1. 初始化PES采样器
    for i in range(df_number):
        df = pd.read_feather(...)
        # 计算每个chunk的收益率
        return_rate_list.append(df.iloc[self.chunk_num]["bid1_price"] / df.iloc[0]["ask1_price"] - 1)
    
    initial_priority_list = self.priority_transformation(return_rate_list, beta=self.beta)
    self.start_selector = start_selector(range(df_number), initial_priority_list)
    
    # 2. 双经验回放缓冲区
    replay_buffer_perfect = Multi_step_ReplayBuffer_multi_info(...)  # 使用最优策略采样
    replay_buffer_normal = Multi_step_ReplayBuffer_multi_info(...)  # 正常探索采样
    
    for sample in range(self.num_sample):
        # 使用PES选择训练样本
        df_index = self.start_selector.sample()[0]
        self.train_df = pd.read_feather(...)
        
        # 3. 第一阶段:使用预计算的Q-Table(最优策略)训练
        train_env = Training_Env(...)
        s, info = train_env.reset()
        while True:
            a = self.act_perfect(info)  # 直接使用Q-Table的最大值作为动作
            s_, r, done, info_ = train_env.step(a)
            replay_buffer_perfect.add(s, info, a, r, s_, info_, done)
            if done:
                break
        
        # 4. 第二阶段:使用探索策略训练
        train_env = Training_Env(...)
        s, info = train_env.reset()
        while True:
            a = self.act(s, info, self.epsilon)  # ε-贪婪探索
            s_, r, done, info_ = train_env.step(a)
            replay_buffer_normal.add(s, info, a, r, s_, info_, done)
            
            # 5. 训练更新
            if step_counter > batch_size and step_counter % target_freq == 1:
                for _ in range(self.update_times):
                    states, infos, actions, rewards, ... = replay_buffer_normal.sample()
                    self.update(states, infos, actions, rewards, ...)
            if done:
                break

5. 低层代理池构建(Comprehensive Evaluation)

代码实现 (EarnHFT_Algorithm/analysis/pick_agent/pick_agent.py):

def get_best_model(label_name, root_path):
    """评估所有低层代理,按收益排序选择"""
    result_dict = {}
    for coffient in coffient_list:
        for epoch in epoch_list:
            target_path = os.path.join(epoch_path, "valid_multi", label_name)
            return_rate = final_balance / required_money
            result_dict["{}_{}".format(coffient, epoch)] = {
                "average_return_rate": np.mean(return_rate_list),
            }
    return find_max_average_return_rate(result_dict)

if __name__ == "__main__":
    save_path = "result_risk/BTCUSDT/potential_model"
    for i in range(5):
        index_model = get_best_model(label_name="label_{}".format(i))
        model_path_list.append(best_model_path)

6. 高层环境(Minute-level Agent Selection)

代码实现 (EarnHFT_Algorithm/env/high_level_env.py):

class high_level_testing_env(Testing_env):
    def __init__(self, df, model_path_list_dict):
        self.low_level_agent_list_dict = {}
        for key in model_path_list_dict:
            self.low_level_agent_list_dict[key] = []
            for model_path in model_path_list_dict[key]:
                model = Qnet(...).to("cpu")
                model.load_state_dict(torch.load(model_path))
                self.low_level_agent_list_dict[key].append(model)
        self.action_space = spaces.Discrete(5)

    def step(self, macro_action):
        current_position_level = int(self.position / step)
        self.chosen_model = self.low_level_agent_list_dict[current_position_level][macro_action]
        reward_mintue = 0
        while self.data.iloc[-1].timestamp.second != 59:
            macro_action = self.pose_macro_action(self.state, self.info)
            self.state, reward, done, self.info = super().step(macro_action)
            reward_mintue += reward
        return self.state, reward_mintue, done, self.info

7. 高层代理训练

代码实现 (EarnHFT_Algorithm/RL/agent/high_level/dqn.py):

class DQN(object):
    def update(self, info, actions, rewards, info_, dones):
        q_eval = self.eval_net(torch.squeeze(info["high_level_state"])).gather(1, actions)
        q_next = self.target_net(torch.squeeze(info_["high_level_state"])).detach()
        q_target = rewards + torch.max(q_next, 1)[0] * (1-dones) * self.gamma
        td_error = self.loss_func(q_eval, q_target)
        
        self.optimizer.zero_grad()
        td_error.backward()
        torch.nn.utils.clip_grad_norm_(self.eval_net.parameters(), self.grad_clip)
        self.optimizer.step()

        for param, target_param in zip(self.eval_net.parameters(), self.target_net.parameters()):
            target_param.data.copy_(self.tau * param.data + (1-self.tau) * target_param.data)

4.8 经验回放缓冲区

代码实现 (EarnHFT_Algorithm/RL/util/replay_buffer_DQN.py):

class Multi_step_ReplayBuffer_multi_info:
    """多步经验回放缓冲区"""
    
    def __init__(self, buffer_size, batch_size, device, seed, gamma, n_step):
        self.buffer_size = buffer_size
        self.gamma = gamma  # 折扣因子
        self.n_step = n_step  # n步回报
        self.n_step_buffer = deque(maxlen=n_step)
    
    def add(self, state, info, action, reward, next_state, next_info, done):
        """添加经验到缓冲区"""
        self.n_step_buffer.append((state, info, action, reward, next_state, next_info, done))
        
        if len(self.n_step_buffer) == self.n_step:
            transition = self.calc_multistep_return(self.n_step_buffer)
            self.memory.append(transition)
    
    def calc_multistep_return(self, n_step_buffer):
        """计算n步回报"""
        Return = 0
        for i in range(self.n_step):
            Return += self.gamma ** i * n_step_buffer[i][3]  # 累加折扣奖励
        return (
            n_step_buffer[0][0],  # 初始状态
            n_step_buffer[0][1],  # 初始info
            n_step_buffer[0][2],  # 动作
            Return,               # n步回报
            n_step_buffer[-1][4],  # 最后一个状态
            n_step_buffer[-1][5],  # 最后一个info
            n_step_buffer[-1][6],  # 最后一个done
        )
    
    def sample(self):
        """随机采样一批经验"""
        experiences = random.sample(self.memory, k=self.batch_size)
        # 转换为tensor并移动到指定设备
        ...
        return (states, infos, actions, rewards, next_states, next_infos, dones)

五、完整训练流程

┌─────────────────────────────────────────────────────────────────┐
│                      步骤1: 数据预处理                           │
├─────────────────────────────────────────────────────────────────┤
│  1.1 下载订单簿快照 + 交易数据 (Tardis API)                       │
│  1.2 数据清洗:秒级/分钟级聚合                                    │
│  1.3 特征工程:创建技术指标特征                                    │
│  1.4 IC分析:筛选优质特征                                         │
│      - second_feature.npy: 低层代理特征 (秒级)                    │
│      - minitue_feature.npy: 高层代理特征 (分钟级)                 │
│  1.5 数据分割:60%训练 / 20%验证 / 20%测试                        │
│  1.6 训练集分块:每块14400秒,避免内存溢出                         │
└─────────────────────────────────────────────────────────────────┘
                                 ↓
┌─────────────────────────────────────────────────────────────────┐
│                    步骤2: 低层代理训练                            │
├─────────────────────────────────────────────────────────────────┤
│  2.1 预计算Q-Table (动态规划)                                     │
│  2.2 使用不同beta参数训练多个DDQN代理:                           │
│      - beta = 100: 高度偏好好行情                                 │
│      - beta = 30: 温和偏好好行情                                  │
│      - beta = -10: 略微风险厌恶                                   │
│      - beta = -90: 高度风险厌恶                                   │
│  2.3 训练过程:                                                   │
│      - 第一阶段:使用Q-Table引导(模仿最优策略)                   │
│      - 第二阶段:ε-贪婪探索 + 经验回放                            │
│      - KL散度约束:保持与Q-Table一致                              │
│  2.4 输出:result_risk/{dataset}/beta_XX/.../trained_model.pkl   │
└─────────────────────────────────────────────────────────────────┘
                                 ↓
┌─────────────────────────────────────────────────────────────────┐
│                   步骤3: 低层代理综合评估                          │
├─────────────────────────────────────────────────────────────────┤
│  3.1 在验证集上评估所有低层代理                                    │
│  3.2 按市场状态分类评估 (label_0 ~ label_4):                     │
│      - 基于斜率/分位数划分5种市场环境                              │
│  3.3 计算指标:                                                   │
│      - 原始收益率:final_balance / required_money                 │
│      - 归一化收益率:收益率 / 交易次数                             │
│  3.4 选择每个状态下的最佳代理                                      │
└─────────────────────────────────────────────────────────────────┘
                                 ↓
┌─────────────────────────────────────────────────────────────────┐
│                    步骤4: 构建代理池                              │
├─────────────────────────────────────────────────────────────────┤
│  4.1 将选中的低层代理保存到代理池                                  │
│  4.2 代理池结构:                                                 │
│      potential_model/                                            │
│      ├── initial_action_0/                                       │
│      │   ├── model_0.pth                                        │
│      │   └── ...                                                │
│      ├── initial_action_1/                                       │
│      └── ...                                                     │
└─────────────────────────────────────────────────────────────────┘
                                 ↓
┌─────────────────────────────────────────────────────────────────┐
│                    步骤5: 高层代理训练                            │
├─────────────────────────────────────────────────────────────────┤
│  5.1 加载低层代理池                                               │
│  5.2 高层环境:每分钟调用一次低层代理                              │
│  5.3 高层DQN学习:选择能带来长期收益的低层代理                     │
│  5.4 输出:result_risk/{dataset}/high_level/.../trained_model.pkl│
└─────────────────────────────────────────────────────────────────┘
                                 ↓
┌─────────────────────────────────────────────────────────────────┐
│                    步骤6: 测试与评估                              │
├─────────────────────────────────────────────────────────────────┤
│  6.1 在测试集上运行完整系统                                       │
│  6.2 生成回测报告和收益曲线图                                     │
│  6.3 计算指标:收益率、夏普比率、最大回撤等                        │
└─────────────────────────────────────────────────────────────────┘

六、关键超参数说明

参数 说明 默认值 作用
action_dim 动作维度 5 0%, 25%, 50%, 75%, 100% 持仓
max_holding_number 最大持仓 0.01 (BTC) 决定仓位管理的粒度
back_time_length 历史状态长度 1 使用多少历史时间步
beta PES偏好参数 -90, -10, 30, 100 控制对不同收益分布的偏好
gamma 折扣因子 1.0 远期奖励的重要性
epsilon_init 初始探索率 0.9 初始随机探索概率
epsilon_min 最小探索率 0.3 保持一定的探索能力
batch_size 批次大小 512 每次更新的样本数
lr_init 初始学习率 1e-2 模型收敛速度
reward_scale 奖励缩放 30 稳定训练过程
tau 软更新系数 0.005 目标网络更新速度
ada KL系数 256→128 KL散度约束强度

七、论文贡献点总结

7.1 核心创新

  1. 分层强化学习框架

    • 将高频交易分解为高层(策略选择)和低层(执行)两个时间尺度
    • 高层在分钟级别,低层在秒级别
    • 解决了高频环境下状态空间爆炸和信用分配问题
  2. 动态规划Q-Table预训练

    • 使用后向递推计算理论最优Q值
    • 作为RL训练的引导信号,加速收敛
    • 通过KL散度让智能体模仿最优策略
  3. 代理池机制

    • 训练多个具有不同风险偏好的低层代理
    • 在验证集上评估并选择最佳代理
    • 高层代理学习"何时使用哪个代理"
  4. 流动性约束的动作空间

    • 基于订单簿深度动态限制可执行动作
    • 避免模拟执行与真实市场脱节
    • 更贴近实际交易约束

7.2 实践意义

  • 解决了RL在高频领域的两个核心挑战:状态爆炸和信用分配
  • 模块化设计:可灵活替换低层代理或调整高层策略
  • 可解释性:通过代理池选择,可以分析高层决策的偏好

七、运行指南

环境配置

conda create -n earnhft python=3.7
conda activate earnhft
pip install -r EarnHFT_Algorithm/requirements.txt

训练流程

# 1. 数据预处理
cd data_preprocess
bash preprocess/concat_clean.sh
bash preprocess/create_feature.sh
bash preprocess/merge_new.sh
bash ic_analysis/calculate_ic.sh

# 2. 低层代理训练
cd ../EarnHFT_Algorithm
bash script/BTCUSDT/low_level/train.sh

# 3. 低层代理评估
bash script/BTCUSDT/low_level/valid_multi.sh

# 4. 策略选择
python analysis/pick_agent/pick_agent.py

# 5. 高层代理训练
bash script/BTCUSDT/high_level/train.sh

# 6. 测试
bash script/BTCUSDT/high_level/test.sh

八、文件结构

earn_hft/
├── 2309.12891v1.pdf              # 原始论文
├── README.md                      # 项目说明
├── detail.md                      # 本文档
│
├── data_preprocess/               # 数据预处理
│   ├── download_code/             # 数据下载
│   │   ├── download.py
│   │   └── download.sh
│   ├── preprocess/                # 数据清洗和聚合
│   │   ├── concat_clean.py
│   │   ├── create_feature.py
│   │   └── merge_new.py
│   ├── ic_analysis/               # 特征选择
│   │   ├── calculate_ic.py
│   │   └── feature/               # 筛选后的特征
│   │       ├── second_feature.npy
│   │       └── minitue_feature.npy
│   └── pic/                       # 数据结构图
│
└── EarnHFT_Algorithm/             # 核心算法
    ├── env/                       # 强化学习环境
    │   ├── low_level_env.py       # 低层环境(秒级)
    │   ├── high_level_env.py      # 高层环境(分钟级)
    │   └── test_env.py            # 测试环境
    │
    ├── model/                     # 神经网络模型
    │   └── net.py                 # Qnet, Actor, Critic等
    │
    ├── RL/                        # 强化学习算法
    │   ├── agent/
    │   │   ├── base/              # 基础算法实现
    │   │   │   ├── dqn_train.py
    │   │   │   ├── dqn_test.py
    │   │   │   └── ...
    │   │   ├── high_level/        # 高层代理
    │   │   │   ├── dqn.py
    │   │   │   └── dqn_position.py
    │   │   └── low_level/         # 低层代理
    │   │       └── ddqn_pes_risk_aware.py
    │   └── util/                  # 工具函数
    │       ├── replay_buffer_DQN.py  # 经验回放
    │       ├── graph.py              # 可视化
    │       └── episode_selector.py   # PES采样
    │
    ├── tool/                      # 工具函数
    │   ├── demonstration.py       # 动态规划Q-Table
    │   ├── label_util.py          # 市场状态标注
    │   └── market_dynamics_modeling_analysis.py
    │
    ├── analysis/                  # 分析工具
    │   ├── pick_agent/            # 策略选择
    │   │   └── pick_agent.py
    │   └── calculate_metric/      # 指标计算
    │
    ├── comprehensive_evaluation/  # 综合评估
    │   ├── analyzer.py
    │   └── slice_model.py
    │
    ├── data/                      # 数据处理
    │   ├── split_data.py
    │   └── split.sh
    │
    ├── script/                    # 训练脚本
    │   ├── BTCUSDT/
    │   │   ├── low_level/
    │   │   │   ├── train.sh
    │   │   │   └── valid_multi.sh
    │   │   └── high_level/
    │   │       ├── train.sh
    │   │       ├── pick.sh
    │   │       └── test.sh
    │   ├── ETHUSDT/
    │   └── GALAUSDT/
    │
    └── requirements.txt           # Python依赖

九、参考资源

  1. 论文原文:https://arxiv.org/pdf/2309.12891.pdf
  2. 官方GitHub:https://github.com/qinmoelei/EarnHFT
  3. Tardis API:https://tardis.dev/ (加密货币数据源)
  4. 相关论文
    • EIIE: “Deep reinforcement learning for automated stock trading”
    • Alpha158: 微软Qlib的特征工程方法
  5. 代码参考
    • https://github.com/Lizhi-sjtu/DRL-code-pytorch/tree/main/3.Rainbow_DQN
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐