跳至正文
全部策略

策略

SOL 鲸鱼与散户主动吃单资金流分歧,多空策略(BINANCE USD-M永续合约,TRADE-TICK驱动,15m决策K线,小型激进交易者选择另一侧时交易大型激进交易者所选的一侧,固定名义金额规模划分,低参数)

结局: 已放弃

SolWhaleVsRetailTakerFlowDivergenceLS15m

SOL 鲸鱼与散户主动吃单资金流分歧,多空策略(BINANCE USD-M永续合约,TRADE-TICK驱动,15m决策K线,小型激进交易者选择另一侧时交易大型激进交易者所选的一侧,固定名义金额规模划分,低参数)

假设

一种LONG-SHORT、单一标的的MICROSTRUCTURE策略,运行于SOLUSDT.BINANCE,由TRADE TICKS驱动,而非K线。该信号按TRADE SIZE对主动吃单流进行分层,并交易两个群体之间的DIVERGENCE:当LARGE激进交易者(单笔交易名义金额高于固定USD——机构/鲸鱼资金流)净BUYING,而SMALL激进交易者(散户)净SELLING时,做LONG;当大型激进交易者在散户买入时净SELLING,则做SHORT。这填补了违规最严重的两个配额维度:short_1m_15m周期(4.7%,而目标为>=10%)以及非仅做多方向(long_only为84.1%,而上限为<=55%),并引入了投资组合几乎未使用的一种DATA PRIMITIVE——按规模分层的原始逐笔成交数据。尽管Binance权重过高(74.1%),仍选择该交易场所,这是经过审慎考虑且有充分理由的例外:该策略需要多年期SUB-HOURLY逐笔数据历史,而Hyperliquid在结构上无法提供(其K线API每个周期约提供5000根K线,因此15m仅覆盖约7周),所以若将策略路由至权重不足的交易场所,必然会因历史数据不足而放弃。选择SOL而不是BTC/ETH是为了留出手续费空间:其典型1-3小时波动约为主流币的2x,因此约0.10%的期货往返成本占目标波动的比例要小得多。设计刻意保持精简(4个参数),而关键在于,大型/小型交易的划分采用FIXED USD名义金额阈值,而不是滚动规模百分位——百分位方法要求每根K线都重新排序交易规模缓冲区,这恰好就是导致Layer-3连续五次300超时的每根K线O(n)模式。

零交易结果是DATA-WINDOW故障,而非阈值故障;在做任何改动前,我已分别验证了这两部分判断。(1)沙盒使用1-MINUTE K线运行,其约20千根K线的预算对应一个约28天、截至最新K线的时间窗口;而目录中收集的SOLUSDT.BINANCE逐笔成交历史覆盖2026-04-29..2026-07-17——两者没有交集,因此on_trade_tick从未触发,两个群体的合计值始终为0,分歧值也恒为0.0,任何阈值都无法触发。(2)我在全部收集到的8.54百万条SOL逐笔数据上重放了完全相同的群体逻辑:产生资金流的15m K线有3,331根,数值范围跨越±0.28(large_imb),small_imb为±0.18,分歧p5/p95 = -0.224/+0.195,而CURRENT门槛(entry_thresh 0.18加上严格的散户反向符号条件)在其中430根K线上触发——即12.9%。因此入场逻辑并非过于严格,我有意NOT放宽它,因为这只会增加边际分歧交易,无法覆盖约0.10%的往返成本。需要修正的是决策周期:bar_type从1-MINUTE改为15-MINUTE,这正是该假设标题中所写的设定,其约208天的沙盒窗口也完全覆盖逐笔数据历史。代码改动仅限于记录测得的信号尺度(此前对散户流量±0.05的估计有误),以及增加计数器和一条on_stop诊断信息,用于报告ticks/flow_bars/entry_fires,以便未来的零交易报告能区分资金流缺失与门槛从未触发,而不再将二者混为一谈。除此之外,所有信号、入场、出场和仓位规模逻辑均逐字节不变,_param_bounds现与搜索的参数保持一致。

