交易中的神经网络:自适应周期分块(LightGTS)
引言
时间序列预测长期以来都是诸多领域的核心工具,应用范围涵盖能源、交通、医疗以及教育行业。但恰恰是在金融领域,每一秒的价值都可以用金钱来衡量,预测的准确度也就变得至关重要。这里容不得半点差错:模型哪怕出现极其微小的失误,都会造成交易策略出现亏损。
无论是基于统计学还是深度学习的传统方案,大多遵循一个任务,一个模型的设计原则。这类方案在相对孤立或受控的场景下表现良好,但现实当中金融市场的行为充满不确定性:波动率、数据尺度、周期、市场状态都会发生切换,这些因素都会让固化的任务专用模型效果大打折扣。
在此背景下,所谓时间序列基础模型 (TSFM)应运而生。这类模型在海量、多样化的数据集上完成训练,目标是实现通用性与可扩展性。但现实情况是,这类模型需要消耗巨大的计算资源,而精度上的提升并不总能匹配付出的成本。模型参数量动辄数千万,但在实际使用中,通用性往往会在细节层面大打折扣。
时间序列的独特之处在于它自身的节律。文本里的词元对应的是词语,而时间序列则格外看重尺度与周期性。部分数据一小时更新一次,还有的每十五分钟就产生一条数据。一部分数据呈现日度、周度季节性特征,另一些则表现出季度、年度的季节规律。以上全部要素共同构成所谓内在周期,也就是数据当中反复出现的模式,这对高质量预测至关重要。此外,当数据尺度发生改变,周期长度也会随之改变;如果模型无法处理该现象,它的泛化能力就会急剧下降。
现存绝大多数模型都采用固定分词策略,这正是问题所在。它们只是简单地将数据切分为等长片段,完全不考虑尺度或者周期结构。这就造成部分词元承载的数据量过大,而另一些词元几乎是空的。信息变得模糊,重复出现的周期模式也遭到破坏。当一个在某一尺度训练完成的模型被迁移到另一尺度的数据上时,该现象会表现得尤为突出:预测精度下滑,不得不增加参数量,最终导致训练耗时与训练成本双双上涨。
《LightGTS:轻量通用时间序列预测模型》一文的作者决定不再依靠暴力穷举法,而是采用一套合理方案 —— 利用时间序列本身固有的属性:尺度不变性与周期性。LightGTS框架便是这项研究的成果,它是一套轻量化、高效的解决方案,专门面向真实场景下的时间序列预测任务。其核心思路不是去对抗多尺度问题,而是主动适配不同数据尺度。
该论文提出不再将数据生硬切分为等长片段,转而使用周期词元化。模型会自适应地把数据切分为片段,片段长度等于一个完整周期。这使得模型无论在哪种尺度下,都能捕获完整规律 —— 无论是日线图还是一分钟 K 线图。词元内部的语义在不同尺度下保持一致,从而使特征表征在任务间更稳定、更易迁移。
该框架采用并行解码完成预测:编码器输出的最后一个词元作为起点,基于该词元一次性生成全部未来值。这种方式不仅节省计算时间、降低误差累积(区别于逐步自回归方法),还能更好利用时序本身的结构。最后这个词元浓缩了全部历史上下文信息,并与未来时段的预测目标直接相关,由此生成的预测结果逻辑通顺、结构完整。
除此之外,LightGTS框架的作者摒弃了固定特征投影。取而代之的是使用柔性层,该层可以适配变化的周期长度与多源数据。这一点在金融场景尤为实用:投资组合内可同时包含小时级股票数据与日度宏观经济数据。
实验结果本身就足以说明效果。LightGTS模型的预测精度可对标行业最优方案,参数量却不足 500 万。相比其他TSFM,其参数量仅为后者的 1/10 至 1/100。这代表更短的训练时长、更低的基础设施成本,也更容易部署到实盘交易系统或者分析平台中。
LightGTS算法
设想金融市场中一个典型预测任务。我们有多变量时间序列,例如报价、成交量、指标以及其他市场信号。记为Xt = {xi,t-L:t}i=1,C,其中每一个xi代表单独一条通道在最近L个时间步的观测值。通道数量C可以任意取值,从 1 到数十个不等。这就是我们用于回溯历史的窗口,一个在待分析历史数据上滑动的窗口。
我们的目标是向前预测F个时间步,得到预测值Ŷt = {ŷi,t:t+F}i=1,C。在训练阶段评估精度时,我们还有真实观测数据:Yt = {yi,t:t+F}i=1,C。以上全部内容都属于经典预测框架范畴。
接下来是最核心有趣的部分。模型分为两阶段训练。第一阶段,在来自不同数据源的异构时间序列上进行大规模预训练。数据集可以包含股票、货币对历史数据、经济指标、气象数据 —— 任何具备时序结构的数据均可。下一阶段,针对特定任务对模型进行微调。
有一个值得关注的点:模型甚至不一定需要微调。如果初始预训练就具备足够强的通用性,直接在测试集上评估效果就足够。这对算法交易场景尤为重要:并不总能针对每一个交易品种单独微调模型,实盘场景下更是如此。
LightGTS模型的独特之处是什么?一切都始于周期词元化,它就像一把神奇标尺,可以适配时序自身的波动节律。该框架作者提出,将序列切分为周期分块,每段数据对应一个完整周期(例如日周期、周周期)。该操作被命名为自适应周期分块。该方法会考虑时间序列的尺度与结构,生成完美匹配市场行为重复模式的数据片段。
为讲解该方法,我们先看简单案例 —— 一维时间序列。在实际应用中,该方法可轻松扩展至多变量数据:每条通道独立处理,不会破坏原有结构。
假设我们处理一批来自不同来源的时间序列:各类金融资产、不同市场、不同时间周期。每一条序列都有自身内在节律,也就是所谓固有周期。例如日内交易周期、周波动率,或是季节性趋势。想要高效处理这类序列,第一步就是确定周期长度:也就是待分析数据中多少个时间点构成一个完整循环。
如果你预先知道数据采样频率(例如一小时一条、一分钟一条),周期长度很容易确定:例如小时采样数据的日周期,就等于 24 个数据点。但当缺少频率信息时,谱分析(包括快速傅里叶变换FFT)就能派上用场,帮助我们识别序列中的主导频率。正是这些频率反映重复模式,也就是对市场动态预测至关重要的循环周期。
一旦确定周期长度,我们记作P,整条时间序列就会被整齐切分为连续、无重叠的片段,每段恰好为一个周期长度。每个片段或称分块,包含P个数据点,覆盖一整个完整周期。分块数量等于L除以P向下取整,其中L是原始序列长度。
表面上看,这一步操作很简单,但实际上,它让模型能够提取更高层级的语义结构。不同时间周期、采样频率、数据源的数据,现在都能在同一个周期对齐空间内被解读。这消除了数据尺度差异带来的噪声,让模型学习识别跨周期重复出现的模式,而不只是单纯拟合局部波动率。
正是这种序列切分方式,支持模型在异构数据源上训练。即便采样频率各不相同,全部数据都会转换为可对比形式,周期成为核心信息单元。这意味着模型可以识别并泛化重复出现的市场信号,这在实盘交易中,对可靠预测至关重要。
当时间序列切分为多个周期分块,每个分块覆盖时序一个完整周期后,关键是把这些分块正确映射为向量表征。柔性投影层的精妙之处就在这里,但和现实世界一样,细节决定成败。
最简单的方案是使用固定投影矩阵,把每一个分块转为词元。但问题在哪?不同金融数据拥有不同周期长度:分钟 K 线的日周期包含 1440 个点,小时 K 线的周周期仅 120 个点。于是输入分块尺寸各不相同,固定矩阵无法处理:要么截断数据,要么全部缩放至统一尺寸。简单插值虽然可行,直接拉伸或压缩数据。但这里存在缺陷:这类操作会扭曲原始含义。最终得到对齐规整但空洞无意义的词元,对模型没有价值。
为避免这类失真,论文引入柔性投影层(Flex Projection Layer)。它的任务不只是简单将分块压缩到固定维度,而是在压缩过程保留数据语义。换句话说,来自长度 96 分块生成的词元,应当等价于长度 144 分块生成的词元,前提是二者表征同一个市场周期。
技术上如何实现?假设我们有针对长度P分块训练得到的投影权重θ。我们希望把权重适配给新长度 P′的分块,使得数据与权重相乘结果(即词元)尽可能保持一致。简单插值在这里行不通,太过粗糙。因此采用基于伪逆矩阵做权重适配的线性变换,这是数值计算与回归分析领域成熟方法。
该机制命名为柔性缩放(flex-resize),它求解一个优化问题:寻找新权重θ′,将其作用在新分块上,得到的结果在弗罗贝尼乌斯范数意义下尽可能贴近原始结果。这里引入系数δ,用来表征原始分块与插值后分块之间的方差差异,维持投影的统计稳定性。柔性缩放的最终公式看起来复杂,本质上是让权重矩阵具备自适应柔性的巧妙设计。
柔性投影层的实现包含两组参数矩阵,一组输入矩阵、一组输出矩阵,均基于参考分块尺寸(例如 96)设计。在模型前向传播阶段,借助前面提到的δ⁻¹(A)+变换,矩阵会适配当前分块所需长度。完成适配后,分块可顺利投影至模型隐空间;词元生成完毕,并且完整保留原始市场周期的全部结构。
因此,无论模型使用日线分析周趋势,还是用分钟 K 线做短线交易,数据都会以统一、一致的形式送入模型。这解决了不同尺度之间的冲突,可以高效复用预训练权重,无需从头重新训练。而金融市场数据来源多样、采样频率不一,这种灵活性不是锦上添花,而是刚需。
LightGTS框架架构和经典Transformer一样,包含编码器与解码器,二者都搭载多头注意力模块与全连接层(前馈网络)。但存在一处关键细节:注意力模块使用旋转位置编码(RoPE),不仅能识别词元绝对位置,还能捕捉相对位置。这对时间序列尤其重要:除了顺序,数据点之间的距离同样会影响结果。
周期分块经过柔性投影转为词元后,形成词元序列𝐗ₑ = {𝐱ₑ₁, 𝐱ₑ₂, …, 𝐱ₑₙ},其中𝐱ₑᵢ是索引为i分块的向量表征。编码器处理该序列时,借助RoPE注入位置信息:词元不只是记住自身位置,还会记录相互之间的相对偏移量。
具体来说,对每个词元,使用可训练矩阵𝐖Q和𝐖K计算 Query 查询向量与 Key 键向量。接着,对代表位置i、j的向量对 (𝐱ₑᵢ, 𝐱ₑⱼ),应用旋转矩阵𝐑i−j;该矩阵精准编码二者位置差值。词元i与j之间最终相似度按下面公式计算:

