dexbot 1.4.25 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/README.md +6 -2
- package/analysis/README.md +14 -7
- package/analysis/ama_fitting/package.json +1 -1
- package/analysis/analyze_derivatives.ts +1 -1
- package/analysis/bot_key_utils.ts +272 -3
- package/analysis/bot_usage/discover_bot_accounts.ts +64 -9
- package/analysis/bot_usage/kibana_bot_queries.ts +40 -1
- package/analysis/chart_utils.ts +6 -3
- package/analysis/grid_correction_check.ts +56 -20
- package/analysis/resolve_bot_accounts.ts +199 -0
- package/analysis/trade_profitability.ts +36 -8
- package/analysis/tradingview/README.md +25 -0
- package/analysis/tradingview/analyze_tradingview.ts +2 -2
- package/analysis/trend_detection/package.json +1 -1
- package/claw/modules/claw_launcher.ts +5 -4
- package/claw/modules/credit_runtime_adapter.ts +2 -1
- package/claw/modules/dexbot_profiles.ts +4 -3
- package/claw/package.json +1 -1
- package/claw/runtimes/openclaw-plugin/openclaw.plugin.json +1 -1
- package/claw/runtimes/openclaw-plugin/package.json +1 -1
- package/claw/tests/test_claw_mcp_transport.ts +2 -2
- package/dist/analysis/analyze_derivatives.js +1 -1
- package/dist/analysis/bot_key_utils.d.ts +28 -1
- package/dist/analysis/bot_key_utils.d.ts.map +1 -1
- package/dist/analysis/bot_key_utils.js +385 -3
- package/dist/analysis/bot_key_utils.js.map +1 -1
- package/dist/analysis/bot_usage/discover_bot_accounts.js +60 -10
- package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +45 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.js +39 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -1
- package/dist/analysis/chart_utils.d.ts +2 -1
- package/dist/analysis/chart_utils.d.ts.map +1 -1
- package/dist/analysis/chart_utils.js +4 -1
- package/dist/analysis/chart_utils.js.map +1 -1
- package/dist/analysis/grid_correction_check.d.ts.map +1 -1
- package/dist/analysis/grid_correction_check.js +60 -20
- package/dist/analysis/grid_correction_check.js.map +1 -1
- package/dist/analysis/resolve_bot_accounts.d.ts +3 -0
- package/dist/analysis/resolve_bot_accounts.d.ts.map +1 -0
- package/dist/analysis/resolve_bot_accounts.js +216 -0
- package/dist/analysis/resolve_bot_accounts.js.map +1 -0
- package/dist/analysis/trade_profitability.d.ts.map +1 -1
- package/dist/analysis/trade_profitability.js +40 -8
- package/dist/analysis/trade_profitability.js.map +1 -1
- package/dist/analysis/tradingview/analyze_tradingview.js +2 -2
- package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +2 -1
- package/dist/bot.js.map +1 -1
- package/dist/dexbot.d.ts.map +1 -1
- package/dist/dexbot.js +73 -17
- package/dist/dexbot.js.map +1 -1
- package/dist/market_adapter/ama_signal_runner.js +2 -2
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +2 -1
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts +4 -1
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.js +3 -2
- package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
- package/dist/modules/account_bots.d.ts +42 -1
- package/dist/modules/account_bots.d.ts.map +1 -1
- package/dist/modules/account_bots.js +168 -17
- package/dist/modules/account_bots.js.map +1 -1
- package/dist/modules/account_orders.d.ts +7 -1
- package/dist/modules/account_orders.d.ts.map +1 -1
- package/dist/modules/account_orders.js +34 -1
- package/dist/modules/account_orders.js.map +1 -1
- package/dist/modules/bitshares_client.d.ts +4 -1
- package/dist/modules/bitshares_client.d.ts.map +1 -1
- package/dist/modules/bitshares_client.js +12 -4
- package/dist/modules/bitshares_client.js.map +1 -1
- package/dist/modules/bot_settings.d.ts.map +1 -1
- package/dist/modules/bot_settings.js +2 -1
- package/dist/modules/bot_settings.js.map +1 -1
- package/dist/modules/cli_colors.d.ts +39 -0
- package/dist/modules/cli_colors.d.ts.map +1 -0
- package/dist/modules/cli_colors.js +42 -0
- package/dist/modules/cli_colors.js.map +1 -0
- package/dist/modules/constants.d.ts +2 -0
- package/dist/modules/constants.d.ts.map +1 -1
- package/dist/modules/constants.js +27 -11
- package/dist/modules/constants.js.map +1 -1
- package/dist/modules/credit_pricing.d.ts +61 -0
- package/dist/modules/credit_pricing.d.ts.map +1 -0
- package/dist/modules/credit_pricing.js +237 -0
- package/dist/modules/credit_pricing.js.map +1 -0
- package/dist/modules/credit_runtime.d.ts +1 -0
- package/dist/modules/credit_runtime.d.ts.map +1 -1
- package/dist/modules/credit_runtime.js +49 -107
- package/dist/modules/credit_runtime.js.map +1 -1
- package/dist/modules/dexbot_class.d.ts +3 -1
- package/dist/modules/dexbot_class.d.ts.map +1 -1
- package/dist/modules/dexbot_class.js +22 -6
- package/dist/modules/dexbot_class.js.map +1 -1
- package/dist/modules/dexbot_cow_runtime.d.ts +36 -2
- package/dist/modules/dexbot_cow_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_cow_runtime.js +434 -20
- package/dist/modules/dexbot_cow_runtime.js.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.d.ts +15 -16
- package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.js +69 -42
- package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
- package/dist/modules/dexbot_startup_runtime.d.ts +1 -0
- package/dist/modules/dexbot_startup_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_startup_runtime.js +12 -1
- package/dist/modules/dexbot_startup_runtime.js.map +1 -1
- package/dist/modules/dexbot_state_recovery.d.ts.map +1 -1
- package/dist/modules/dexbot_state_recovery.js +7 -0
- package/dist/modules/dexbot_state_recovery.js.map +1 -1
- package/dist/modules/fund_registry.d.ts +1 -1
- package/dist/modules/fund_registry.js +1 -1
- package/dist/modules/launcher/adapter_requirement.d.ts +38 -0
- package/dist/modules/launcher/adapter_requirement.d.ts.map +1 -0
- package/dist/modules/launcher/adapter_requirement.js +141 -0
- package/dist/modules/launcher/adapter_requirement.js.map +1 -0
- package/dist/modules/launcher/bot_supervisor.d.ts +2 -2
- package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -1
- package/dist/modules/launcher/bot_supervisor.js +32 -3
- package/dist/modules/launcher/bot_supervisor.js.map +1 -1
- package/dist/modules/launcher/launch_modes.d.ts.map +1 -1
- package/dist/modules/launcher/launch_modes.js +5 -4
- package/dist/modules/launcher/launch_modes.js.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.d.ts +1 -1
- package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.js +12 -8
- package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
- package/dist/modules/launcher/status_reporting.d.ts +6 -6
- package/dist/modules/launcher/status_reporting.d.ts.map +1 -1
- package/dist/modules/launcher/status_reporting.js +9 -6
- package/dist/modules/launcher/status_reporting.js.map +1 -1
- package/dist/modules/order/accounting.d.ts +34 -0
- package/dist/modules/order/accounting.d.ts.map +1 -1
- package/dist/modules/order/accounting.js +182 -5
- package/dist/modules/order/accounting.js.map +1 -1
- package/dist/modules/order/export.d.ts +1 -1
- package/dist/modules/order/export.js +1 -1
- package/dist/modules/order/grid.d.ts.map +1 -1
- package/dist/modules/order/grid.js +68 -28
- package/dist/modules/order/grid.js.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.d.ts.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.js +72 -0
- package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
- package/dist/modules/order/logger.d.ts +23 -1
- package/dist/modules/order/logger.d.ts.map +1 -1
- package/dist/modules/order/logger.js +60 -17
- package/dist/modules/order/logger.js.map +1 -1
- package/dist/modules/order/manager.d.ts +41 -1
- package/dist/modules/order/manager.d.ts.map +1 -1
- package/dist/modules/order/manager.js +186 -17
- package/dist/modules/order/manager.js.map +1 -1
- package/dist/modules/order/strategy.d.ts.map +1 -1
- package/dist/modules/order/strategy.js +17 -2
- package/dist/modules/order/strategy.js.map +1 -1
- package/dist/modules/order/sync_engine.d.ts.map +1 -1
- package/dist/modules/order/sync_engine.js +59 -9
- package/dist/modules/order/sync_engine.js.map +1 -1
- package/dist/modules/order/utils/math.d.ts +42 -1
- package/dist/modules/order/utils/math.d.ts.map +1 -1
- package/dist/modules/order/utils/math.js +91 -1
- package/dist/modules/order/utils/math.js.map +1 -1
- package/dist/modules/order/utils/order.d.ts +52 -1
- package/dist/modules/order/utils/order.d.ts.map +1 -1
- package/dist/modules/order/utils/order.js +137 -7
- package/dist/modules/order/utils/order.js.map +1 -1
- package/dist/modules/order/utils/system.d.ts +66 -4
- package/dist/modules/order/utils/system.d.ts.map +1 -1
- package/dist/modules/order/utils/system.js +156 -16
- package/dist/modules/order/utils/system.js.map +1 -1
- package/dist/modules/order/utils/validate.d.ts +30 -3
- package/dist/modules/order/utils/validate.d.ts.map +1 -1
- package/dist/modules/order/utils/validate.js +206 -11
- package/dist/modules/order/utils/validate.js.map +1 -1
- package/dist/modules/utils/chain_logs.d.ts +11 -0
- package/dist/modules/utils/chain_logs.d.ts.map +1 -0
- package/dist/modules/utils/chain_logs.js +23 -0
- package/dist/modules/utils/chain_logs.js.map +1 -0
- package/dist/modules/utils/sanitize_key.d.ts +7 -0
- package/dist/modules/utils/sanitize_key.d.ts.map +1 -1
- package/dist/modules/utils/sanitize_key.js +15 -0
- package/dist/modules/utils/sanitize_key.js.map +1 -1
- package/dist/pm2.d.ts +11 -1
- package/dist/pm2.d.ts.map +1 -1
- package/dist/pm2.js +66 -15
- package/dist/pm2.js.map +1 -1
- package/dist/scripts/analyze-credit.d.ts +4 -0
- package/dist/scripts/analyze-credit.d.ts.map +1 -0
- package/dist/scripts/analyze-credit.js +760 -0
- package/dist/scripts/analyze-credit.js.map +1 -0
- package/dist/scripts/analyze-orders.d.ts +1 -10
- package/dist/scripts/analyze-orders.d.ts.map +1 -1
- package/dist/scripts/analyze-orders.js +11 -34
- package/dist/scripts/analyze-orders.js.map +1 -1
- package/dist/scripts/test-credit-renewal.d.ts.map +1 -1
- package/dist/scripts/test-credit-renewal.js +37 -5
- package/dist/scripts/test-credit-renewal.js.map +1 -1
- package/dist/scripts/tv.d.ts +11 -0
- package/dist/scripts/tv.d.ts.map +1 -0
- package/dist/scripts/tv.js +357 -0
- package/dist/scripts/tv.js.map +1 -0
- package/dist/scripts/update.js +77 -10
- package/dist/scripts/update.js.map +1 -1
- package/dist/unlock.d.ts.map +1 -1
- package/dist/unlock.js +20 -8
- package/dist/unlock.js.map +1 -1
- package/docs/DEXBOT_COMPARISON.md +3 -3
- package/docs/EVOLUTION.md +8 -6
- package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +3 -1
- package/docs/GRID_RECONCILE.md +1 -0
- package/docs/LOGGING.md +3 -0
- package/docs/MPA_CREDIT_USAGE.md +3 -1
- package/docs/README.md +2 -2
- package/docs/WORKFLOW.md +3 -1
- package/package.json +2 -1
- package/scripts/README.md +12 -0
|
@@ -19,7 +19,18 @@ declare class COWRebalanceEngine {
|
|
|
19
19
|
assets: any;
|
|
20
20
|
config: any;
|
|
21
21
|
constructor(deps: any);
|
|
22
|
-
execute({ masterGrid, gridVersion, boundaryIdx, funds, fills, excludeIds }: any): Promise<{
|
|
22
|
+
execute({ masterGrid, gridVersion, boundaryIdx, funds, fills, excludeIds, gapSlots, evacStreaks }: any): Promise<{
|
|
23
|
+
actions: never[];
|
|
24
|
+
stateUpdates: never[];
|
|
25
|
+
hadRotation: boolean;
|
|
26
|
+
workingGrid: null;
|
|
27
|
+
workingIndexes: null;
|
|
28
|
+
workingBoundary: null;
|
|
29
|
+
planningDuration: number;
|
|
30
|
+
aborted: boolean;
|
|
31
|
+
reason: any;
|
|
32
|
+
} | {
|
|
33
|
+
evacReady: any;
|
|
23
34
|
actions: any;
|
|
24
35
|
stateUpdates: any;
|
|
25
36
|
hadRotation: any;
|
|
@@ -138,6 +149,8 @@ declare class OrderManager {
|
|
|
138
149
|
_lastFilledSellPrice: number | null;
|
|
139
150
|
_lastFilledPrice: number | null;
|
|
140
151
|
_lastFilledType: string | null;
|
|
152
|
+
_gapEvacStreaks: Map<string, number>;
|
|
153
|
+
_gapEvacCancelQueued: Set<string>;
|
|
141
154
|
_metrics: any;
|
|
142
155
|
private _currentWorkingGridStack;
|
|
143
156
|
_cowEngine: any;
|
|
@@ -644,6 +657,7 @@ declare class OrderManager {
|
|
|
644
657
|
actions: any[];
|
|
645
658
|
aborted: boolean;
|
|
646
659
|
boundaryIdx: any;
|
|
660
|
+
evacReady: any[];
|
|
647
661
|
summary: {
|
|
648
662
|
total: any;
|
|
649
663
|
creates: any;
|
|
@@ -651,6 +665,32 @@ declare class OrderManager {
|
|
|
651
665
|
updates: any;
|
|
652
666
|
};
|
|
653
667
|
};
|
|
668
|
+
/**
|
|
669
|
+
* Phase 3 safety net — turn stuck gap-evacuation candidates (evacReady
|
|
670
|
+
* from the COW reconcile streak tick) into cancel-only corrections.
|
|
671
|
+
*
|
|
672
|
+
* Gate chain per candidate, in order:
|
|
673
|
+
* 1. Slot idx is STILL genuinely in-band under the CURRENT committed
|
|
674
|
+
* boundary/gap geometry (the plan's frozen geometry may be stale).
|
|
675
|
+
* 2. Streak >= GRID_LIMITS.GAP_EVACUATION_CANCEL_THRESHOLD (warn fires
|
|
676
|
+
* one cycle earlier at GAP_EVACUATION_STREAK_THRESHOLD).
|
|
677
|
+
* 3. Queued-once marker (_gapEvacCancelQueued) not set — a queued entry
|
|
678
|
+
* never re-queues until the slot resolves (leaves the band and its
|
|
679
|
+
* streak entry is dropped).
|
|
680
|
+
* 4. No correction entry already exists for the same chain order.
|
|
681
|
+
* 5. The live slot still exists, is on-chain, and still owns that
|
|
682
|
+
* chain order id.
|
|
683
|
+
*
|
|
684
|
+
* The entry uses isSurplus semantics (not bare cancelOnly): the runner
|
|
685
|
+
* cancels the chain order AND settles the slot back to a spread
|
|
686
|
+
* placeholder via convertToSpreadPlaceholder, keeping fund tracking
|
|
687
|
+
* honest and matching Phase 2 band semantics (genuinely in-band slots
|
|
688
|
+
* are SPREAD VIRTUAL). No re-placement, fee-light.
|
|
689
|
+
*
|
|
690
|
+
* @param {Array} candidates - evacReady candidates [{id, idx, type, price, size, orderId}]
|
|
691
|
+
* @returns {number} Number of corrections queued
|
|
692
|
+
*/
|
|
693
|
+
_processGapEvacuationTeeth(candidates: any): number;
|
|
654
694
|
/**
|
|
655
695
|
* Wait (bounded) until any non-COW broadcast/placement activity — the
|
|
656
696
|
* refcounted _broadcastingFlag — has released. Startup/structural
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../modules/order/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../modules/order/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkJH,cAAM,kBAAkB;IACpB,QAAQ,EAAE,GAAG,CAAC;IACd,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE,GAAG,CAAC;gBAEA,IAAI,EAAE,GAAG;IAOf,OAAO,CAAC,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,KAAK,EACL,KAAU,EACV,UAAsB,EACtB,QAAe,EACf,WAAkB,EACrB,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;CA2IT;AAMD,cAAM,YAAY;IACd,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,EAAE,GAAG,CAAC;IAChB,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,GAAG,CAAC;IACjB,UAAU,EAAE,GAAG,CAAC;IAChB,UAAU,EAAE,GAAG,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,GAAG,CAAC;IACV,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,6BAA6B,EAAE,OAAO,CAAC;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,EAAE,GAAG,CAAC;IACzB,wBAAwB,EAAE,GAAG,CAAC;IAC9B,mBAAmB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,yBAAyB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACnK,oBAAoB,EAAE;QAAE,GAAG,EAAE;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAC9H,OAAO,CAAC,kBAAkB,CAA4C;IACtE,OAAO,CAAC,mBAAmB,CAA4C;IACvE,OAAO,CAAC,yBAAyB,CAAc;IAC/C,OAAO,CAAC,0BAA0B,CAAc;IAEhD;;;;;;;;;;;;OAYG;IACH,IAAI,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAc/C;IACD,IAAI,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAGjD;IAED;;;OAGG;IACH,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAchD;IACD,IAAI,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAGlD;IACD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,GAAG,CAAC;IACf,aAAa,EAAE,GAAG,CAAC;IACnB,KAAK,EAAE,GAAG,CAAC;IACX,qBAAqB,EAAE,GAAG,CAAC;IAC3B,qBAAqB,EAAE,GAAG,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,4BAA4B,EAAE,GAAG,EAAE,CAAC;IACpC,cAAc,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,oBAAoB,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpC,kBAAkB,EAAE,GAAG,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;IACf,mBAAmB,EAAE,GAAG,CAAC;IACzB,eAAe,EAAE,GAAG,CAAC;IACrB,SAAS,EAAE,GAAG,CAAC;IACf,SAAS,EAAE,GAAG,CAAC;IACf,wBAAwB,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,iBAAiB,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC;IAC/D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,2BAA2B,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC;IAClE,oBAAoB,EAAE,OAAO,CAAC;IAC9B,qBAAqB,EAAE,GAAG,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B,EAAE,GAAG,CAAC;IACrC,kBAAkB,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,yBAAyB,EAAE,MAAM,CAAC;IAClC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACvD,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAKlC,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,CAAC,wBAAwB,CAAQ;IACxC,UAAU,EAAE,GAAG,CAAC;IAChB,aAAa,EAAE,GAAG,CAAC;IACnB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAE5D;;OAEG;gBACS,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAiI5C,aAAa;IAYb,oBAAoB;IAOpB;;;;;;;;;OASG;IACH,mBAAmB,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,GAAE,GAAU;IASxD;;;;;;;;OAQG;IACH,kBAAkB,CAAC,MAAM,GAAE,GAAU;IAOrC;;;;;;;;OAQG;IACH,sBAAsB,CAAC,WAAW,EAAE,GAAG;IAOvC,kBAAkB,CAAC,KAAK,EAAE,GAAG;IAK7B,2BAA2B;IAM3B;;OAEG;IACH,aAAa;IAIb;;OAEG;IACH,eAAe;IAIf;;;OAGG;IACH,oBAAoB;IAIpB;;;;;;OAMG;IACH,cAAc;IAId;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,GAAG;IAI1B;;;;;;;OAOG;IACH,wBAAwB;IAcxB;;;OAGG;IACH,gBAAgB;IAIhB;;OAEG;IACH,cAAc;IAQd;;OAEG;IACH,eAAe;;;;IA8Bf;;OAEG;IACH,iBAAiB;IAajB;;OAEG;IACH,gBAAgB;IAchB;;;;;OAKG;IACG,UAAU;IAMhB;;;;;;;;;OASG;IACH,qBAAqB;;;;kBAjYD,MAAM;mBAAS,MAAM;oBAAU,MAAM;;;;;;;;;;;IAqZzD;;;OAGG;IACG,oBAAoB,CAAC,SAAS,GAAE,GAAsC;IAwB5E;;;OAGG;IACG,kBAAkB,CAAC,SAAS,EAAE,GAAG;IAKvC;;;;;;;;;;;;OAYG;IACG,2BAA2B,CAAC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;;;;;;;IAiCnE;;;;;;;OAOG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOhD;;;;;;;;;;;;;OAaG;IACG,qBAAqB,CAAC,KAAK,SAAe;IAe1C,iCAAiC;IAIvC;;;OAGG;IACG,gBAAgB,CAAC,MAAM,GAAE,GAA8D;IAMvF,iBAAiB,CAAC,MAAM,EAAE,GAAG;IAiBnC,kCAAkC;IASlC;;OAEG;IACH,uBAAuB;IAyBvB;;OAEG;IACG,gBAAgB;IAMhB,iBAAiB;IAMvB;;;;;;;;;;;;;;;;;;OAkBG;IACH,eAAe;IA0Bf;;;;OAIG;IACG,gBAAgB;IAWtB;;;;;;;;;;;;;OAaG;IACH,kBAAkB;IAelB;;;OAGG;IACH,mBAAmB;IAQnB;;;;OAIG;IACH,kBAAkB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;IAIzC;;;;OAIG;IACH,mBAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG;IAI3C;;;;OAIG;IACH,wBAAwB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG;IAIjD;;;;OAIG;IACG,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAMxC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAI9B,iBAAiB;IAIvB;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,GAAG;IAOxB;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,GAAG;IAM1B;;;OAGG;IACH,aAAa,CAAC,EAAE,EAAE,GAAG;IAUrB,kBAAkB;IASlB,4BAA4B,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;;;;IAW9D,uBAAuB,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;;;IAOnD,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,GAAE,GAAmB,EAAE,OAAO,GAAE,GAAQ;IAOxE,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,GAAE,GAAmB,EAAE,OAAO,GAAE,GAAQ;IAuFnF;;;OAGG;IACH,IAAI,mBAAmB,IAAI,GAAG,CAE7B;IAED,IAAI,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAI/B;IAED,gBAAgB,IAAI,GAAG;IAKvB,kCAAkC,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG;IAiB7D;;;;;OAKG;IACG,oBAAoB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,GAAE,GAAoB,EAAE,OAAO,GAAE,GAAQ;IAmBzF;;;;;;;;OAQG;IACH,cAAc;IAMd;;;OAGG;IACH,eAAe;IAIf;;;;OAIG;IACH,WAAW;IAIX;;;;;;;;;;;;;OAaG;IACG,cAAc,CAAC,YAAY,GAAE,GAAwB;;;;;;;;;;;;;;;;;;;;IAgC3D;;;;;OAKG;IACG,mBAAmB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG;IA8B/D;;OAEG;IACH,0BAA0B;IAiD1B;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG;IAe7C;;;;;;;OAOG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAYlC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK7C;;;;;OAKG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAyB9D;;;;;OAKG;IACH,sBAAsB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IA0CxC;;;;;;OAMG;IACH,4BAA4B,CAAC,eAAe,EAAE,GAAG,GAAG,IAAI;IAmDxD;;OAEG;IACH,yBAAyB;IAMzB;;OAEG;IACH,8BAA8B;IAM9B;;;;OAIG;IACG,oBAAoB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG;IAIvD;;;OAGG;IACG,eAAe,CAAC,OAAO,EAAE,GAAG;IAIlC;;OAEG;IACH,sBAAsB;IAItB;;OAEG;IACH,wBAAwB;;;;;;;;;;;;;;;;;;IAOxB;;;OAGG;IACH,eAAe,CAAC,eAAe,GAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAK;;;;IA+CjE;;OAEG;IACH,4BAA4B;IAW5B;;;;OAIG;IACH,aAAa,CAAC,UAAU,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG;;;;;;;;;;;;IAWlD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,0BAA0B,CAAC,UAAU,EAAE,GAAG;IA6D1C;;;;;;;;;;;;;;;OAeG;IACG,mBAAmB,CAAC,SAAS,GAAE,MAAc,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAmCzH;;;;;;;;OAQG;IACG,oBAAoB,CAAC,KAAK,GAAE,GAAQ,EAAE,UAAU,GAAE,GAAe,EAAE,OAAO,GAAE,GAAQ;IAcpF,sBAAsB,CAAC,KAAK,GAAE,GAAQ,EAAE,UAAU,GAAE,GAAe;IA8CzE,wBAAwB;;;;;IAiClB,kBAAkB,CAAC,WAAW,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,OAAO,GAAE,GAAQ;IAoKxG;;;;OAIG;IACH,+BAA+B,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;;;;;;;IAYjE;;;OAGG;IACH,sBAAsB,CAAC,MAAM,GAAE,GAAiB;IAIhD;;;OAGG;IACH,qBAAqB,CAAC,MAAM,GAAE,GAAU;IASxC;;;;;;;OAOG;IACG,WAAW,CAAC,cAAc,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,GAAG,CAAA;KAAE;;;;;;;;;;;;IAyDvH,IAAI,iBAAiB,QAEpB;IAED,IAAI,iBAAiB,CAAC,KAAK,KAAA,EAO1B;IAED,IAAI,sBAAsB,QAEzB;IAED,IAAI,sBAAsB,CAAC,KAAK,KAAA,EAO/B;IAED,IAAI,cAAc;eA5kEY,MAAM;sBAAgB,MAAM;uBAAiB,MAAM;kBAAY,OAAO;uBAAiB,MAAM;oCAA8B,OAAO;MA8kE/J;IAED,IAAI,cAAc,CAAC,KAAK;eAhlEM,MAAM;sBAAgB,MAAM;uBAAiB,MAAM;kBAAY,OAAO;uBAAiB,MAAM;oCAA8B,OAAO;KAglExI,EAavB;IAED,IAAI,eAAe;aA9lEU;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE;cAAQ;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE;MAgmE1H;IAED,IAAI,eAAe,CAAC,KAAK;aAlmEI;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE;cAAQ;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE;KAkmElG,EAQxB;CAEJ;AAED,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAA"}
|
|
@@ -26,10 +26,10 @@ import StrategyEngine from './strategy.js';
|
|
|
26
26
|
import SyncEngine from './sync_engine.js';
|
|
27
27
|
import { calculateCurrentSpread, checkSpreadCondition, checkGridHealth } from './grid.js';
|
|
28
28
|
import * as Format from './format.js';
|
|
29
|
-
import { ORDER_TYPES, ORDER_STATES, REBALANCE_STATES, DEFAULT_CONFIG, TIMING, LOG_LEVEL, PIPELINE_TIMING, COW_PERFORMANCE, COW_ACTIONS } from '../constants.js';
|
|
29
|
+
import { ORDER_TYPES, ORDER_STATES, REBALANCE_STATES, DEFAULT_CONFIG, TIMING, LOG_LEVEL, PIPELINE_TIMING, COW_PERFORMANCE, COW_ACTIONS, GRID_LIMITS } from '../constants.js';
|
|
30
30
|
import { getMinOrderSize, computeChainFundTotals, hasValidAccountTotals, resolveConfigValueWithRegistry, isExplicitZeroAllocation, floatToBlockchainInt, validateBoundaryCommit, resolveGapSlots } from './utils/math.js';
|
|
31
31
|
import { validateOrder, validateGridForPersistence, validateWorkingGridFunds, checkFundDrift, reconcileGrid, optimizeRebalanceActions, projectTargetToWorkingGrid, buildStateUpdates, buildAbortedResult, buildSuccessResult, evaluateCommit } from './utils/validate.js';
|
|
32
|
-
import { resolveSpreadOrderSide, parseSlotIndex, parseChainOrder } from './utils/order.js';
|
|
32
|
+
import { resolveSpreadOrderSide, parseSlotIndex, parseChainOrder, geometryTypeForSlotIndex, isOrderOnChain } from './utils/order.js';
|
|
33
33
|
import { getErrorMessage } from '../utils/errors.js';
|
|
34
34
|
const { toFiniteNumber } = Format;
|
|
35
35
|
// ===============================================================================
|
|
@@ -133,7 +133,7 @@ class COWRebalanceEngine {
|
|
|
133
133
|
this.assets = deps.assets;
|
|
134
134
|
this.config = deps.config;
|
|
135
135
|
}
|
|
136
|
-
async execute({ masterGrid, gridVersion, boundaryIdx, funds, fills = [], excludeIds = new Set() }) {
|
|
136
|
+
async execute({ masterGrid, gridVersion, boundaryIdx, funds, fills = [], excludeIds = new Set(), gapSlots = null, evacStreaks = null }) {
|
|
137
137
|
const startTime = Date.now();
|
|
138
138
|
const workingGrid = new WorkingGrid(masterGrid, { baseVersion: gridVersion });
|
|
139
139
|
const strategyParams = {
|
|
@@ -149,12 +149,29 @@ class COWRebalanceEngine {
|
|
|
149
149
|
let dustThresholdPercent = this.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE;
|
|
150
150
|
const reconcileResult = reconcileGrid(masterGrid, targetGrid, targetBoundary, {
|
|
151
151
|
logger: (msg, level) => this.logger?.log(msg, level),
|
|
152
|
-
dustThresholdPercent
|
|
152
|
+
dustThresholdPercent,
|
|
153
|
+
gapSlots,
|
|
154
|
+
evacStreaks,
|
|
155
|
+
assets: this.assets
|
|
153
156
|
});
|
|
157
|
+
// Gap-evacuation telemetry: evacReady is the streak-tick output of
|
|
158
|
+
// reconcileGrid (stuck in-band candidates). It must survive both
|
|
159
|
+
// abort and success so the manager can act on it even when the
|
|
160
|
+
// rebalance plan itself aborts for an unrelated reason.
|
|
161
|
+
const evacReady = Array.isArray(reconcileResult?.evacReady)
|
|
162
|
+
? reconcileResult.evacReady
|
|
163
|
+
: [];
|
|
154
164
|
if (reconcileResult.aborted) {
|
|
155
|
-
|
|
165
|
+
const aborted = buildAbortedResult(reconcileResult.reason);
|
|
166
|
+
aborted.evacReady = evacReady;
|
|
167
|
+
return aborted;
|
|
156
168
|
}
|
|
157
|
-
const optimizedActions = optimizeRebalanceActions(reconcileResult.actions, masterGrid
|
|
169
|
+
const optimizedActions = optimizeRebalanceActions(reconcileResult.actions, masterGrid, {
|
|
170
|
+
logger: (msg, level) => this.logger?.log(msg, level),
|
|
171
|
+
boundaryIdx: targetBoundary,
|
|
172
|
+
gapSlots,
|
|
173
|
+
assets: this.assets
|
|
174
|
+
});
|
|
158
175
|
// Stale-placement guard: drop placements crossing the plan's own
|
|
159
176
|
// boundary (see stalePlacementDropReason) — defer them to the next
|
|
160
177
|
// cycle instead of filling immediately.
|
|
@@ -217,13 +234,16 @@ class COWRebalanceEngine {
|
|
|
217
234
|
`price=${Number.isFinite(price) ? Format.formatPrice6(price) : 'n/a'})`;
|
|
218
235
|
this.logger?.log(line, a.type === COW_ACTIONS.UPDATE ? 'info' : 'debug');
|
|
219
236
|
}
|
|
220
|
-
return
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
237
|
+
return {
|
|
238
|
+
...buildSuccessResult({
|
|
239
|
+
actions: optimizedActions,
|
|
240
|
+
stateUpdates,
|
|
241
|
+
workingGrid,
|
|
242
|
+
workingBoundary: targetBoundary,
|
|
243
|
+
planningDuration: duration
|
|
244
|
+
}),
|
|
245
|
+
evacReady
|
|
246
|
+
};
|
|
227
247
|
}
|
|
228
248
|
}
|
|
229
249
|
// ===============================================================================
|
|
@@ -357,6 +377,8 @@ class OrderManager {
|
|
|
357
377
|
_lastFilledSellPrice;
|
|
358
378
|
_lastFilledPrice;
|
|
359
379
|
_lastFilledType;
|
|
380
|
+
_gapEvacStreaks;
|
|
381
|
+
_gapEvacCancelQueued;
|
|
360
382
|
// anchor fields removed
|
|
361
383
|
// Note: dedupe lives inside the anchor object (`_seenKeys`), not here.
|
|
362
384
|
// Kept for backwards compat if external code checks existence; not used.
|
|
@@ -469,6 +491,8 @@ class OrderManager {
|
|
|
469
491
|
this._lastFilledSellPrice = null;
|
|
470
492
|
this._lastFilledPrice = null;
|
|
471
493
|
this._lastFilledType = null;
|
|
494
|
+
this._gapEvacStreaks = new Map();
|
|
495
|
+
this._gapEvacCancelQueued = new Set();
|
|
472
496
|
this._metrics = {
|
|
473
497
|
fundRecalcCount: 0,
|
|
474
498
|
lockAcquisitions: 0,
|
|
@@ -1485,14 +1509,20 @@ class OrderManager {
|
|
|
1485
1509
|
recordLastFilledPrices(fills) {
|
|
1486
1510
|
if (!Array.isArray(fills) || fills.length === 0)
|
|
1487
1511
|
return;
|
|
1512
|
+
let recorded = 0;
|
|
1513
|
+
let lastKind = 'unknown';
|
|
1514
|
+
let lastPriceSrc = 'direct';
|
|
1488
1515
|
for (const f of fills) {
|
|
1489
1516
|
if (!f || (f.type !== ORDER_TYPES.BUY && f.type !== ORDER_TYPES.SELL))
|
|
1490
1517
|
continue;
|
|
1491
1518
|
let price = Number(f.price ?? f.order?.price);
|
|
1519
|
+
let priceSrc = 'direct';
|
|
1492
1520
|
if (!Number.isFinite(price) || price <= 0) {
|
|
1493
1521
|
try {
|
|
1494
1522
|
const slot = f.id ? this.orders?.get?.(f.id) : null;
|
|
1495
1523
|
price = slot ? Number(slot.price) : null;
|
|
1524
|
+
if (Number.isFinite(price) && price > 0)
|
|
1525
|
+
priceSrc = 'slot-fallback';
|
|
1496
1526
|
}
|
|
1497
1527
|
catch {
|
|
1498
1528
|
price = null;
|
|
@@ -1506,6 +1536,22 @@ class OrderManager {
|
|
|
1506
1536
|
this._lastFilledBuyPrice = price;
|
|
1507
1537
|
else if (f.type === ORDER_TYPES.SELL)
|
|
1508
1538
|
this._lastFilledSellPrice = price;
|
|
1539
|
+
recorded++;
|
|
1540
|
+
lastKind = f?.isPartial === true ? 'partial' : (f?.isPartial === false ? 'full' : 'unknown');
|
|
1541
|
+
lastPriceSrc = priceSrc;
|
|
1542
|
+
}
|
|
1543
|
+
// One line per fill batch (chunk): the pivot mutations above are otherwise
|
|
1544
|
+
// silent. src records the kind of the pivot-setting fill (full vs
|
|
1545
|
+
// partial — partial pivots behave differently downstream) and whether
|
|
1546
|
+
// its price came from the fill itself or the invisible slot fallback.
|
|
1547
|
+
if (recorded > 0) {
|
|
1548
|
+
try {
|
|
1549
|
+
const fmt = (v) => (v == null || !Number.isFinite(Number(v)) ? 'none' : Format.formatPrice6(Number(v)));
|
|
1550
|
+
this.logger?.log?.(`[FILL-PIVOT] pivot=${fmt(this._lastFilledPrice)}(${this._lastFilledType}) ` +
|
|
1551
|
+
`buy=${fmt(this._lastFilledBuyPrice)} sell=${fmt(this._lastFilledSellPrice)} ` +
|
|
1552
|
+
`n=${recorded} src=${lastKind}/${lastPriceSrc}`, 'info');
|
|
1553
|
+
}
|
|
1554
|
+
catch { /* logging is best-effort */ }
|
|
1509
1555
|
}
|
|
1510
1556
|
}
|
|
1511
1557
|
/**
|
|
@@ -1516,8 +1562,7 @@ class OrderManager {
|
|
|
1516
1562
|
* @param {Array} chainOpenOrders - raw chain open orders (from readOpenOrdersGuarded)
|
|
1517
1563
|
*/
|
|
1518
1564
|
seedLastFilledPricesFromBook(chainOpenOrders) {
|
|
1519
|
-
|
|
1520
|
-
return;
|
|
1565
|
+
// Already armed — silent (the guard has a live pivot).
|
|
1521
1566
|
if (this._lastFilledPrice != null)
|
|
1522
1567
|
return;
|
|
1523
1568
|
if (this._lastFilledType != null)
|
|
@@ -1525,6 +1570,13 @@ class OrderManager {
|
|
|
1525
1570
|
// Only seed when cold (no fills yet) — don't overwrite a live value.
|
|
1526
1571
|
if (this._lastFilledBuyPrice != null && this._lastFilledSellPrice != null)
|
|
1527
1572
|
return;
|
|
1573
|
+
if (!Array.isArray(chainOpenOrders) || chainOpenOrders.length === 0) {
|
|
1574
|
+
try {
|
|
1575
|
+
this.logger?.log?.(`[LAST-FILL-GUARD] Book seed skipped: no chain orders; guard remains DISABLED (cold) until the first fill`, 'warn');
|
|
1576
|
+
}
|
|
1577
|
+
catch { }
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1528
1580
|
try {
|
|
1529
1581
|
let maxBuy = null;
|
|
1530
1582
|
let minSell = null;
|
|
@@ -1572,6 +1624,16 @@ class OrderManager {
|
|
|
1572
1624
|
}
|
|
1573
1625
|
catch { }
|
|
1574
1626
|
}
|
|
1627
|
+
// A startup that ends with the guard disabled must say so: the
|
|
1628
|
+
// ambiguous seed (both sides present, no real fill yet) leaves
|
|
1629
|
+
// _lastFilledType null by design, and that hole is otherwise only
|
|
1630
|
+
// inferable by the absence of any log line.
|
|
1631
|
+
if (this._lastFilledPrice == null || this._lastFilledType == null) {
|
|
1632
|
+
try {
|
|
1633
|
+
this.logger?.log?.(`[LAST-FILL-GUARD] Book seed left guard DISABLED (cold): lastBuy=${maxBuy} lastSell=${minSell} lastPrice=${this._lastFilledPrice} lastType=${this._lastFilledType}; guard arms on the first fill`, 'warn');
|
|
1634
|
+
}
|
|
1635
|
+
catch { }
|
|
1636
|
+
}
|
|
1575
1637
|
}
|
|
1576
1638
|
catch { }
|
|
1577
1639
|
}
|
|
@@ -1687,11 +1749,101 @@ class OrderManager {
|
|
|
1687
1749
|
* @returns {Object}
|
|
1688
1750
|
*/
|
|
1689
1751
|
reconcileGrid(targetGrid, targetBoundary) {
|
|
1752
|
+
if (!(this._gapEvacStreaks instanceof Map))
|
|
1753
|
+
this._gapEvacStreaks = new Map();
|
|
1690
1754
|
return reconcileGrid(this.orders, targetGrid, targetBoundary, {
|
|
1691
1755
|
logger: (msg, level) => this.logger.log(msg, level),
|
|
1692
|
-
dustThresholdPercent: this.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE
|
|
1756
|
+
dustThresholdPercent: this.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE,
|
|
1757
|
+
gapSlots: this._gapSlots,
|
|
1758
|
+
evacStreaks: this._gapEvacStreaks,
|
|
1759
|
+
assets: this.assets
|
|
1693
1760
|
});
|
|
1694
1761
|
}
|
|
1762
|
+
/**
|
|
1763
|
+
* Phase 3 safety net — turn stuck gap-evacuation candidates (evacReady
|
|
1764
|
+
* from the COW reconcile streak tick) into cancel-only corrections.
|
|
1765
|
+
*
|
|
1766
|
+
* Gate chain per candidate, in order:
|
|
1767
|
+
* 1. Slot idx is STILL genuinely in-band under the CURRENT committed
|
|
1768
|
+
* boundary/gap geometry (the plan's frozen geometry may be stale).
|
|
1769
|
+
* 2. Streak >= GRID_LIMITS.GAP_EVACUATION_CANCEL_THRESHOLD (warn fires
|
|
1770
|
+
* one cycle earlier at GAP_EVACUATION_STREAK_THRESHOLD).
|
|
1771
|
+
* 3. Queued-once marker (_gapEvacCancelQueued) not set — a queued entry
|
|
1772
|
+
* never re-queues until the slot resolves (leaves the band and its
|
|
1773
|
+
* streak entry is dropped).
|
|
1774
|
+
* 4. No correction entry already exists for the same chain order.
|
|
1775
|
+
* 5. The live slot still exists, is on-chain, and still owns that
|
|
1776
|
+
* chain order id.
|
|
1777
|
+
*
|
|
1778
|
+
* The entry uses isSurplus semantics (not bare cancelOnly): the runner
|
|
1779
|
+
* cancels the chain order AND settles the slot back to a spread
|
|
1780
|
+
* placeholder via convertToSpreadPlaceholder, keeping fund tracking
|
|
1781
|
+
* honest and matching Phase 2 band semantics (genuinely in-band slots
|
|
1782
|
+
* are SPREAD VIRTUAL). No re-placement, fee-light.
|
|
1783
|
+
*
|
|
1784
|
+
* @param {Array} candidates - evacReady candidates [{id, idx, type, price, size, orderId}]
|
|
1785
|
+
* @returns {number} Number of corrections queued
|
|
1786
|
+
*/
|
|
1787
|
+
_processGapEvacuationTeeth(candidates) {
|
|
1788
|
+
if (!Array.isArray(candidates) || candidates.length === 0)
|
|
1789
|
+
return 0;
|
|
1790
|
+
if (!Array.isArray(this.ordersNeedingPriceCorrection))
|
|
1791
|
+
return 0;
|
|
1792
|
+
if (!(this._gapEvacStreaks instanceof Map))
|
|
1793
|
+
this._gapEvacStreaks = new Map();
|
|
1794
|
+
if (!(this._gapEvacCancelQueued instanceof Set))
|
|
1795
|
+
this._gapEvacCancelQueued = new Set();
|
|
1796
|
+
// Release queued-once markers for slots that resolved (dropped from
|
|
1797
|
+
// the streak map) so a future return to the band can be acted on again.
|
|
1798
|
+
for (const id of Array.from(this._gapEvacCancelQueued)) {
|
|
1799
|
+
if (!this._gapEvacStreaks.has(id))
|
|
1800
|
+
this._gapEvacCancelQueued.delete(id);
|
|
1801
|
+
}
|
|
1802
|
+
const rawThreshold = Number(GRID_LIMITS?.GAP_EVACUATION_CANCEL_THRESHOLD);
|
|
1803
|
+
const cancelThreshold = Number.isFinite(rawThreshold) && rawThreshold > 0 ? Math.floor(rawThreshold) : 3;
|
|
1804
|
+
const boundary = this.boundaryIdx;
|
|
1805
|
+
const gapSlots = this._gapSlots;
|
|
1806
|
+
let queued = 0;
|
|
1807
|
+
for (const candidate of candidates) {
|
|
1808
|
+
const slotId = candidate?.id;
|
|
1809
|
+
const chainOrderId = candidate?.orderId;
|
|
1810
|
+
if (!slotId || !chainOrderId)
|
|
1811
|
+
continue;
|
|
1812
|
+
// 1. Re-verify geometry against the CURRENT committed boundary.
|
|
1813
|
+
const idx = parseSlotIndex(slotId);
|
|
1814
|
+
if (idx === null || geometryTypeForSlotIndex(idx, boundary, gapSlots) !== ORDER_TYPES.SPREAD)
|
|
1815
|
+
continue;
|
|
1816
|
+
// 2. Act threshold (stricter than the warn threshold).
|
|
1817
|
+
if (Number(this._gapEvacStreaks.get(slotId) || 0) < cancelThreshold)
|
|
1818
|
+
continue;
|
|
1819
|
+
// 3./4. Queued-once + no duplicate chain-order entry.
|
|
1820
|
+
if (this._gapEvacCancelQueued.has(slotId))
|
|
1821
|
+
continue;
|
|
1822
|
+
if (this.ordersNeedingPriceCorrection.some((entry) => entry?.chainOrderId === chainOrderId))
|
|
1823
|
+
continue;
|
|
1824
|
+
// 5. Live slot check.
|
|
1825
|
+
const slot = this.orders.get(slotId);
|
|
1826
|
+
if (!slot || !isOrderOnChain(slot) || slot.orderId !== chainOrderId)
|
|
1827
|
+
continue;
|
|
1828
|
+
this.ordersNeedingPriceCorrection.push({
|
|
1829
|
+
gridOrder: { ...slot },
|
|
1830
|
+
chainOrderId,
|
|
1831
|
+
expectedPrice: slot.price,
|
|
1832
|
+
actualPrice: slot.price,
|
|
1833
|
+
size: slot.size,
|
|
1834
|
+
type: slot.type,
|
|
1835
|
+
isSurplus: true,
|
|
1836
|
+
gapEvacuation: true,
|
|
1837
|
+
boundaryIdx: boundary
|
|
1838
|
+
});
|
|
1839
|
+
this._gapEvacCancelQueued.add(slotId);
|
|
1840
|
+
queued++;
|
|
1841
|
+
this.logger?.log?.(`[GAP-EVAC] Queued cancel-only evacuation for ${slotId} ` +
|
|
1842
|
+
`(${slot.type} @${Format.formatPrice6(slot.price)}, ` +
|
|
1843
|
+
`x${this._gapEvacStreaks.get(slotId)} in band, boundary ${boundary}, gap ${gapSlots})`, 'warn');
|
|
1844
|
+
}
|
|
1845
|
+
return queued;
|
|
1846
|
+
}
|
|
1695
1847
|
/**
|
|
1696
1848
|
* Wait (bounded) until any non-COW broadcast/placement activity — the
|
|
1697
1849
|
* refcounted _broadcastingFlag — has released. Startup/structural
|
|
@@ -1762,14 +1914,31 @@ class OrderManager {
|
|
|
1762
1914
|
return buildAbortedResult('COW Engine not initialized (assets not available)');
|
|
1763
1915
|
}
|
|
1764
1916
|
this._setRebalanceState(REBALANCE_STATES.REBALANCING);
|
|
1917
|
+
if (!(this._gapEvacStreaks instanceof Map))
|
|
1918
|
+
this._gapEvacStreaks = new Map();
|
|
1919
|
+
if (!(this._gapEvacCancelQueued instanceof Set))
|
|
1920
|
+
this._gapEvacCancelQueued = new Set();
|
|
1765
1921
|
const result = await cowEngine.execute({
|
|
1766
1922
|
masterGrid: this.orders,
|
|
1767
1923
|
gridVersion: this._gridVersion,
|
|
1768
1924
|
boundaryIdx: this.boundaryIdx,
|
|
1769
1925
|
funds: this.getChainFundsSnapshot(),
|
|
1770
1926
|
fills,
|
|
1771
|
-
excludeIds
|
|
1927
|
+
excludeIds,
|
|
1928
|
+
gapSlots: this._gapSlots,
|
|
1929
|
+
evacStreaks: this._gapEvacStreaks
|
|
1772
1930
|
});
|
|
1931
|
+
// Phase 3 safety net: act on stuck in-band orders regardless of the
|
|
1932
|
+
// plan outcome — a plan that aborted for unrelated reasons must not
|
|
1933
|
+
// delay the cancel-only evacuation queue. Queued-once per slot; the
|
|
1934
|
+
// corrections runner (correctAllPriceMismatches) executes the cancel
|
|
1935
|
+
// and settles the slot back to a spread placeholder.
|
|
1936
|
+
try {
|
|
1937
|
+
this._processGapEvacuationTeeth(result?.evacReady);
|
|
1938
|
+
}
|
|
1939
|
+
catch (gapEvacError) {
|
|
1940
|
+
this.logger?.log?.(`[GAP-EVAC] Teeth processing failed (non-fatal): ${getErrorMessage(gapEvacError)}`, 'warn');
|
|
1941
|
+
}
|
|
1773
1942
|
if (result.aborted) {
|
|
1774
1943
|
// Nothing was pushed for an aborted result — the push below is
|
|
1775
1944
|
// skipped — so there is no working-grid ref to clear here. Popping
|