Type/to search
8
Follow
1370
Followers
每根 K 线都更新模型,究竟是在适应市场,还是在追逐噪声?一次基于 FMZ Rust 的在线学习对照实践
Discussions
Created 2026-07-26 18:13:37  Updated 2026-07-27 11:17:06
 0
 2

img

一次基于 FMZ Rust 的在线学习对照实验

在线学习在量化研究里很容易被包装成一项天然优势:市场是非平稳的,所以模型应该持续吸收新数据。

这个推理只走了一半。

模型更新得更快,确实可能更早摆脱已经失效的历史关系;但同一套更新机制,也会更快地把短期随机波动写进参数。对交易策略来说,后者不仅表现为预测不稳定,还会转化为更高的换手、更强的成本敏感性,以及更大的路径依赖。

因此,本文不试图证明“在线模型优于固定模型”。实验要回答的是一个更具体的问题:

当模型结构、特征、交易规则和成本假设完全相同时,改变模型吸收新样本的速度,会怎样影响样本外损失、参数稳定性、换手和虚拟净值?

为避免把模型差异和回测环境差异混在一起,四套模型在同一个 Rust 策略进程内并行运行,读取同一组 K 线,使用相同的特征和虚拟成交规则。策略不向交易所发单,只维护四个影子账户。

本文保留一组实际回测,用来检查时间对齐、标签分布、预测损失、换手和交易成本是否符合预期。但单次回测不会被当作普遍结论。策略的主要价值,仍然是建立一套可复现的比较框架。


1. 研究问题:更新速度本身就是模型风险

在线学习通常采用“先预测、后观察标签、再更新”的顺序。第 \(t\) 个样本到来时,模型先用当前参数做预测;真实结果出现后,计算损失并更新参数。

这类方法的优势是无需反复保存和重训全部历史数据,也能逐步吸收新信息。问题在于,每条新样本都会立即影响参数。

可以把更新机制理解为一条连续的速度轴:

text
永不更新 ── 定期滚动重训 ── 误差恶化后更新 ── 每根 K 线更新 ── 每个 Tick 更新

越靠左,参数越稳定,但面对结构变化时反应更慢;越靠右,模型越灵活,也越容易被短期噪声推动。

因此,本次实验预先提出三个待检验的判断,而不是预设答案:

  1. 逐根在线更新可能缩短模型在行情切换后的恢复时间;
  2. 同一机制也可能放大参数波动、信号翻转和交易成本;
  3. 模型表现未必随更新频率单调改善,中间速度可能更稳。

2. 实验设计:只改变模型怎样吸收新样本

四组模型共享同一套初始化参数。

模型更新方式研究含义
固定模型初始化后不再更新观察历史关系自然衰减的速度
逐根在线每获得一个新标签就做一次梯度更新最快的样本吸收速度
滚动重训每隔固定根数,用最近窗口从头训练降低单个样本的即时影响
误差门控近期 Log Loss 明显恶化后,用小批近期样本低速更新在稳定和适应之间加一道门槛

第四组只能称为“误差门控更新”,不能称为严格的概念漂移检测器。

预测损失上升可能来自条件分布变化,也可能只是波动率上升、异常值、标签随机性或模型本身校准不佳。本文只利用损失恶化作为工程触发条件,不根据它断言市场已经发生概念漂移。

为了保证比较尽量干净,四组模型使用完全相同的:

  • 初始训练样本;
  • 特征及标准化参数;
  • 逻辑回归结构;
  • 多空概率阈值;
  • 收益计算方式;
  • 单边换手成本假设。

四个虚拟账户也在同一根 K 线上同步结算。这样,结果差异主要来自更新机制,而不是数据切片、接口时点或回测撮合差异。


3. 时间对齐:先把未来函数和成交假设处理清楚

在线模型最容易出错的地方不是梯度公式,而是样本时间。

本文在第 \(t\) 根 K 线收盘后计算特征 \(x_t\),预测第 \(t+1\) 根 K 线从开盘到收盘的方向:

下一根K线标签定义

这里的 0 类准确地说是“非上涨”,因为开盘价等于收盘价时也会被编码为 0。

标签函数如下:

rust
fn make_label( bars: &[Bar], feature_index: usize, ) -> f64 { let next_bar = bars[feature_index + 1]; if next_bar.close > next_bar.open { 1.0 } else { 0.0 } }

流程如下:

