跳至正文
全部策略

策略

忠实移植 Hummingbot PMMSimpleController(作者 hummingbot,Apache-2.0):在WLDUSDT.BINANCE 1分钟K线上进行2+2档对称纯做市,围绕中间价设置1%/2%价差,每档配置三重屏障执行器(SL 3%、限价TP 2%、45分钟时限、1.5%/0.3%移动止损),每5分钟刷新,冷却15秒,20x

结局: 已放弃

HummingbotPmmSimpleWld

结局总结

经过四轮迭代,HummingbotPmmSimpleWld 在WLDUSDT根一分钟K线上测试了对称被动做市,并为每个档位设置退出机制。回测产生了10,546个已平仓净头寸,夏普比率为-6.733,收益率为-100%,最终账户清算。回测评估因测得预期收益为负而放弃该策略;参数计划完全冻结,没有获授权的优化路径。

假设

忠实翻译 hummingbot 的 controllers/market_making/pmm_simple.py(PMMSimpleController,提交 9af100d6822da7d2d0291a906c730ef172284ee2,作者:hummingbot,Apache-2.0;原作者应获致谢)。控制器文件仅覆写 get_executor_config()。每条交易规则均来自 MarketMakingControllerBase / MarketMakingControllerConfigBase 中的默认值以及 PositionExecutor 的三重屏障,下面逐一列出,以便开发者逐条翻译。源代码没有作出任何业绩声明;我们的回测将使用真实费用来作出判断。 MARKET(源代码默认值):连接器 binance_perpetual,trading_pair WLD-USDT,映射到 WLDUSDT.BINANCE(USD-M 永续合约,挂单方 0.02% / 吃单方 0.05%),使用 1-MINUTE 柱线。Binance 有 1 分钟的历史数据,可追溯至 2023-07,覆盖 WLD。语料中……展开收起

忠实翻译 hummingbot 的 controllers/market_making/pmm_simple.py(PMMSimpleController,提交 9af100d6822da7d2d0291a906c730ef172284ee2,作者:hummingbot,Apache-2.0;原作者应获致谢)。控制器文件仅覆写 get_executor_config()。每条交易规则均来自 MarketMakingControllerBase / MarketMakingControllerConfigBase 中的默认值以及 PositionExecutor 的三重屏障,下面逐一列出,以便开发者逐条翻译。源代码没有作出任何业绩声明;我们的回测将使用真实费用来作出判断。 MARKET(源代码默认值):连接器 binance_perpetual,trading_pair WLD-USDT,映射到 WLDUSDT.BINANCE(USD-M 永续合约,挂单方 0.02% / 吃单方 0.05%),使用 1-MINUTE 柱线。Binance 有 1 分钟的历史数据,可追溯至 2023-07,覆盖 WLD。语料中 BINANCE 占比过高。忠实移植仍保留它,因为源代码的默认连接器和交易对是 Binance 永续合约 WLD-USDT。语料中很少使用 WLD 本身,而且这种机制在多个方面代表性不足:它同时做多和做空,采用短期周期,并通过在两侧提供被动流动性来做市,每笔订单均设置三重屏障。 LEVELS:buy_spreads [0.01, 0.02] 和 sell_spreads [0.01, 0.02] 共给出四个层级 ID:buy_0、buy_1、sell_0 和 sell_1。优化计划只接受标量,因此这些列表被声明为标量参数 buy_spread_0=0.01、buy_spread_1=0.02、sell_spread_0=0.01 和 sell_spread_1=0.02。buy_amounts_pct 和 sell_amounts_pct 默认为 None,这意味着均匀分配:total_amount_quote 被分为买入侧 50% / 卖出侧 50%,然后在各侧的层级间均匀分配,因此每个层级获得 25%(标量参数 level_amount_pct_buy_0 = buy_1 = sell_0 = sell_1 = 0.25)。参考价格为中间价,且 spread_multiplier = 1,因为 pmm_simple 没有自定义 processed_data。层级价格 = reference_price * (1 - 价差)(买入)和 reference_price * (1 + 价差)(卖出)。层级数量(基础币)= 层级报价金额 / 层级价格。 SIZING(平台适配):源代码的 total_amount_quote 默认值是在 20x 账户上使用 100 USDT。在我们的 $100k 引擎上,执行器创建时 total_amount_quote = total_notional_equity_fraction (1.0) x get_account_equity()。因此,每个层级对应权益名义价值的 25%,单边最大敞口为权益的 50%(单侧两个层级)。config.leverage = 20 是源代码默认值,且不超过 BINANCE 20x 上限;它只设置保证金。使用 make_qty 舍入数量,确保价格 > 0,将名义价值上限设为计算值,并跳过名义价值低于 $5 最低值的任何层级。 EXECUTION SUBSTITUTIONS(来自 context.execution_capabilities): (1) 不支持 hedge_mode(源代码的 position_mode 默认值为 HEDGE),也不支持 per_executor_deadlines。此处使用的等效方案:策略维护一个内部账本,最多跟踪四个 VIRTUAL 执行器,每个层级 ID 对应一个。每个执行器都有自己的入场价格、已成交数量、创建时间戳和屏障。每笔虚拟入场和出场都会作为真实订单发送到单一的 NETTING 仓位。因此,交易场所的净仓位始终等于未平仓虚拟执行器之和;账户盈亏和费用也等于各执行器盈亏和费用之和,因为在对冲模式下,每笔成交同样会是独立订单,并支付相同费用。与对冲模式相比,只有保证金使用量和仓位报告有所不同。 (2) 中间价:此设计不使用报价刻度,因此参考价格为最新 1 分钟柱线的收盘价。 (3) Hummingbot 大约每秒运行一次;我们在每根 1 分钟柱线收盘时进行评估。executor_refresh_time / 300 秒等于 5 根柱线,而 cooldown_time / 15 秒向上取整为 1 根柱线,因此,已关闭的层级可能会在下一根柱线收盘时重新报价。 限价入场单和限价止盈单会留在模拟交易场所中;当柱线内的交易价格穿过其价格时,这些订单便会成交。止损是柱线内的保护性止损:对净仓位下达一笔以减仓为目的的 stop_market 订单,由平台模拟交易场所在柱线内撮合,并同步反映到实盘。检测到时间限制或追踪退出条件的柱线收盘时,以市价单退出。