verification_loop:sandbox_timeout:验证失败(Layer 3 — 沙盒回测):烟雾测试在约20000根K线的窗口(SOLUSDT.BINANCE-15-MINUTE-LAST-EXTERNAL的208天)上超过了300秒的墙钟时间限制。这通常意味着每根K线的工作量会随历史长度增长——例如反复扫描完整的资金费率/补充数据序列,或在每根K线上于calculate_signal()/on_bar()中重建列表并调用min()/sorted()。在__init__中预先计算已排序的时间戳数组ONCE并使用bisect,或按时间戳缓存查找结果,使每根K线的成本为O(log n)而非O(n)。

实现

在 SOLUSDT.BINANCE USD-M 永续合约上的多空逐笔成交微观结构策略,使用 15 分钟决策 K 线。每笔主动吃单交易根据 FIXED USD 名义金额(large_usd)划分为大户流量与散户流量,并对每个队列的有向名义金额失衡在含流量的 15 分钟 K 线回溯窗口内进行累加。交易信号为背离度 large_imbalance - small_imbalance:仅当大户净买入 WHILE 散户净卖出且背离度突破 entry_thresh 时开 LONG,仅在镜像情形下开 SHORT。出场条件包括硬性 1.2% 止损、0.8% 止盈(约为 0.10% 往返吃单成本的若干倍数)、反向背离翻转、12 根 K 线的时间止损,以及在交易已突破 0.15% 后触发的背离塌缩出场。每笔 tick 的计算复杂度为 O(1),每根 K 线为 O(lookback),不使用规模百分位与历史重扫;若窗口内无 tick 流量,则两个失衡均为 0,策略停止运作而非以价格代理替代。

验证结果

sandbox_timeout:验证失败(Layer 3 — 沙盒回测):烟雾测试在约20000根K线的窗口(SOLUSDT.BINANCE-15-MINUTE-LAST-EXTERNAL的208天)上超过了300秒的墙钟时间限制。这通常意味着每根K线的工作量会随历史长度增长——例如反复扫描完整的资金费率/补充数据序列,或在每根K线上于calculate_signal()/on_bar()中重建列表并调用min()/sorted()。在__init__中预先计算已排序的时间戳数组ONCE并使用bisect,或按时间戳缓存查找结果,使每根K线的成本为O(log n)而非O(n)。

迭代历史

验证失败(Layer 3 — 沙盒回测):未产生交易 使用的K线类型:SOLUSDT.BINANCE-15-MINUTE-LAST-EXTERNAL,处理的K线数:204740 诊断信息:should_enter() 在评估的204732根K线上返回了0次方向 -> 你的ENTRY CONDITION从未触发。请放宽入场逻辑/阈值。 请确保你的策略能在给定数据和参数下产生交易。

验证失败(Layer 4 — QA审查): - 假设中指定的入场条件未实现。标题和描述都明确写出了触发条件:'交易大型激进交易者所采取的一侧:当小型激进交易者采取WHEN SMALL AGGRESSORS TAKE THE OTHER SIDE' / '当LARGE激进交易者净BUYING,而SMALL激进交易者净SELLING时,做LONG'。第2次迭代移除了反向符号条件(large_imb > 0 > small_imb),并将其替换为(large_imb > 0)AND(分歧 >= 0.15)。两者并不等价:large_imb=0.50、small_imb=+0.30时,分歧=0.20,会触发LONG,尽管散户与鲸鱼一样净BUYING——这正是假设排除的情形。该策略现在交易的是鲸鱼失衡加相对倾向,而不是鲸鱼与散户之间的分歧,因此实际交易的并非所述优势。注意这造成的方向不对称:135笔空头对比88笔多头。 - 出场结构无法覆盖手续费。没有NO止盈,也没有任何最低波动目标——唯一的出场条件是1.5%硬止损、分歧收敛(|signal| < 0.05)和分歧反转。由于入场要求|divergence| >=……展开收起