text
第 t 根 K 线结束 ↓ 计算 x_t 并预测第 t+1 根方向 ↓ 假定在第 t+1 根开盘附近建立仓位 ↓ 第 t+1 根收盘,得到标签和开盘到收盘收益 ↓ 先评价原预测,再允许模型更新

这种定义没有假定策略能够在已经知道收盘价后,仍成交在第 \(t\) 根 K 线的收盘价上。

虚拟账户使用第 \(t+1\) 根 K 线的开盘到收盘收益:

开盘到收盘收益

这仍然是简化模型。真实订单未必能成交在下一根 K 线的开盘价,盘口冲击、延迟和滑点也不会固定。代码中的成本只是统一的压力测试假设,不代表任何交易所的真实费率。

3.1 回测与实盘分别判断完整 K 线

第一版策略曾统一使用当前时间判断 K 线是否结束。在实际回测中,这种写法把正在形成的 Bar 提前当成了完整样本,导致大量 K 线出现 Open == Close,模型准确率异常接近 100%。

修正版通过 IsVirtual() 区分运行环境:

  • 回测环境中,保守使用行情数组的倒数第二根 Bar;
  • 实盘环境中,检查最后一根 Bar 的起始时间加周期长度是否已经不晚于当前时间;
  • 如果实盘接口中的最后一根仍未结束,则退回倒数第二根。
rust
fn latest_closed_index( bars: &[Bar], is_backtest: bool, bar_seconds: i64, ) -> Option<usize> { if bars.len() < 2 { return None; } if is_backtest { return Some(bars.len() - 2); } let last_index = bars.len() - 1; let period_ms = bar_seconds * 1000; let current_time_ms = (UnixNano() / 1_000_000) as i64; if bars[last_index].time + period_ms <= current_time_ms { Some(last_index) } else { Some(last_index - 1) } }

少处理一根 K 线的代价,远小于把未完成数据误作标签。

3.2 Test-then-train

每个新标签出现时,处理顺序严格保持为:

  1. 使用之前保存的预测计算准确率和 Log Loss;
  2. 使用之前确定的仓位计算当前 K 线收益;
  3. 将当前样本加入训练数据;
  4. 按各模型的规则更新参数;
  5. 使用当前完整 K 线生成下一根预测。

也就是先测试,再训练。当前样本不会先进入模型,再拿同一条样本评价模型。


4. 模型:简单的逻辑回归足够完成这次实验

本文没有使用神经网络或树模型,而是使用带 L2 正则的逻辑回归:

逻辑回归预测概率

其中 \(p_t\) 是下一根 K 线上涨的估计概率。

逐根更新采用二元交叉熵对应的随机梯度:

逻辑回归在线更新

上式只写出了权重项。代码中的偏置 \(b\) 也会同步更新,但不施加 L2 正则。

rust
fn predict( &self, features: &[f64; N_FEATURES], ) -> f64 { let mut linear_value = self.bias; for j in 0..N_FEATURES { linear_value += self.weights[j] * features[j]; } Self::sigmoid(linear_value) } fn update( &mut self, features: &[f64; N_FEATURES], label: f64, learning_rate_scale: f64, ) { let probability = self.predict(features); let error = probability - label; let step = self.learning_rate * learning_rate_scale; for j in 0..N_FEATURES { let gradient = clip( error * features[j] + self.l2_penalty * self.weights[j], -5.0, 5.0, ); self.weights[j] -= step * gradient; } self.bias -= step * clip(error, -1.0, 1.0); self.updates += 1; }

选择简单模型并不是认为逻辑回归足以描述市场,而是为了减少实验中的混杂因素。

如果同时改变网络结构、训练轮数、特征数量和更新频率,最后很难判断收益差异来自哪里。线性模型的参数变化可以直接测量,也便于观察“模型适应”是否伴随着过大的权重漂移。

代码还对单次梯度和标准化特征做了截断,目的不是提高收益,而是避免极端 K 线让参数在一次更新中跳得过远。


5. 特征:只保留价格结构和成交量的基础信息

模型使用八个特征:

  1. 单根对数收益;
  2. K 线实体的对数收益;
  3. 最高价与最低价的对数区间;
  4. 上影线相对长度;
  5. 下影线相对长度;
  6. 成交量对数变化;
  7. 三根 K 线动量;
  8. 最近五根 K 线收益的实现波动率。