重试修复:先前的契约在optimization_plan.fixed中将buy_spreads/sell_spreads声明为列表,但计划验证器会因 fixed 值必须是有限标量而拒绝。现在已将列表声明为逐档标量(buy_spread_0、buy_spread_1、sell_spread_0、sell_spread_1、level_amount_pct_*),全部采用来源中的默认值。市场、交易场所和机制不变:使用 hummingbot 自带的默认连接器和交易对,即binance_perpetual WLD-USDT,映射为WLDUSDT.BINANCE。非数值来源设置写在正文中,而非 fixed 中:take_profit_order_type LIMIT、position_mode HEDGE(由净额头寸上的虚拟执行器取代)以及price_type中间价。空的 tunable 对象使其成为忠实的固定默认值实验。

在测得的WLDUSDT分钟忠实移植基准测试中,预期收益为负:PF 0.542,且净头寸平均收益为负,最终导致账户清算。这是由已实现亏损支持的经济性否定结论,而非仅基于回撤,也非对优化失败的预测。冻结的计划没有可调参数。证据不能证明所有做市机制或原版 Hummingbot 实现都不可行。

实现

将 Hummingbot PMMSimpleController 移植到WLDUSDT.BINANCE分钟K线上,每侧设两个被动报价档位,并为每个档位配置独立的虚拟执行器三重屏障。平仓执行器会保留其档位,直至确认平仓成交、收到取消确认且迟到成交完成补偿。保护失败会启动受跟踪的关闭流程。

保留先前实现中的信号、交易品种、仓位规模、价差、屏障和冻结的参数计划。针对第一处 QA 缺陷,通过在部分平仓或平仓被拒时保留执行器敞口、通过已确认的成交跟踪带符号的补偿债务、在后续控制周期重试最终失败的订单,并在所有未结订单结算前阻止层级复用来加以解决。针对第二处缺陷,每个控制周期都核对缺失或尺寸改变的屏障,并在屏障被拒绝、拒绝受理、过期或构建失败后启动有跟踪的关闭流程。订单提交前先登记所有权,以处理同步回调。保留现有的平台适配:用柱线收盘价代替中间价,分钟级控制近似源代码的逐笔计时,并在 NETTING 账户上用真实订单实现虚拟对冲执行器。净仓位报告和虚拟执行器的经济表现需要单独评估;负值的截断沙盒结果不足以判定正确性。未进行独立验证。由于此工作区只允许只读文件系统访问,无法写入所需的发件箱文件;本回复包含完整的任务限定 JSON。

