问题描述
如题,本地训练好的 xgboost 模型,怎么在聚宽平台进行回测呢?上传模型权重,k线级别预测买卖信号吗?会不会很慢?
解决方案
在 JoinQuant (聚宽) 平台上使用本地离线训练好的 XGBoost 模型进行回测是完全可行的。整个流程主要包括:上传模型文件、在策略中读取并加载模型、构造特征并进行预测。以下是详细的步骤和性能优化建议:
第一步:上传模型文件到聚宽“研究”环境
- 在本地使用 Python 训练好 XGBoost 模型后,使用
joblib或pickle将模型保存为文件(例如xgb_model.pkl)。 - 登录聚宽平台,进入**“投资研究”**模块。
- 点击上传按钮,将你的
xgb_model.pkl文件上传到研究环境的根目录(或指定文件夹)。
第二步:在回测策略中加载模型
在回测代码中,不能直接使用本地路径读取文件,必须使用聚宽提供的 read_file API。为了避免每次调仓都重新加载模型导致回测极慢,强烈建议将模型加载逻辑放在 process_initialize 或 initialize 函数中。
import jqdata
import pandas as pd
import numpy as np
import xgboost as xgb
import joblib
from six import BytesIO
def initialize(context):
set_benchmark('000300.XSHG')
set_option('use_real_price', True)
g.security = '000001.XSHE'
# 加载模型
load_model(context)
# 每天开盘前运行
run_daily(market_open, time='09:30')
def load_model(context):
# 使用 read_file 读取研究环境中的模型文件
# 注意:如果是 Python3 环境,使用 BytesIO
model_bytes = read_file('xgb_model.pkl')
g.model = joblib.load(BytesIO(model_bytes))
log.info("XGBoost 模型加载成功!")
第三步:在 K 线级别预测买卖信号
在定时运行函数(如 market_open)或 handle_data 中,获取最新的行情数据,构造与训练时完全一致的特征,然后输入模型进行预测。
def market_open(context):
# 1. 获取数据构造特征 (假设模型需要过去5天的收盘价和成交量)
df = attribute_history(g.security, 5, '1d', ['close', 'volume'])
# 2. 构造特征向量 (需与离线训练时的特征工程保持绝对一致)
# 这里仅为示例,实际特征可能更复杂
feature_vector = np.array([[df['close'].mean(), df['volume'].mean()]])
# 3. 模型预测
prediction = g.model.predict(feature_vector)[0]
# 4. 根据信号下单
cash = context.portfolio.available_cash
if prediction == 1 and cash > 0:
order_value(g.security, cash)
log.info("预测信号为1,买入")
elif prediction == 0 and context.portfolio.positions[g.security].closeable_amount > 0:
order_target(g.security, 0)
log.info("预测信号为0,卖出")
关于性能:会不会很慢?
会不会很慢取决于你的代码实现方式。 如果处理不当,确实会非常慢甚至触发超时(聚宽限制每个函数运行不能超过 1800 秒)。请注意以下几点优化技巧:
- 避免重复加载模型:如上文所述,务必在
initialize或process_initialize中只加载一次模型,将其存入全局变量g中。千万不要在handle_data中每次都read_file。 - 批量预测代替循环单条预测:如果你操作的是一个包含几百只股票的股票池,不要在一个
for循环中对每只股票单独调用model.predict()。应该先将所有股票的特征拼接成一个大的pandas.DataFrame或numpy.ndarray,然后一次性调用g.model.predict(features_df)。XGBoost 的批量预测速度极快,而循环单条预测会带来巨大的函数调用开销。 - 特征计算的效率:在回测中实时计算复杂特征(如各种技术指标、滚动窗口统计)是非常耗时的。尽量使用向量化操作(Pandas/Numpy),避免使用低效的 Python 循环。
- 内存限制:聚宽回测环境有 3G 的内存限制。如果你的模型文件非常大(例如几百MB的随机森林或XGBoost),加载到内存中可能会导致 OOM(内存溢出)被系统强杀。建议在离线训练时控制树的深度和数量,或者使用
xgboost原生的.model格式保存和加载,通常比pickle更省内存。
总结来说,只要模型加载一次,并且采用批量特征构造 + 批量预测的方式,在聚宽平台上进行 K 线级别(无论是日线还是分钟线)的 XGBoost 信号预测是完全可以做到高效且流畅的。