没有加入 RSI、MACD、均线交叉等派生指标,也没有使用几十个滞后项。

下面是特征计算中的主要部分:

rust
fn raw_features( bars: &[Bar], index: usize, ) -> [f64; N_FEATURES] { let current = bars[index]; let previous = bars[index - 1]; let epsilon = 1e-12; let log_return_1 = (current.close.max(epsilon) / previous.close.max(epsilon)) .ln(); let candle_body = (current.close.max(epsilon) / current.open.max(epsilon)) .ln(); let range = (current.high.max(epsilon) / current.low.max(epsilon)) .ln(); let upper_wick = (current.high - current.open.max(current.close)) .max(0.0) / current.open.max(epsilon); let lower_wick = (current.open.min(current.close) - current.low) .max(0.0) / current.open.max(epsilon); let volume_change = ((current.volume + epsilon) / (previous.volume + epsilon)) .ln(); let momentum_3 = (current.close.max(epsilon) / bars[index - 3] .close .max(epsilon)) .ln(); // 最近五根收益的实现波动率 // 在完整代码中按同一窗口继续计算。 [ log_return_1, candle_body, range, upper_wick, lower_wick, volume_change, momentum_3, realized_volatility, ] }

初始样本被按时间分为前 80% 和后 20%。标准化器只用前 80% 的特征拟合均值和标准差,之后保持固定。四套模型始终使用同一个标准化器。

这里特意不让标准化器在线更新。否则,逐根模型获得的不仅是参数更新,还多了一层特征分布自适应,比较对象就不再单一。

固定标准化器有利于保持四组模型可比,但当特征分布长期变化时,也可能产生尺度失配。因此,本次结果同时包含模型关系失效和固定标准化尺度失配的影响,二者并没有被单独识别。


6. 初始化:四个模型必须站在同一条起跑线上

代码默认准备 320 条初始监督样本。

初始化分两步:

  1. 使用前 80% 样本做六轮批量训练;
  2. 对后 20% 样本执行逐条的“预测—记录损失—更新”。

第二段得到的平均预测前 Log Loss,被用作误差门控模型的参考损失。处理完这段样本后得到的模型,才是四组模型共同的初始参数。

rust
fn fit_initial_model( samples: &[Sample], split_index: usize, config: &Config, ) -> (LogisticModel, f64) { let mut model = train_model( &samples[..split_index], config.initial_epochs, config, ); let mut loss_sum = 0.0; let mut count = 0usize; for sample in &samples[split_index..] { let probability = model.predict(&sample.x); loss_sum += log_loss( probability, sample.y, ); count += 1; model.update( &sample.x, sample.y, 1.0, ); } let baseline_loss = if count == 0 { 0.69314718056 } else { loss_sum / count as f64 }; (model, baseline_loss) }

这种处理解决了两个问题。

第一,参考损失不是模型在已经训练过的数据上的回看损失,而是按时间顺序得到的预测前损失。

第二,四组模型都从同一个、已经吸收全部初始化样本的参数状态开始。不会出现固定模型和在线模型的初始训练数据不同,却把后续差异归因于更新方式的情况。


7. 四种更新机制

7.1 固定模型

固定模型在初始化后不再修改权重。

它提供的是基准:如果后续表现持续恶化,说明初始化阶段学到的关系无法稳定外推;如果它反而最稳,则说明额外更新没有带来足够的信息增量。

需要注意,固定模型只表示权重和偏置不再更新,不代表预测概率或仓位保持不变。输入特征每根 K 线都在变化,固定参数同样可能产生频繁换手。

7.2 逐根在线模型

每个标签出现后执行一次梯度更新:

rust
online_model.update( &previous_features, label, 1.0, );

它对新环境反应最快,也最容易把连续几条偶然样本解释成结构变化。

学习率是这组模型最重要的风险参数。学习率越大,新样本对参数的影响越强。本文使用界面默认值 0.02,不做样本内寻优。

7.3 滚动重训模型

在默认参数下,滚动模型保存最近 240 条样本,每经过 32 条新样本,将模型参数清零,再用窗口内样本重新训练。

rust
if processed_bars % config.retrain_every == 0 { periodic_model = retrain_from_window( &rolling_samples, &config, ); periodic_retrains += 1; }

这种方式有两个特征:

  • 旧样本会被明确移出训练集;
  • 单根新样本不会立即改变模型,而是等到下一次重训时与一批近期样本共同起作用。

它的适应有延迟,但参数变化通常不会像逐根更新那样完全由最后一条样本推动。滚动窗口和重训间隔都可以在策略界面中调整。

7.4 误差门控模型

门控模型维护自身预测 Log Loss 的指数移动平均:

Log Loss EMA

当近期损失高于初始化参考损失的一定比例,且不处于冷却期时,模型才使用最近一小批样本进行低学习率更新。

rust
let current_gated_loss = log_loss( gated_old_probability, label, ); gated_loss_ema = (1.0 - config.loss_ema_alpha) * gated_loss_ema + config.loss_ema_alpha * current_gated_loss; let gate_threshold = baseline_loss * config.gate_loss_multiplier; if gate_cooldown_left == 0 && gated_loss_ema > gate_threshold { let batch_start = rolling_samples .len() .saturating_sub( config.gate_batch ); for (sample_index, sample) in rolling_samples .iter() .enumerate() { if sample_index >= batch_start { gated_model.update( &sample.x, sample.y, config.gated_lr_scale, ); } } gate_events += 1; gate_cooldown_left = config.gate_cooldown; }

界面默认参数为:

  • 损失阈值:参考损失的 1.10 倍;
  • 更新批量:最近 32 条样本;
  • 学习率缩放:基础学习率的 0.25;
  • 更新后冷却:32 根 K 线。

这些值只是未经优化的实验默认值。它们的作用是定义一套可重复的门控规则,不代表统计意义上的最优阈值。


8. 交易映射与成本

模型概率被映射为三种仓位:

rust
fn position_from_probability( probability: f64, config: &Config, ) -> i32 { if probability >= config.long_threshold { 1 } else if probability <= config.short_threshold { -1 } else { 0 } }

默认规则是:

text
p >= 0.55:多仓 p <= 0.45:空仓 其他:不持仓

0.45 到 0.55 的中性区间用于减少模型在 0.5 附近的小幅波动直接转化为交易。

仓位变化量定义为:

换手定义

因此:

  • 空仓到多仓,换手为 1;
  • 多仓到空仓,换手为 1;
  • 多仓直接反为空仓,换手为 2。

成本已经设置为界面参数,而不是写死的代码常量:

rust
let cost_bps = float_parameter( "CostBps", CostBps, 0.0, 100.0, true, )?; cost_per_turnover: cost_bps / 10_000.0,

默认将 CostBps 设置为 5,即每单位单边换手扣除 5 个基点。该值是实验参数,可以在策略界面中调整,不代表具体交易所的实际费率。


9. 评价指标:不要只看准确率

四组模型同时记录以下指标:

指标观察目的
平均 Log Loss概率预测是否变得更可靠,而不只是方向碰巧正确
方向准确率0.5 阈值下的基本分类表现
虚拟净收益预测能否在统一交易规则下转化为收益
最大回撤更新机制是否增加净值路径风险
持仓率某模型是否只是因为更少交易而显得稳定
累计换手交易成本敏感性
仓位变化次数信号是否频繁改口
多空直接翻转次数模型是否在两个方向间剧烈摆动
参数位移当前权重与共同初始模型之间的距离

其中,参数位移定义为权重和偏置差值的欧氏距离。由于特征使用同一个固定标准化器,四组模型之间可以做相对比较。

参数位移大本身不是错误。行情结构真的改变时,模型需要移动。需要警惕的是下面这种组合:

text
参数位移快速上升 + 换手明显增加 + Log Loss 没有改善 + 扣成本净值恶化

这更像是模型在追逐近期样本,而不是获得了稳定的适应能力。


10. 默认参数下的一组实际回测

修正完整 K 线判断后,使用以下条件完成了一次基准回测:

text
品种:ETH_USDT.swap 周期:15 分钟 回测区间:2025-07-09 至 2026-06-21 初始化样本:320 样本外 K 线:33333 基础学习率:0.02 滚动窗口:240 单边换手成本:5 bps

默认参数回测状态栏

默认参数回测日志

样本外统计中,上涨标签为 16644 条,非上涨标签为 16689 条,其中有 36 根 K 线开盘价等于收盘价。状态栏当前显示为“下跌”,但代码中的实际口径是 Close <= Open,因此下文统一称为“非上涨”。

模型准确率Log Loss持仓率累计换手多空翻转参数位移净收益
固定模型52.07%0.709465.2%2475549850.0000-100.00%
逐根在线51.44%0.720356.7%2107336190.4409-100.00%
滚动重训51.74%0.730164.6%2127141110.5712-100.00%
误差门控49.40%0.698618.3%61901420.2989-98.00%
  • 10.1 时间对齐问题已经修正

    上涨与非上涨标签基本均衡,模型准确率回到 49%~52%,初始化参考 Log Loss 为 0.6988。此前接近 100% 的准确率,确实来自未完成 K 线被提前处理,而不是模型突然获得了极强的预测能力。

  • 10.2 更新更勤,没有改善样本外概率预测

    对于始终输出 0.5 的朴素概率模型,每条样本的 Log Loss 都约为 0.6931。

    本次回测中,四组模型的平均 Log Loss 均高于这一基准。误差门控最接近 0.6931,但仍不能认为模型已经获得有效预测能力。

    逐根在线和滚动重训都产生了明显的参数位移,但 Log Loss 分别上升到 0.7203 和 0.7301,弱于固定模型。至少在当前品种、周期、特征和默认参数下,更频繁地更新模型没有改善样本外概率预测。

  • 10.3 门控机制降低了噪声反应,但没有创造交易优势

    误差门控模型只触发了 8 次更新。它的累计换手降到 6190,多空直接翻转只有 142 次,明显低于另外三组。

    这说明门控机制至少完成了它的工程目标:减少模型因为短期误差而频繁改口。

    但其成本后净值仍下降约 98%。准确的结论不是“误差门控已经有效”,而是:

    受控更新比无条件更新更稳定,但稳定本身还没有转化为交易优势。

    状态栏最终显示“未达到更新阈值”,只表示回测结束时损失 EMA 位于阈值下方,并不与历史上曾触发 8 次更新矛盾。

  • 10.4 固定模型不更新参数,仍然可能频繁换手

    固定模型的参数位移为 0,但累计换手反而是四组中最高的。

    这并不矛盾。固定模型只表示权重和偏置不再变化,输入特征 \(x_t\) 每根 K 线仍然不同。参数固定、输入变化,预测概率和仓位依然会变化。

  • 10.5 净值接近零后,收益指标已经饱和

    四组模型在 5 bps 单边成本下都出现了严重亏损。主要问题不是某一次大额损失,而是在三万多根 K 线上累计了大量换手。

    当净值接近零以后,净收益和最大回撤都接近极限值,已经很难继续区分模型之间的经济差异。

    后续版本应至少增加:

    • 扣成本前的毛收益;
    • 累计成本;
    • 净对数收益;
    • 每千根 K 线换手;
    • 0、2、5、10 bps 多种成本情景。

    这组结果不能证明在线学习在其他市场中无效。它只能说明:在本次实验条件下,模型更新得更勤,并没有表现出更强的市场适应能力;受控更新减少了噪声反应,但稳定性还没有转化为交易优势。


11. 完整 Rust 实现

完整策略只读取 K 线,在内存中维护四个模型和四个虚拟账户,不包含真实下单逻辑。

策略代码


12. 怎样判断模型是在适应,还是在追噪声

一次回测中在线模型净值最高,不能直接证明在线更新有效。更有信息量的是指标之间的关系,以及结论能否跨区间重复。

  • 情形一:Log Loss 改善,换手没有明显上升

    如果逐根模型在行情切换后较快降低 Log Loss,同时参数位移趋于稳定,累计换手与固定模型差距不大,这才是较强的适应证据。

    这里的重点不是“参数动了”,而是参数移动后预测质量得到持续改善。

  • 情形二:准确率提高,但 Log Loss 和净值变差

    准确率只关心概率是否跨过 0.5,不关心模型有多自信。

    模型可能把原来的 0.51 提高到 0.90,方向仍然正确;一旦判断错误,Log Loss 会显著恶化。交易上,这类过度自信也更容易让信号跨过多空阈值。

    因此,在线模型准确率略高,但 Log Loss、回撤和成本后收益更差,并不矛盾。

  • 情形三:零成本有优势,加入成本后消失

    这通常意味着在线更新产生了更多边际信号,但单次优势不足以覆盖交易摩擦。

    此时模型也许确实捕捉到了一点短期可预测性,但这种可预测性没有达到可交易强度。不能把毛收益提升等同于策略有效。

  • 情形四:滚动重训或门控更新更稳

    如果这两组在多个品种和周期上都表现出较低 Log Loss、较小回撤和较低换手,说明有用的适应速度可能位于“永不更新”和“逐根更新”之间。

    仍需注意,滚动窗口、重训间隔和门控阈值本身也是超参数。不能只保留表现最好的一组设置。

  • 情形五:固定模型最好

    这并不说明市场是平稳的,只说明在当前特征、模型和样本区间中,新样本没有提供足够稳定的信息,或者在线更新规则没有正确提取这些信息。

    固定模型参数稳定,并不代表信号更少。本次回测中,固定模型的累计换手反而是四组中最高的。


13. 结果应怎样记录

至少应按品种、周期和时间区间分别保存下表,而不是只保留一条总净值:

品种周期区间模型Log Loss准确率毛收益累计成本净收益最大回撤持仓率换手参数位移

还应增加三类稳健性检查。

13.1 成本情景

至少比较:

text
0 bps 2 bps / 单边换手 5 bps / 单边换手 10 bps / 单边换手

如果在线模型只在零成本下胜出,结论应写成“产生了更多毛信号”,而不是“更适应市场”。

13.2 相邻参数

不要做大规模寻优,只检查结论是否对相邻参数稳定,例如:

text
在线学习率:0.01 / 0.02 / 0.04 重训间隔:16 / 32 / 64 滚动窗口:120 / 240 / 480 门控损失倍数:1.05 / 1.10 / 1.20

如果优势只出现在一个非常窄的参数点,更可能是样本适配。

13.3 分阶段观察

把结果按波动率、趋势强度或自然时间区间拆分。

总样本收益可能掩盖两种完全不同的行为:模型在切换期恢复更快,但在稳定期因频繁更新持续漏损。只有分阶段观察,才能看见适应收益和噪声成本分别发生在哪里。


14. 这套实验仍然有哪些限制

第一,虚拟成交不是交易所撮合。下一根开盘附近入场、固定基点成本和无盘口冲击,都是简化假设。

第二,模型只预测下一根 K 线的开盘到收盘方向。这个目标方便做时间对齐,但不代表它是最有经济意义的预测目标。

第三,固定标准化器保证了模型比较的一致性,却没有解决特征分布漂移。在线标准化可以作为另一组实验,但不能只加入逐根模型。

第四,误差门控只是一条启发式规则,不具有漂移检测算法的统计保证。若要研究正式的漂移识别,应单独实现 ADWIN、DDM 等方法,并控制误报和检测延迟。

第五,单一品种、单一周期或单一回测区间无法回答“在线学习是否更好”。这类问题只能通过跨市场、跨阶段和相邻参数的稳定性来回答。

第六,逻辑回归的结论不应直接外推到深度模型。复杂模型有更强的表达能力,也有更大的更新自由度;在线更新的噪声风险通常不会因此自动消失。

第七,当前虚拟净值在较高换手成本下快速接近零,导致净收益和最大回撤指标出现饱和。后续研究应同时输出毛收益、累计成本、净对数收益以及每千根 K 线换手,避免不同模型都显示为接近 -100% 后无法继续比较。


结论

市场会变,不等于模型应该在每根 K 线后立即改变。

固定模型承担的是“停留在旧关系里”的风险;逐根在线模型承担的是“过度相信最近样本”的风险。两者之间不存在一个脱离数据、成本和预测目标的普遍答案。

在线更新是否有价值,至少要同时满足三点:

  1. 新环境出现后,预测损失能够更快恢复;
  2. 参数变化没有长期演化为更高的信号翻转和换手;
  3. 改善在成本后仍然存在,并能跨品种、周期和相邻参数重复。

本次默认参数回测中,逐根在线和滚动重训都发生了明显参数移动,却没有降低样本外 Log Loss;误差门控减少了换手和多空翻转,但仍未形成可交易优势。

如果模型只是更新得更勤、参数走得更远、交易做得更多,却没有持续降低样本外损失,那么它并没有更适应市场。

它只是更快地学会了最近发生的事情。

策略代码


风险提示:本文讨论的是在线学习机制和回测方法,不构成投资建议。代码中的收益、成本和仓位均为研究用简化模型,不能替代真实成交、风控和交易所规则。

Related Recommendations
Comment
All comments (0)
No data
No data
  • 1
Forums
PINE Language
Get the app
iPhone Download
© 2015 - ∞ INVENTOR PTE LTD (SG)