验证结果

终态确认后,安排一次带防护的核对,及时恢复保护或推进有跟踪的关闭流程。避免在反复被拒时形成递归提交循环。

部分成交改变所需保护屏障数量时,会取消两张保护订单。如果取消确认异步到达,_release 会清除其标识符,但不会立即重新核对并设置替代屏障。因此,保护可能一直缺失到下一分钟控制周期。保护屏障遭拒时也会启动关闭流程,但拒绝回调不会立即推进该流程。

保留已完成虚拟执行器的记录,包括实际成交价格、数量、手续费和时间戳;在解读执行器级统计数据前,将已实现与未实现盈亏总额同账户核对。

虚拟账本跟踪敞口和结算,但不会保留已完成执行器的盈亏、手续费或持仓时长。沙盒明确报告的是已平仓NETTING头寸,这些头寸可能合并或抵消多个虚拟执行器。因此,其交易笔数、胜率和平均单笔交易收益无法直接说明该假设下每个执行器的结果。

截断的沙盒中,每个已平仓净头寸的净收益平均为-0.21524%,且模型估算的市场冲击较大。应分别评估完整历史数据下的执行成本和虚拟执行器经济性;净头寸交易并非单个执行器的往返交易。沙盒亏损不能证明实现存在正确性问题。

回测评审

夏普
-6.73
总收益率
-100.00%
最大回撤
100.00%
总交易数
10546
胜率
56.5%
盈利因子
0.54

交易明细确认两个方向均有交易且持仓时间较短,符合预期的双向执行模式;净头寸记录无法验证单个虚拟执行器的经济性。

主要输入审计报告显示,1,639,440根K线无缺口或重复,账户级核算结果一致。

测得预期收益为负:10,546个已平仓净头寸、利润因子0.542、净头寸平均收益-0.2148%、夏普比率-6.733。QA的经济性担忧得到账户层面结果的印证。

账户亏损100%,并于2023-11-13被清算。可用历史数据延伸至2026,但经济表现记录在约113天后结束。

模拟影响合计为 $213,010,佣金为 $58,703。这些成本影响显著;报告并未证明亏损完全由费用造成,也未指出已验证的实现缺陷。

已登记的计划冻结了所有交易参数,且没有可调参数,因此优化没有获授权的改进路径。

已平仓净头寸,而非虚拟执行器的往返交易

分析

语义审计器发现代码与假设不一致——代码并未实现该假设(NOT)。请重写策略,使其实现假设EXACTLY(标的、时间周期、方向、所述优势/机制、仓位规模)。具体问题:遗留敞口:代码注释称,若成交到达时执行器已关闭(TP与SL之间发生同一根K线内的竞态),则会以市价单将其对冲归零。但在on_order_filled中的同级订单取消循环,以及_close_executor和_place_barriers,都会在调用 self._cancel(other) 后立即执行 self._omap.pop(other)。在 NautilusTrader 回测中,取消指令会排队,只有当前K线经过撮合引擎处理(开盘价、最高价、最低价、收盘价)后才会执行。因此,当TP限价单在最高价成交、止损单在最低价触发时,止损单仍会成交。成交时,on_order_filled发现标签为 None……展开收起

