FreqAI数据流水线实战:K线变PyTorch张量要闯的5道关(附完整代码与坑位)
FreqAI数据流水线实战K线变PyTorch张量要闯的5道关附完整代码与坑位【免费下载链接】freqtradeFree, open source crypto trading bot项目地址: https://gitcode.com/GitHub_Trending/fr/freqtrade回测刚跑起来模型就因为一堆 NaN 直接崩了或者更隐蔽——回测收益好得离谱实盘却一路打脸。十有八九是数据在进场—认列—切时间—加工—转张量这条路上被人动了手脚。这篇文章带你把 Freqtrade 的 FreqAI 模块当成一条闯关流水线逐关拆解它如何把原始 K 线变成 PyTorch 模型能直接吃的特征张量每一关都给出仓库里的真实代码位置和可抄的配置。全景图一条流水线4 个关卡加 1 个验收点先别急着看代码。你写好的特征列从策略的feature_engineering_standard()出来之后会依次经过下面 5 个节点任何一关不过后面的模型训练都是空中楼阁关卡一·数据进场NaN 和 Inf 清洗data_kitchen.py 的filter_features关卡二·自动认列按%/暗号识别特征和标签find_features/find_labels关卡三·时间切割滑动窗口切出训练窗 紧随的测试窗序列split_timerange关卡四·管道加工去常量、标准化、PCA 降维、DBSCAN 去离群freqai_interface.py 的define_data_pipeline验收点·张量出炉DataFrame 变 float32 张量装进 DataLoader 喂给模型freqtrade/freqai/torch/ 目录这张图对应 FreqAI 官方的算法流程数据从策略层流入经过 DataKitchen 的清洗与切窗模型在窗口上反复训练与预测。下面逐关过。关卡一数据进场NaN 该删行还是填 0取决于你处于哪个模式你以为 NaN 就是个脏数据删掉就完事了FreqAI 的分寸感恰恰在这里——训练和预测两种模式下同一行 NaN 的待遇完全不同。关键在 data_kitchen.py 第 233-283 行的filter_features# 来源freqtrade/freqai/data_kitchen.py:233-283 filtered_df unfiltered_df.filter(training_feature_list, axis1) filtered_df filtered_df.replace([np.inf, -np.inf], np.nan) # Inf 先归一成 NaN统一判据 drop_index pd.isnull(filtered_df).any(axis1) # 标出任何一格为 NaN 的行 if training_filter: filtered_df filtered_df[drop_index 0] # 训练模式直接删行样本纯度优先 labels labels[(drop_index 0) (drop_index_labels 0)] else: filtered_df.fillna(0, inplaceTrue) # 预测模式填 0 保住行数 self.do_predict np.array((~drop_index).astype(int)) # 打标记这行不许出预测为什么预测模式不删行因为预测结果要按date拼回策略的原始 DataFrame行数必须一一对齐。填 0 只是占位真正的保护是do_predict这个 0/1 掩码——含 NaN 的 K 线不会触发买入。更狠的一层保险如果训练数据被 NaN 全删光非实盘模式会直接抛OperationalException并提示你数据下载量不足而不是静默地产出一个空模型。关卡二自动认列% 是特征 是标签找不到就报错不用手动维护特征列表这件事是 FreqAI 对新手最友好的设计。你在策略里写dataframe[%rsi_7]、dataframe[price-change-7]流水线就会自动把它们归位。认列逻辑在 data_kitchen.py 第 387-405 行核心就是两行列表推导# 来源freqtrade/freqai/data_kitchen.py:387-405 column_names dataframe.columns features [c for c in column_names if % in c] # % 前缀 特征列 if not features: raise OperationalException(Could not find any features!) # 一个都找不到直接报错 self.training_features_list featuresfind_labels同理用前缀抓标签列存进self.label_list。注意这里的暗号约定是包含即命中% in c所以特征名千万别乱用百分号当普通字符。还有一个隐藏约定%%开头的列fill_predictions第 446 行会被识别为给用户看的透传列不参与训练方便你把自定义指标带回 FreqUI 画图。关卡三时间切割滑窗分割为什么能防穿越随机打乱切训练/测试集是时间序列建模的第一大忌——模型会偷偷看到未来。FreqAI 的解法是把整段回测区间切成训练窗在前、测试窗紧随其后的序列循环推进。核心循环在 data_kitchen.py 第 331-368 行的split_timerange# 来源freqtrade/freqai/data_kitchen.py:331-368 train_period_days train_split * SECONDS_IN_DAY # 训练窗长度由 train_period_days 配置 bt_period bt_split * SECONDS_IN_DAY # 测试窗长度由 backtest_period_days 配置 while True: timerange_train.stopts timerange_train.startts train_period_days tr_training_list.append(timerange_train.timerange_str) # 关键一步测试窗起点 训练窗终点只能往后看天然杜绝未来数据 timerange_backtest.startts timerange_train.stopts timerange_backtest.stopts min(timerange_backtest.startts int(bt_period), config_timerange.stopts) tr_backtesting_list.append(timerange_backtest.timerange_str) if timerange_backtest.stopts config_timerange.stopts: break推一步你就明白妙处第一个测试窗用的是训练时根本看不到的数据模型每次在窗口末端做一次真正的盲测。循环结束后所有测试窗拼起来恰好覆盖你--timerange指定的整个回测区间——预测总量一分不差但没有任何一段测试数据混进过对应训练集。窗口长度由配置里的train_period_days和backtest_period_days控制config_schema.py 第 1186-1196 行。关卡四管道加工去常量、标准化、PCA、DBSCAN 的灵活拼装清洗后的特征值域可能差着好几个数量级还有常量列和离群点。FreqAI 把这一坨预处理委托给datasieve库的 Pipeline做成可插拔的积木——你只需要在配置里开关。拼装逻辑在 freqai_interface.py 第 558-586 行的define_data_pipeline# 来源freqtrade/freqai/freqai_interface.py:558-586 ft_params self.freqai_info[feature_parameters] pipe_steps [ (const, ds.VarianceThreshold(threshold0)), # 第 1 步方差为 0 的常量列扔掉 (scaler, SKLearnWrapper(MinMaxScaler(feature_range(-1, 1)))), # 第 2 步全部压进 [-1, 1] ] if ft_params.get(principal_component_analysis, False): pipe_steps.append((pca, ds.PCA(n_components0.999))) # 可选PCA 降到 99.9% 方差 if ft_params.get(use_DBSCAN_to_remove_outliers, False): pipe_steps.append((dbscan, ds.DBSCAN(n_jobsthreads))) # 可选DBSCAN 剔除离群样本 return Pipeline(pipe_steps)顺序即流程先扔常量否则 MinMaxScaler 会除零再标准化开了 PCA 还会追加一个post-pca-scaler第 567-569 行因为 PCA 变换后的值域要重新压回 [-1, 1]。标签列走单独的define_label_pipeline第 588-591 行同样做 MinMax 标准化预测时再反变换回真实价格尺度。验收时刻张量出炉形状直接喂 LSTM / Transformer流水线跑完data_dictionary里躺着的是四个 DataFrametrain_features/test_features/train_labels/test_labels。最后一步交给 freqtrade/freqai/torch/ 下的转换器。基础转换只有几行见 PyTorchDataConvertor.py 第 47-50 行# 来源freqtrade/freqai/torch/PyTorchDataConvertor.py:47-50 def convert_x(self, df: pd.DataFrame, device: str) - torch.Tensor: x torch.tensor(df.values, devicedevice, dtypetorch.float32) # DataFrame → float32 张量 return xPyTorchModelTrainer.create_data_loaders_dictionaryPyTorchModelTrainer.py 第 159-179 行接着把张量包成TensorDatasetDataLoader自动按batch_size切批、shuffle打乱。如果你跑的是 Transformer 类模型PyTorchTransformerTrainer会换成WindowDatasetdatasets.py 第 13-19 行按window_size从张量上切出连续时间步# 来源freqtrade/freqai/torch/datasets.py:13-19 window_x self.xs[idx_rev : idx_rev self.window_size, :] # 连续 window_size 个时间步 window_y self.ys[idx_rev self.window_size - 1, :].unsqueeze(0) # 窗口最后一行当目标 return window_x, window_y于是每个 batch 的输入形状就是(批次, 时间步, 特征数)输出对应最后一个时间步的预测——LSTM、Transformer 要的正是这个结构你一行 reshape 都不用写。三个高频坑位与解法坑位 1NaN 占比过高训练样本被腰斩⚠️ 原因几乎都是指标预热期RSI 要 14 根 K 线、你的窗口切片只有几百根开头全是 NaN 被关卡一删掉了。触发点在 data_kitchen.py 第 265-271 行——丢弃超过 10% 时日志会明确告诉你最差的那列指标是谁。解法三选一调大startup_candle_count、给indicator_periods_candles配足预热根数、或把特征参数如 RSI 周期缩短。日志里那句dropped X training points due to NaNs是你最快的体检指标。坑位 2特征重要性到底怎么看用树模型LightGBM/XGBoost时FreqAI 会自动画最好 vs 最差特征双栏水平柱状图保存在模型目录下sub-train-*的 HTML 文件里入口是 utils.py 第 93-155 行的plot_feature_importance注意它只支持有feature_importances_的模型PyTorch 模型会直接跳过并打日志。训练完先打开这张图底部那排贡献接近 0 的特征就是你下一轮要剪掉的。坑位 3数据一大就慢三个开关都在feature_parameters里config_schema.py 第 1226-1374 行data_kitchen_thread_count数据处理线程数不填时默认按 CPU 核数推算data_kitchen.py 第 99-102 行include_timeframes只拉你真正用到的周期别把 1m 和 4h 都塞进去principal_component_analysis: true特征数上百时开 PCA训练速度和内存都会明显改善带走三句话NaN 处理没有对错只有模式训练删行保纯度预测填 0 加do_predict掩码保行数对齐。防穿越不靠自觉靠结构测试窗起点永远等于训练窗终点滑窗循环到--timerange末尾才收工。你唯一要写的是特征列和配置开关%/暗号加 Pipeline 积木会替你把剩下的脏活干完。想动手验证的话从 docs/freqai.md 过一遍配置项再对照 docs/freqai-feature-engineering.md 的特征工程写法然后把 freqtrade/templates/FreqaiExampleStrategy.py 复制进自己的 user_data/strategies改两个特征周期先跑通第一次滑窗回测——日志里那句 dropped X training points 会告诉你第一步该调哪里。【免费下载链接】freqtradeFree, open source crypto trading bot项目地址: https://gitcode.com/GitHub_Trending/fr/freqtrade创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考