该数值越高,代表词元i对词元j分配的注意力越多。全部相似度值经由SoftMax函数归一化,再结合另一组可训练矩阵𝐖V.得到的 Value 值向量,计算加权求和。
正是这套注意力机制,直接决定每一个词元需要关注哪些相邻词元,以及关注强度。注意力计算完成后,每个词元送入全连接模块前馈网络,提取隐藏特征,丰富表征信息。
最终,编码器输出隐空间,其中每一条向量𝐞ⱼ不仅包含分块局部信息,还融合其他所有词元的上下文,同时考虑它们在时序中的相对位置。这套机制让模型理解数据的结构、节律与重复模式;金融时序中,单个数据点本身价值有限,上下文才是核心。
前面提到,周期分块可以从时序中提取重复周期。但想要在预测生成阶段充分利用这些信息,模型采用一种全新方案 ——周期并行解码。经典自回归方式需要一步步生成预测,而该方法属于非自回归策略,可以一次性处理全部未来预测区间。
核心理念简洁精巧:编码器输出隐空间中最后一个词元𝐞ₙ,压缩存储全部前置序列信息,包含内在周期性。因此,我们取出这个词元,复制K份(其中K = F/P,也就是待预测的周期数量),得到矩阵𝐇,作为解码器输入。
但有一点需要注意:随着预测步不断向前延伸,最后一个词元对远期预测的影响力会衰减。因此对每一个复制向量𝐡ⱼ施加权重函数 ω(j) = 1/eʲ,随着距离当前时刻越远,指数式降低贡献度。加权后的词元 ω(j)·𝐡ⱼ同时送入解码器,这就是解码器并行架构的核心。
解码器输出矩阵𝐙,即对应未来多个周期的预测词元。为把词元还原为标准时序数值,模型通过前面介绍的柔性缩放机制做逆投影,这次作用在解码器参数θd上。
于是模型一次性输出全部预测区间的结果𝐘̂,不存在逐点预测典型的误差累积与延迟问题。这不仅加快计算速度,还能更好保留周期性:因为周期性在词元化阶段就已经确定,并贯穿整套架构,从编码器一直延续到最终输出。
底层运行时,LightGTS运转如精密时钟:富有节律、计算精准,无多余开销。依靠周期词元化与并行解码,模型避开了笨重架构、迁移性差等经典缺陷。
按照时序预测领域通用惯例,LightGTS框架作者使用经典均方误差(MSE)作为损失函数。该指标衡量预测值和真实观测数据之间偏差,作为评判预测质量的客观标准。
下方为作者绘制的LightGTS框架示意图。