语义审计器发现代码与假设不一致——代码并未实现该假设(NOT)。请重写策略,使其实现假设EXACTLY(标的、时间周期、方向、所述优势/机制、仓位规模)。具体问题:遗留敞口:代码注释称,若成交到达时执行器已关闭(TP与SL之间发生同一根K线内的竞态),则会以市价单将其对冲归零。但在on_order_filled中的同级订单取消循环,以及_close_executor和_place_barriers,都会在调用 self._cancel(other) 后立即执行 self._omap.pop(other)。在 NautilusTrader 回测中,取消指令会排队,只有当前K线经过撮合引擎处理(开盘价、最高价、最低价、收盘价)后才会执行。因此,当TP限价单在最高价成交、止损单在最低价触发时,止损单仍会成交。成交时,on_order_filled发现标签为 None 后提前返回,导致对冲归零的市价单从未发出。由于止损单的reduce_only=False,该成交会在20x开立反向头寸,却没有账本记录或保护屏障。随后净头寸不再等于虚拟执行器头寸之和,破坏了假设要求的净额账本等价关系。-100%收益和100%回撤与这些泄漏头寸不断累积的情况相符。 ## 知识库优化建议(来自知识库;应进行测试,不要想当然) 知识库中的做市材料指出,K线数据无法确定K线内的成交顺序。对称报价策略的主要威胁是库存风险,尤其是在趋势行情中逆势报价(单边成交/逆势挂单)。建议设置库存限额并调整价格倾斜、按波动率调整报价、用短期趋势过滤器取消风险一侧的报价,并控制仓位规模。首要修复是让账本在K线数据下保持安全,堵住-100%这次运行中的孤立成交泄漏;其他优化则可降低左偏的亏损特征(60%胜率、PF 0.53)。 1。[退出] 安全处理K线内保护屏障及逐K线账本核对:所有stop_market订单均设reduce_only=True;将已取消订单ID标记为'cancel_pending'并保留,直到收到 OrderCanceled 或 OrderFilled,以便对迟到成交发出对冲市价单;当一根K线同时触及TP和SL时,记入STOP_LOSS;每根K线收盘时,若净头寸与账本差额达到或超过1个仓位增量,则以市价单修正;若在1440根K线内修正次数超过3次,则停止报价60根K线(来源:基于逐笔成交的高频回测系统兼论K线回测的缺陷,第1页) 2。[过滤] 短期趋势过滤器:取消并跳过逆势一侧的报价:若 ret15 > +1.0% 且 close > EMA30,则不挂卖单并取消未成交的卖单;若 ret15 < -1.0% 且 close < EMA30,则买单同理;在任一状态下,均以市价平掉亏损的逆势执行器(来源:浅谈数字货币做市策略(2):盘口策略,第1页;数字货币高频策略详细入门,第1页;加止损可以控制风险……那么,古尔丹,代价是什么呢?,第1页) 3。[仓位规模] 库存上限加报价倾斜:max_inventory = 权益的0.25(不在会增加该库存的一侧新增订单);ref = close * (1 - 0.01 * inv / 0.25)(来源:浅谈数字货币做市策略(2):盘口策略,第1页;行业大佬揭秘算法交易:发明者量化平台做市商策略,第1页) 4。[参数] 按波动率调整价差和保护屏障:spread_0 = max(0.01, 2*ATR60/close),spread_1 = 2*spread_0,TP = spread_0,SL = 3*spread_0,移动止损激活值 = 1.5*spread_0,在执行器创建时固定(来源:行业大佬揭秘算法交易:发明者量化平台做市商策略,第1页;浅谈数字货币做市策略(2):盘口策略,第1页) 5。[仓位规模] 将报价总名义金额降至权益的0.25x:total_notional_equity_fraction = 0.25(来源:行业大佬揭秘算法交易:发明者量化平台做市商策略,第1页;基于逐笔成交的高频回测系统兼论K线回测的缺陷,第1页)

迭代历史

验证失败(第 3 层——沙盒回测):数量的 `value` 无效:由于尺寸增量 0.00000001 和尺寸精度 8,7.275957614183426e-12 被舍入为零 使用的柱线类型:WLDUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL,已处理柱线数:0 请确保你的策略能够基于给定数据和参数产生交易。

正确性方面无需更改。可选地,在诊断中统计对冲归零('n')的成交次数,以便分析师了解竞态发生频率。

TP限价单和SL止损单在on_order_filled内提交。在模拟交易场所中,这些订单可能在触发入场成交的同一根1分钟K线内撮合,使用K线OHLC,且不掌握K线内的价格路径。当TP和SL价格都处于同一根K线的范围内时,结果由交易场所的撮合顺序决定。代码会安全处理这一竞态:第二笔成交会通过市价单对冲,因此账本仍与净头寸一致。代价是多一次市价往返交易,且这些K线中的执行器盈亏只是近似值。