验证失败(Layer 4 — QA审查): - 假设中指定的入场条件未实现。标题和描述都明确写出了触发条件:'交易大型激进交易者所采取的一侧:当小型激进交易者采取WHEN SMALL AGGRESSORS TAKE THE OTHER SIDE' / '当LARGE激进交易者净BUYING,而SMALL激进交易者净SELLING时,做LONG'。第2次迭代移除了反向符号条件(large_imb > 0 > small_imb),并将其替换为(large_imb > 0)AND(分歧 >= 0.15)。两者并不等价:large_imb=0.50、small_imb=+0.30时,分歧=0.20,会触发LONG,尽管散户与鲸鱼一样净BUYING——这正是假设排除的情形。该策略现在交易的是鲸鱼失衡加相对倾向,而不是鲸鱼与散户之间的分歧,因此实际交易的并非所述优势。注意这造成的方向不对称:135笔空头对比88笔多头。 - 出场结构无法覆盖手续费。没有NO止盈,也没有任何最低波动目标——唯一的出场条件是1.5%硬止损、分歧收敛(|signal| < 0.05)和分歧反转。由于入场要求|divergence| >= 0.15,而出场在|divergence| < 0.05时触发,仓位会在资金流噪声衰减后平仓,平均持仓约1小时23分钟,却不要求价格波动足以覆盖约0.10%的主动吃单往返成本。沙盒结果确认问题出在结构上:total_commission 19,362 USD = 毛利的94.83%,换手率2788%,avg_trade_return_pct -0.0536%,而期货最低要求为0.15%。 - 假设的核心数据前提并未满足,因此后续结果都不可信。该假设特意将策略路由至Binance,因为策略“需要多年期SUB-HOURLY逐笔数据历史”。开发者自己的理由记载,SOLUSDT.BINANCE逐笔成交数据覆盖约30天(32个parquet文件,2026-06-18..2026-07-17),而K线约有204,740根(约5.8年)——约98.6%的K线没有逐笔资金流,分歧值恒为零。沙盒使用data_days=35运行,产生223笔交易。在35天、223笔交易的微观结构样本上进行优化并通过过拟合/样本外门槛只会产生噪声,而完整历史回测会显示数年权益曲线走平,仅在35天的活跃窗口附近波动,从而扭曲分析人员看到的每一项指标;平坦期为5.8年。 - 杠杆通过getattr(self.config, 'leverage', 1.0)读取。这正是leverage_set_but_unused门槛此前在某策略(AvaxVolatilitySpikeWickRejectionFadeLS15m第1次迭代)中拒绝的写法——静态分析器无法识别getattr访问是在使用杠杆。此处Layer-1已通过,但该门槛在Layer 3之后运行,可能会以同样理由阻止此策略。 - 相对于止损而言,仓位规模较激进:capital_frac杠杆0.5 x 2.0 = 每笔交易使用相当于权益100%的名义金额(沙盒中avg_position_pct 126%),因此1.5%硬止损每次止损交易会造成约3%的权益损失。观察到max_consecutive_losses=14时,这会迅速累积(max_drawdown 59%)。 - 预热期间,如果基础模板没有在min_bars_required之前调用calculate_signal,逐笔数据就会累积到self._cur中,却从未提交或重置,因此第一个已提交的桶可能会聚合任意长时间跨度的资金流。此外,无论是否存在逐笔数据,双端队列都会在每个决策K线上追加一次,因此零资金流K线会悄然稀释滚动窗口(两项失衡值都恰好变为0.0)。

验证失败(Layer 3 — 沙盒回测):未产生交易 使用的K线类型:SOLUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL,处理的K线数:40747 诊断信息:should_enter() 在评估的40687根K线上返回了0次方向 -> 你的ENTRY CONDITION从未触发。请放宽入场逻辑/阈值。 请确保你的策略能在给定数据和参数下产生交易。

Stratmill 是研究与模拟交易工具,不提供财务建议,也不是经纪商。回测与模拟结果均为假设性结果。交易存在亏损风险。