在 MQL5中的实现
详细讲解完LightGTS框架理论部分后,我们进入文章实操章节。本节介绍我们使用MQL5实现模型核心组件的自研方案,实现过程兼顾金融时序特点与平台本身的限制。
我们从最基础、也最有意思的模块开始:自适应周期分块。该模块是时间序列转为 Transformer 可处理结构的起点。这里会遇到数个棘手难题。
其中一个难题就是分块尺寸动态变化,原始框架论文中已经提到。论文提出了一种较为优雅的权重自适应调整方法。但在实际落地时,该方案只能解决一部分问题。
毕竟分块尺寸改变时,分块数量也会动态、不可预测地变化。这会显著提升模型架构复杂度,尤其是在MQL5这类强类型语言中实现。传统循环与数组要求全程严格管控尺寸,意味着不仅要适配输入数据维度,还要开发一套机制,将时间序列自适应切分为可变数量分块,同时保证周期性、与历史观测保持一致。
遗憾的是,我们采用的架构方案不支持运行时输入、输出张量动态维度。因此,我们需要另一套更务实的方案:缓冲区尺寸固定,但依然支持可变数量词元。
其中一种方案是创建超额分配缓冲区,容量可容纳最大可能词元数量。如果实际词元数量更少,多余单元填充 0。该方案确实可以在不同分块数量下提供一定灵活性;但代价是额外内存占用,很大一部分内存会闲置。
此外,不能忽略Transformer架构的核心短板:注意力计算复杂度随序列长度呈二次增长。送入模型的词元越多,注意力模块消耗的时间与资源就越高。换句话说,过多词元不仅内存利用率低,还会直接损害模型计算性能,实盘场景或是高频行情数组处理时尤为明显。
因此我们需要另一种更灵活的方案。这里值得关注LightGTS框架作者提出的无重叠周期分块思想;该思路下,时序的每一段对应一个完整周期。逻辑上很合理:时间序列通常包含多个独立周期分量,单独分析每个周期,能够提取语义纯净的特征。
但是我们建议换一个思路思考这个问题。如果放弃分块不可重叠这一硬性约束,结果会如何?我们可以预先设定输出分块数量,再根据输入序列的周期性,调整相邻窗口之间的重叠长度。
这套方案有多项优势。第一,无论待分析时序的周期如何,分块数量恒定。设计固定架构时这点极为便利。第二,灵活重叠机制能够完整覆盖周期数据结构,不会截断数据,也不会丢失窗口边界上的信息。最后,可以平滑控制语义表征分辨率,同时不破坏输出张量的紧凑性。
简单来讲,我们提议放宽严格的一个分块 — 一个周期(one patch — one cycle)规则,改为可控表征密度,同时保证总输出信息量不变,提升模型对输入序列长度变化的鲁棒性。
我相信这个思路已经讲清楚。现在进入实操实现环节。第一步是确定待分析时间序列的周期。我们采用久经检验的经典方法,基于快速傅里叶变换 (FFT)。
该方法原理简单:我们查看时间序列频率分量的振幅谱,识别能量最高的频率。该频率一般对应数据中的主导周期。周期值等于检测频率的倒数。
为什么专门选用FFT?第一,即便处理大数据,算法速度快、效率高。第二,可以识别肉眼很难察觉的隐藏周期依赖关系。最后,FFT的一大优势:在缺少时序先验频率信息的场景下依旧可用 —— 真实交易数据往往就是这种情况。
当然还有额外优势:我们的库中已经存在现成可用的FFT实现。提醒一下读者,我们之前在FITS框架的相关工作中就使用过该 FFT 模块。
库内的FFT实现会返回频谱实部与虚部,完全匹配快速傅里叶变换经典结果。但仅凭这些信息,无法判断哪一个频率在信号中占主导、决定振荡结构。
为避免给 CPU 带来额外负担,并保持并行执行效率,我们直接在OpenCL上下文内编写内核,单独为每一条序列计算主导频率。每一个工作项读取独立频谱,计算全部频率分量能量,选出振幅最大的分量。就像聆听一段复杂旋律,瞬间识别支撑整首曲子的底层节奏。这套方案对多变量时间序列非常重要,每条变量都可能拥有自身特征频率。
我们在 OpenCL 内核MainFreq中实现该算法,内核接收实部、虚部频谱数组。输出数组存储每条序列最显著频率对应的索引。
__kernel void MainFreq(__global const float* freq_r, __global const float* freq_im, __global float *main_freq, int dimension ) { if(dimension <= 0) return; //--- size_t n = get_global_id(0); const int shift = n * dimension;
在内核主体中,我们首先在一维任务空间内识别每个工作项。得到的索引代表待分析单条序列的唯一编号。借助该索引,我们立刻确定频谱数组内的偏移量,使每个工作项仅处理属于自身的那一条序列。
接下来,初始化变量,用于存储最大振幅(能量)及其对应的索引。
float max_f = 0; float max_id = 0; float energy;
准备工作到此完成,随后我们遍历频谱,从一次谐波开始。
for(int i = 1; i < dimension; i++) { float2 freq = (float2)(freq_r[shift + i], freq_im[shift + i]); energy = ComplexAbs(freq); if(max_f < energy) { max_f = energy; max_id = i + 1; } }
我们刻意跳过零频率(也就是DC直流分量)—— 它不携带任何周期性相关信息,仅反映信号的恒定分量。
每一轮迭代中,我们利用实部与虚部构造复数。该复数的模代表对应频率的强度。如果算出的能量超过当前最大值,就更新保存的数值。
最后,遍历完整段频谱之后,将结果写入全局数据缓冲区。
main_freq[n] = max_id; }
该算法如同经验丰富的指挥,密切关注乐团中的每一件乐器,判断哪一个乐器在演奏主旋律。我们不只是求解频率,还会计算信号最显著的周期,后续模型会利用这个周期自适应构建分块。由于每条序列(多模态场景下)独立处理,最终得到一套可扩展、灵活且完全自主的局部周期检测系统。
还有一点需要重点强调:本文提出的算法具备完全确定性,不含任何可训练参数,不会产生训练开销。它仅依托频谱本身的数学特性:直接估算各频率分量的振幅,不使用任何统计方法、回归算法或自适应权重。该特性让这套方法透明可靠,在数据预处理阶段尤为适用 —— 预处理阶段必须避免引入欠拟合或过拟合带来的数据失真。换句话说,该方案依托纯粹、无偏的数学运算,而非概率假设,对于波动剧烈的市场时间序列分析而言,这一点至关重要。
我们下一步的工作,就是实际实现分段尺寸动态变化的自适应分块算法。但不难想象,这部分内容无法用寥寥数语讲清楚。落地实现需要处理大量技术细节,而本文篇幅已经很长。因此,效仿悬念连续剧的经典做法,我们建议暂且告一段落,在下一篇文章继续探讨所提方案的实现方式。
在下一篇文章中,我们会一步步讲解如何实现动态生成分块的机制,该机制能够适配变化的周期长度,同时保证输出词元数量固定。我们还会探讨架构灵活性与计算效率之间可能存在的各项取舍。
结论
本文详细探讨了LightGTS框架的理论基础,重点介绍其核心组件:周期分块、柔性词元投影以及并行解码机制。我们分析了该架构如何处理多变量时间序列,并在无需重新训练模型的前提下适配不同周期。文章重点阐述了基于快速傅里叶变换计算主导频率的技术细节。
我们也讨论了动态内存分配与可变词元数量带来的工程限制,并提出基于重叠分块、定长输出向量的替代方案。该方案不仅提升了与Transformer架构的兼容性,还能更高效地利用资源,避免内存过度占用与性能下降。
本文所展示的内容,为后续完整自适应分块模块的实现、以及将其接入预测模型架构打下坚实基础。在下一篇文章中,我们将沿着这条思路继续深入,聚焦自适应时序分块的具体实现,并把生成的词元集成到可训练模型之中。
参考
本文使用的程序
| # | 名称 | 类型 | 说明 |
|---|---|---|---|
| 1 | Study.mq5 | EA | 用于离线模型训练的EA |
| 2 | StudyOnline.mq5 | EA | 用于在线模型训练的EA |
| 3 | Test.mq5 | EA | 用于模型测试的EA |
| 4 | Trajectory.mqh | 类库 | 描述系统状态与模型架构的结构体 |
| 5 | NeuroNet.mqh | 类库 | 用于构建神经网络的类库 |
| 6 | NeuroNet.cl | 库文件 | OpenCL程序的代码库文件 |
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/18596
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
从基础到进阶:处理鼠标事件
新手在交易中的10个基本错误
从新手到专家:报表 EA — 搭建工作流程