可选择按 eid 记录每个执行器已实现的盈亏和 close_type,以便分析师逐个评估执行器的经济表现。

虚拟执行器的头寸合并为单一NETTING头寸。因此,交易账本记录的是净头寸开仓/平仓周期(沙盒中106个已平仓头寸,来自252笔成交),而不是每个执行器各记一笔。报告的头寸中,同时开仓的多头和空头执行器会相互抵消。avg_trade_return_pct等单笔交易统计和胜率按净头寸周期计算,而非按每个 Hummingbot 执行器计算。

无。

静态分析标记了 min_bars_required 覆写。基类模板将此方法说明为“按需覆写”,因此该覆写是有意为之且无害:策略只需要前一根柱线的收盘价。

验证失败(第4层——QA评审)[类别=code_defect]: - [edge_concern] 截断的沙盒中,每个已平仓净头寸平均为-0.21968%,且模型估算的市场冲击较大。应分别评估完整历史数据的经济性和虚拟执行器核算;这些结果不能决定实现是否正确。 - [严重] _close_executor 在确认市价平仓前移除执行器并取消其保护。带有标签 'c' 的平仓成交会被忽略,被拒绝或拒绝执行的平仓订单无法恢复已移除的执行器。平仓失败或未完成会留下未跟踪敞口,同时该档位还可能创建另一个执行器。带有标签 'n' 的补偿订单失败也会留下无法恢复的敞口。(第257行)——修复:保留平仓执行器,直到确认成交量耗尽其剩余数量。跟踪平仓和补偿数量,处理拒单和未完成成交,并在释放档位之前核对未结敞口。 - [严重] 保护性止损被拒、拒绝或过期时,_release 只会清除 ex['sl']。_control_executor 从不重建缺失的屏障。因此,止损单提交失败的执行器可能一直暴露在风险中,直到触及时间限制或移动止损退出,期间缺少所需的3%保护性止损。止盈单提交失败后也不会恢复。(第352行)——修复:在每个控制周期核对所需屏障,并明确处理提交失败。恢复缺失的保护,或通过受跟踪的关闭流程平掉执行器;不要继续将缺乏保护的执行器视为正常。

保留平仓执行器,直到确认成交量耗尽其剩余数量。跟踪平仓和补偿数量,处理拒单和未完成成交,并在释放档位之前核对未结敞口。

_close_executor 在确认市价平仓之前,会移除执行器并取消其保护。带有“c”标签的平仓成交会被忽略,而被拒绝或拒绝受理的平仓订单无法恢复已移除的执行器。因此,平仓失败或未完成会留下未跟踪的敞口,同时该层级可能创建另一个执行器。带有“n”标签的补偿订单失败,同样会留下无法恢复的敞口。

每个控制周期都核对必需的屏障,并明确处理提交失败。恢复缺失的保护,或通过有跟踪的关闭流程平掉执行器;不要继续将未受保护的执行器视为正常。

保护性止损被拒、拒绝或过期时,_release 只会清除 ex['sl']。_control_executor 从不重建缺失的屏障。因此,止损单提交失败的执行器可能一直暴露在风险中,直到触及时间限制或移动止损退出,期间缺少所需的3%保护性止损。止盈单提交失败后也不会恢复。

结局总结

该基准的账户级亏损足以支持否决,但净仓位结果无法证明单个虚拟执行器的经济表现,也不能推翻原始 Hummingbot 实现。

回测评估结论为放弃,因为已实现亏损表明预期收益为负,且冻结的计划没有可调参数。未进入优化、优化后分析或风险评审阶段。

将 Hummingbot 的 PMMSimpleController 移植到WLDUSDT Binance 永续合约一分钟K线上,以1%/2%价差挂出两档买单和两档卖单,并为每档配置三重屏障退出。

回测记录了 10,546 个已平净仓位、-100% 的回报率、夏普比率 -6.733 和利润因子 0.542。净仓位平均回报率为 -0.2148%,账户在约 113 天后于 2023-11-13 被强平。

分析

PMMSimpleController

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