dexbot 1.1.10
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/LICENSE +21 -0
- package/README.md +287 -0
- package/claw/README.md +513 -0
- package/claw/scripts/memu_runner.py +385 -0
- package/claw/skills/bitshares-guide/SKILL.md +14 -0
- package/claw/skills/bitshares-guide/references/example-skill-shells.md +18 -0
- package/claw/skills/bitshares-guide/references/presentation-patterns.md +19 -0
- package/claw/skills/bitshares-guide/references/scope-guardrails.md +9 -0
- package/claw/skills/launcher-ops/SKILL.md +18 -0
- package/claw/skills/launcher-ops/references/launcher-workflow.md +23 -0
- package/claw/skills/margin-trading/SKILL.md +23 -0
- package/claw/skills/margin-trading/references/honest-asset-list.md +74 -0
- package/claw/skills/margin-trading/references/honest-assets.md +44 -0
- package/claw/skills/margin-trading/references/position-management.md +203 -0
- package/claw/skills/margin-trading/references/trading-concepts.md +80 -0
- package/claw/skills/memu-memory/SKILL.md +218 -0
- package/claw/skills/shared/references/js-automation-overview.md +24 -0
- package/claw/skills/shared/references/safety-and-staleness.md +11 -0
- package/claw/skills/shared/references/skill-boundaries.md +17 -0
- package/claw/skills/trend-detection/SKILL.md +33 -0
- package/claw/skills/trend-detection/agents/openai.yaml +3 -0
- package/claw/skills/trend-detection/references/service.md +45 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts +3 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.js +149 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.js.map +1 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts +3 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js +387 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js.map +1 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts +3 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js +200 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +1 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts +3 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.js +212 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +1 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts +31 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js +249 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js.map +1 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts +2 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.js +782 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.js.map +1 -0
- package/dist/analysis/analyze_derivatives.d.ts +95 -0
- package/dist/analysis/analyze_derivatives.d.ts.map +1 -0
- package/dist/analysis/analyze_derivatives.js +295 -0
- package/dist/analysis/analyze_derivatives.js.map +1 -0
- package/dist/analysis/analyze_dynamic_weight.d.ts +14 -0
- package/dist/analysis/analyze_dynamic_weight.d.ts.map +1 -0
- package/dist/analysis/analyze_dynamic_weight.js +208 -0
- package/dist/analysis/analyze_dynamic_weight.js.map +1 -0
- package/dist/analysis/analyze_kalman.d.ts +13 -0
- package/dist/analysis/analyze_kalman.d.ts.map +1 -0
- package/dist/analysis/analyze_kalman.js +123 -0
- package/dist/analysis/analyze_kalman.js.map +1 -0
- package/dist/analysis/analyze_regime.d.ts +20 -0
- package/dist/analysis/analyze_regime.d.ts.map +1 -0
- package/dist/analysis/analyze_regime.js +139 -0
- package/dist/analysis/analyze_regime.js.map +1 -0
- package/dist/analysis/analyze_regime_windows.d.ts +19 -0
- package/dist/analysis/analyze_regime_windows.d.ts.map +1 -0
- package/dist/analysis/analyze_regime_windows.js +413 -0
- package/dist/analysis/analyze_regime_windows.js.map +1 -0
- package/dist/analysis/analyze_risk_profile.d.ts +3 -0
- package/dist/analysis/analyze_risk_profile.d.ts.map +1 -0
- package/dist/analysis/analyze_risk_profile.js +159 -0
- package/dist/analysis/analyze_risk_profile.js.map +1 -0
- package/dist/analysis/analyze_trade_heatmap.d.ts +3 -0
- package/dist/analysis/analyze_trade_heatmap.d.ts.map +1 -0
- package/dist/analysis/analyze_trade_heatmap.js +367 -0
- package/dist/analysis/analyze_trade_heatmap.js.map +1 -0
- package/dist/analysis/analyze_volatility.d.ts +22 -0
- package/dist/analysis/analyze_volatility.d.ts.map +1 -0
- package/dist/analysis/analyze_volatility.js +172 -0
- package/dist/analysis/analyze_volatility.js.map +1 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts +99 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts.map +1 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.js +804 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.js.map +1 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts +2 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts.map +1 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.js +347 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.js.map +1 -0
- package/dist/analysis/bot_fitting/shared_utils.d.ts +15 -0
- package/dist/analysis/bot_fitting/shared_utils.d.ts.map +1 -0
- package/dist/analysis/bot_fitting/shared_utils.js +48 -0
- package/dist/analysis/bot_fitting/shared_utils.js.map +1 -0
- package/dist/analysis/bot_key_utils.d.ts +16 -0
- package/dist/analysis/bot_key_utils.d.ts.map +1 -0
- package/dist/analysis/bot_key_utils.js +61 -0
- package/dist/analysis/bot_key_utils.js.map +1 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.d.ts +3 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.d.ts.map +1 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.js +498 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +546 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.js +427 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -0
- package/dist/analysis/chart_utils.d.ts +13 -0
- package/dist/analysis/chart_utils.d.ts.map +1 -0
- package/dist/analysis/chart_utils.js +142 -0
- package/dist/analysis/chart_utils.js.map +1 -0
- package/dist/analysis/derivative_chart_generator.d.ts +18 -0
- package/dist/analysis/derivative_chart_generator.d.ts.map +1 -0
- package/dist/analysis/derivative_chart_generator.js +896 -0
- package/dist/analysis/derivative_chart_generator.js.map +1 -0
- package/dist/analysis/math_utils.d.ts +35 -0
- package/dist/analysis/math_utils.d.ts.map +1 -0
- package/dist/analysis/math_utils.js +121 -0
- package/dist/analysis/math_utils.js.map +1 -0
- package/dist/analysis/price_sources.d.ts +34 -0
- package/dist/analysis/price_sources.d.ts.map +1 -0
- package/dist/analysis/price_sources.js +103 -0
- package/dist/analysis/price_sources.js.map +1 -0
- package/dist/analysis/trade_profitability.d.ts +115 -0
- package/dist/analysis/trade_profitability.d.ts.map +1 -0
- package/dist/analysis/trade_profitability.js +1247 -0
- package/dist/analysis/trade_profitability.js.map +1 -0
- package/dist/analysis/tradingview/analyze_tradingview.d.ts +38 -0
- package/dist/analysis/tradingview/analyze_tradingview.d.ts.map +1 -0
- package/dist/analysis/tradingview/analyze_tradingview.js +212 -0
- package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +9 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +1717 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts +250 -0
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/derivative_analyzer.js +903 -0
- package/dist/analysis/trend_detection/derivative_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +1449 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/hurst_analyzer.d.ts +42 -0
- package/dist/analysis/trend_detection/hurst_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/hurst_analyzer.js +159 -0
- package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.js +408 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts +103 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.js +229 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts +34 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts.map +1 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.js +89 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.js.map +1 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts +39 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.js +132 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/regime_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/regime_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/regime_chart_generator.js +345 -0
- package/dist/analysis/trend_detection/regime_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts +2 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.js +130 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.js.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts +2 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js +38 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js.map +1 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.js +732 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.js.map +1 -0
- package/dist/bot.d.ts +49 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +221 -0
- package/dist/bot.js.map +1 -0
- package/dist/credential-daemon.d.ts +64 -0
- package/dist/credential-daemon.d.ts.map +1 -0
- package/dist/credential-daemon.js +987 -0
- package/dist/credential-daemon.js.map +1 -0
- package/dist/dexbot.d.ts +87 -0
- package/dist/dexbot.d.ts.map +1 -0
- package/dist/dexbot.js +1222 -0
- package/dist/dexbot.js.map +1 -0
- package/dist/market_adapter/ama_signal_runner.d.ts +3 -0
- package/dist/market_adapter/ama_signal_runner.d.ts.map +1 -0
- package/dist/market_adapter/ama_signal_runner.js +175 -0
- package/dist/market_adapter/ama_signal_runner.js.map +1 -0
- package/dist/market_adapter/candle_utils.d.ts +57 -0
- package/dist/market_adapter/candle_utils.d.ts.map +1 -0
- package/dist/market_adapter/candle_utils.js +252 -0
- package/dist/market_adapter/candle_utils.js.map +1 -0
- package/dist/market_adapter/core/asymmetric_bounds.d.ts +20 -0
- package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -0
- package/dist/market_adapter/core/asymmetric_bounds.js +88 -0
- package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -0
- package/dist/market_adapter/core/config_normalizers.d.ts +10 -0
- package/dist/market_adapter/core/config_normalizers.d.ts.map +1 -0
- package/dist/market_adapter/core/config_normalizers.js +24 -0
- package/dist/market_adapter/core/config_normalizers.js.map +1 -0
- package/dist/market_adapter/core/kibana_candles.d.ts +74 -0
- package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -0
- package/dist/market_adapter/core/kibana_candles.js +249 -0
- package/dist/market_adapter/core/kibana_candles.js.map +1 -0
- package/dist/market_adapter/core/kibana_client.d.ts +27 -0
- package/dist/market_adapter/core/kibana_client.d.ts.map +1 -0
- package/dist/market_adapter/core/kibana_client.js +120 -0
- package/dist/market_adapter/core/kibana_client.js.map +1 -0
- package/dist/market_adapter/core/kibana_market_candles.d.ts +143 -0
- package/dist/market_adapter/core/kibana_market_candles.d.ts.map +1 -0
- package/dist/market_adapter/core/kibana_market_candles.js +170 -0
- package/dist/market_adapter/core/kibana_market_candles.js.map +1 -0
- package/dist/market_adapter/core/market_adapter_service.d.ts +210 -0
- package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -0
- package/dist/market_adapter/core/market_adapter_service.js +2328 -0
- package/dist/market_adapter/core/market_adapter_service.js.map +1 -0
- package/dist/market_adapter/core/strategies/ama.d.ts +2 -0
- package/dist/market_adapter/core/strategies/ama.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/ama.js +138 -0
- package/dist/market_adapter/core/strategies/ama.js.map +1 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.d.ts +50 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.js +143 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -0
- package/dist/market_adapter/core/strategies/atr/calculator.d.ts +12 -0
- package/dist/market_adapter/core/strategies/atr/calculator.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/atr/calculator.js +47 -0
- package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -0
- package/dist/market_adapter/core/strategies/collateral_manager.d.ts +32 -0
- package/dist/market_adapter/core/strategies/collateral_manager.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/collateral_manager.js +68 -0
- package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -0
- package/dist/market_adapter/core/strategies/regime_gate.d.ts +66 -0
- package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/regime_gate.js +189 -0
- package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -0
- package/dist/market_adapter/index.d.ts +10 -0
- package/dist/market_adapter/index.d.ts.map +1 -0
- package/dist/market_adapter/index.js +71 -0
- package/dist/market_adapter/index.js.map +1 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts +3 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts.map +1 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +1165 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -0
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts +54 -0
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -0
- package/dist/market_adapter/inputs/fetch_lp_data.js +743 -0
- package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -0
- package/dist/market_adapter/inputs/kibana_source.d.ts +68 -0
- package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -0
- package/dist/market_adapter/inputs/kibana_source.js +143 -0
- package/dist/market_adapter/inputs/kibana_source.js.map +1 -0
- package/dist/market_adapter/interval_utils.d.ts +6 -0
- package/dist/market_adapter/interval_utils.d.ts.map +1 -0
- package/dist/market_adapter/interval_utils.js +14 -0
- package/dist/market_adapter/interval_utils.js.map +1 -0
- package/dist/market_adapter/log_format.d.ts +16 -0
- package/dist/market_adapter/log_format.d.ts.map +1 -0
- package/dist/market_adapter/log_format.js +72 -0
- package/dist/market_adapter/log_format.js.map +1 -0
- package/dist/market_adapter/lp_chart_core.d.ts +6 -0
- package/dist/market_adapter/lp_chart_core.d.ts.map +1 -0
- package/dist/market_adapter/lp_chart_core.js +874 -0
- package/dist/market_adapter/lp_chart_core.js.map +1 -0
- package/dist/market_adapter/lp_chart_runner.d.ts +135 -0
- package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -0
- package/dist/market_adapter/lp_chart_runner.js +337 -0
- package/dist/market_adapter/lp_chart_runner.js.map +1 -0
- package/dist/market_adapter/lp_chart_strategy_loader.d.ts +23 -0
- package/dist/market_adapter/lp_chart_strategy_loader.d.ts.map +1 -0
- package/dist/market_adapter/lp_chart_strategy_loader.js +169 -0
- package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -0
- package/dist/market_adapter/market_adapter.d.ts +133 -0
- package/dist/market_adapter/market_adapter.d.ts.map +1 -0
- package/dist/market_adapter/market_adapter.js +1331 -0
- package/dist/market_adapter/market_adapter.js.map +1 -0
- package/dist/market_adapter/merge_lp_data.d.ts +3 -0
- package/dist/market_adapter/merge_lp_data.d.ts.map +1 -0
- package/dist/market_adapter/merge_lp_data.js +125 -0
- package/dist/market_adapter/merge_lp_data.js.map +1 -0
- package/dist/market_adapter/test_helpers.d.ts +14 -0
- package/dist/market_adapter/test_helpers.d.ts.map +1 -0
- package/dist/market_adapter/test_helpers.js +22 -0
- package/dist/market_adapter/test_helpers.js.map +1 -0
- package/dist/market_adapter/utils/adapter_client.d.ts +20 -0
- package/dist/market_adapter/utils/adapter_client.d.ts.map +1 -0
- package/dist/market_adapter/utils/adapter_client.js +88 -0
- package/dist/market_adapter/utils/adapter_client.js.map +1 -0
- package/dist/market_adapter/utils/atomic_write.d.ts +9 -0
- package/dist/market_adapter/utils/atomic_write.d.ts.map +1 -0
- package/dist/market_adapter/utils/atomic_write.js +13 -0
- package/dist/market_adapter/utils/atomic_write.js.map +1 -0
- package/dist/market_adapter/utils/chain.d.ts +50 -0
- package/dist/market_adapter/utils/chain.d.ts.map +1 -0
- package/dist/market_adapter/utils/chain.js +196 -0
- package/dist/market_adapter/utils/chain.js.map +1 -0
- package/dist/market_adapter/utils/data_discovery.d.ts +6 -0
- package/dist/market_adapter/utils/data_discovery.d.ts.map +1 -0
- package/dist/market_adapter/utils/data_discovery.js +35 -0
- package/dist/market_adapter/utils/data_discovery.js.map +1 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts +15 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js +60 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -0
- package/dist/market_adapter/utils/file_lock.d.ts +19 -0
- package/dist/market_adapter/utils/file_lock.d.ts.map +1 -0
- package/dist/market_adapter/utils/file_lock.js +191 -0
- package/dist/market_adapter/utils/file_lock.js.map +1 -0
- package/dist/market_adapter/utils/native_history.d.ts +19 -0
- package/dist/market_adapter/utils/native_history.d.ts.map +1 -0
- package/dist/market_adapter/utils/native_history.js +172 -0
- package/dist/market_adapter/utils/native_history.js.map +1 -0
- package/dist/market_adapter/utils/paths.d.ts +5 -0
- package/dist/market_adapter/utils/paths.d.ts.map +1 -0
- package/dist/market_adapter/utils/paths.js +7 -0
- package/dist/market_adapter/utils/paths.js.map +1 -0
- package/dist/modules/account_bots.d.ts +112 -0
- package/dist/modules/account_bots.d.ts.map +1 -0
- package/dist/modules/account_bots.js +1259 -0
- package/dist/modules/account_bots.js.map +1 -0
- package/dist/modules/account_orders.d.ts +273 -0
- package/dist/modules/account_orders.d.ts.map +1 -0
- package/dist/modules/account_orders.js +662 -0
- package/dist/modules/account_orders.js.map +1 -0
- package/dist/modules/authority_resolver.d.ts +2 -0
- package/dist/modules/authority_resolver.d.ts.map +1 -0
- package/dist/modules/authority_resolver.js +231 -0
- package/dist/modules/authority_resolver.js.map +1 -0
- package/dist/modules/bitshares-native/chain_client.d.ts +38 -0
- package/dist/modules/bitshares-native/chain_client.d.ts.map +1 -0
- package/dist/modules/bitshares-native/chain_client.js +322 -0
- package/dist/modules/bitshares-native/chain_client.js.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts +59 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.js +456 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.d.ts +66 -0
- package/dist/modules/bitshares-native/crypto/ecc.d.ts.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.js +557 -0
- package/dist/modules/bitshares-native/crypto/ecc.js.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts +2 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.js +20 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -0
- package/dist/modules/bitshares-native/index.d.ts +3 -0
- package/dist/modules/bitshares-native/index.d.ts.map +1 -0
- package/dist/modules/bitshares-native/index.js +32 -0
- package/dist/modules/bitshares-native/index.js.map +1 -0
- package/dist/modules/bitshares-native/resolvers.d.ts +40 -0
- package/dist/modules/bitshares-native/resolvers.d.ts.map +1 -0
- package/dist/modules/bitshares-native/resolvers.js +161 -0
- package/dist/modules/bitshares-native/resolvers.js.map +1 -0
- package/dist/modules/bitshares-native/serial/chain_constants.d.ts +56 -0
- package/dist/modules/bitshares-native/serial/chain_constants.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/chain_constants.js +92 -0
- package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -0
- package/dist/modules/bitshares-native/serial/index.d.ts +10 -0
- package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/index.js +14 -0
- package/dist/modules/bitshares-native/serial/index.js.map +1 -0
- package/dist/modules/bitshares-native/serial/operations.d.ts +102 -0
- package/dist/modules/bitshares-native/serial/operations.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/operations.js +615 -0
- package/dist/modules/bitshares-native/serial/operations.js.map +1 -0
- package/dist/modules/bitshares-native/serial/serializer.d.ts +64 -0
- package/dist/modules/bitshares-native/serial/serializer.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/serializer.js +252 -0
- package/dist/modules/bitshares-native/serial/serializer.js.map +1 -0
- package/dist/modules/bitshares-native/serial/types.d.ts +120 -0
- package/dist/modules/bitshares-native/serial/types.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/types.js +837 -0
- package/dist/modules/bitshares-native/serial/types.js.map +1 -0
- package/dist/modules/bitshares-native/signing_client.d.ts +6 -0
- package/dist/modules/bitshares-native/signing_client.d.ts.map +1 -0
- package/dist/modules/bitshares-native/signing_client.js +141 -0
- package/dist/modules/bitshares-native/signing_client.js.map +1 -0
- package/dist/modules/bitshares-native/subscriptions.d.ts +6 -0
- package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -0
- package/dist/modules/bitshares-native/subscriptions.js +865 -0
- package/dist/modules/bitshares-native/subscriptions.js.map +1 -0
- package/dist/modules/bitshares-native/transport.d.ts +51 -0
- package/dist/modules/bitshares-native/transport.d.ts.map +1 -0
- package/dist/modules/bitshares-native/transport.js +447 -0
- package/dist/modules/bitshares-native/transport.js.map +1 -0
- package/dist/modules/bitshares-native/tx/builder.d.ts +30 -0
- package/dist/modules/bitshares-native/tx/builder.d.ts.map +1 -0
- package/dist/modules/bitshares-native/tx/builder.js +262 -0
- package/dist/modules/bitshares-native/tx/builder.js.map +1 -0
- package/dist/modules/bitshares_client.d.ts +129 -0
- package/dist/modules/bitshares_client.d.ts.map +1 -0
- package/dist/modules/bitshares_client.js +627 -0
- package/dist/modules/bitshares_client.js.map +1 -0
- package/dist/modules/bot_settings.d.ts +33 -0
- package/dist/modules/bot_settings.d.ts.map +1 -0
- package/dist/modules/bot_settings.js +328 -0
- package/dist/modules/bot_settings.js.map +1 -0
- package/dist/modules/bots_file_lock.d.ts +88 -0
- package/dist/modules/bots_file_lock.d.ts.map +1 -0
- package/dist/modules/bots_file_lock.js +161 -0
- package/dist/modules/bots_file_lock.js.map +1 -0
- package/dist/modules/chain_keys.d.ts +302 -0
- package/dist/modules/chain_keys.d.ts.map +1 -0
- package/dist/modules/chain_keys.js +1095 -0
- package/dist/modules/chain_keys.js.map +1 -0
- package/dist/modules/chain_orders.d.ts +423 -0
- package/dist/modules/chain_orders.d.ts.map +1 -0
- package/dist/modules/chain_orders.js +1201 -0
- package/dist/modules/chain_orders.js.map +1 -0
- package/dist/modules/cli_whitelist_args.d.ts +6 -0
- package/dist/modules/cli_whitelist_args.d.ts.map +1 -0
- package/dist/modules/cli_whitelist_args.js +13 -0
- package/dist/modules/cli_whitelist_args.js.map +1 -0
- package/dist/modules/config.d.ts +57 -0
- package/dist/modules/config.d.ts.map +1 -0
- package/dist/modules/config.js +107 -0
- package/dist/modules/config.js.map +1 -0
- package/dist/modules/constants.d.ts +635 -0
- package/dist/modules/constants.d.ts.map +1 -0
- package/dist/modules/constants.js +1464 -0
- package/dist/modules/constants.js.map +1 -0
- package/dist/modules/cr_planner.d.ts +51 -0
- package/dist/modules/cr_planner.d.ts.map +1 -0
- package/dist/modules/cr_planner.js +299 -0
- package/dist/modules/cr_planner.js.map +1 -0
- package/dist/modules/credential_policy.d.ts +188 -0
- package/dist/modules/credential_policy.d.ts.map +1 -0
- package/dist/modules/credential_policy.js +1452 -0
- package/dist/modules/credential_policy.js.map +1 -0
- package/dist/modules/credential_runtime.d.ts +42 -0
- package/dist/modules/credential_runtime.d.ts.map +1 -0
- package/dist/modules/credential_runtime.js +148 -0
- package/dist/modules/credential_runtime.js.map +1 -0
- package/dist/modules/credential_session_cache.d.ts +36 -0
- package/dist/modules/credential_session_cache.d.ts.map +1 -0
- package/dist/modules/credential_session_cache.js +106 -0
- package/dist/modules/credential_session_cache.js.map +1 -0
- package/dist/modules/credit_runtime.d.ts +412 -0
- package/dist/modules/credit_runtime.d.ts.map +1 -0
- package/dist/modules/credit_runtime.js +2866 -0
- package/dist/modules/credit_runtime.js.map +1 -0
- package/dist/modules/crypto/browser_provider.d.ts +15 -0
- package/dist/modules/crypto/browser_provider.d.ts.map +1 -0
- package/dist/modules/crypto/browser_provider.js +113 -0
- package/dist/modules/crypto/browser_provider.js.map +1 -0
- package/dist/modules/crypto/index.d.ts +9 -0
- package/dist/modules/crypto/index.d.ts.map +1 -0
- package/dist/modules/crypto/index.js +44 -0
- package/dist/modules/crypto/index.js.map +1 -0
- package/dist/modules/crypto/node_provider.d.ts +15 -0
- package/dist/modules/crypto/node_provider.d.ts.map +1 -0
- package/dist/modules/crypto/node_provider.js +74 -0
- package/dist/modules/crypto/node_provider.js.map +1 -0
- package/dist/modules/crypto/provider.d.ts +34 -0
- package/dist/modules/crypto/provider.d.ts.map +1 -0
- package/dist/modules/crypto/provider.js +3 -0
- package/dist/modules/crypto/provider.js.map +1 -0
- package/dist/modules/crypto/pure_ripemd160.d.ts +8 -0
- package/dist/modules/crypto/pure_ripemd160.d.ts.map +1 -0
- package/dist/modules/crypto/pure_ripemd160.js +142 -0
- package/dist/modules/crypto/pure_ripemd160.js.map +1 -0
- package/dist/modules/crypto/pure_scrypt.d.ts +23 -0
- package/dist/modules/crypto/pure_scrypt.d.ts.map +1 -0
- package/dist/modules/crypto/pure_scrypt.js +161 -0
- package/dist/modules/crypto/pure_scrypt.js.map +1 -0
- package/dist/modules/crypto/pure_secp256k1.d.ts +29 -0
- package/dist/modules/crypto/pure_secp256k1.d.ts.map +1 -0
- package/dist/modules/crypto/pure_secp256k1.js +195 -0
- package/dist/modules/crypto/pure_secp256k1.js.map +1 -0
- package/dist/modules/crypto/sync.d.ts +13 -0
- package/dist/modules/crypto/sync.d.ts.map +1 -0
- package/dist/modules/crypto/sync.js +37 -0
- package/dist/modules/crypto/sync.js.map +1 -0
- package/dist/modules/dexbot_class.d.ts +1074 -0
- package/dist/modules/dexbot_class.d.ts.map +1 -0
- package/dist/modules/dexbot_class.js +4613 -0
- package/dist/modules/dexbot_class.js.map +1 -0
- package/dist/modules/dexbot_credential_client.d.ts +71 -0
- package/dist/modules/dexbot_credential_client.d.ts.map +1 -0
- package/dist/modules/dexbot_credential_client.js +224 -0
- package/dist/modules/dexbot_credential_client.js.map +1 -0
- package/dist/modules/dexbot_fill_runtime.d.ts +173 -0
- package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -0
- package/dist/modules/dexbot_fill_runtime.js +217 -0
- package/dist/modules/dexbot_fill_runtime.js.map +1 -0
- package/dist/modules/dexbot_maintenance_runtime.d.ts +279 -0
- package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -0
- package/dist/modules/dexbot_maintenance_runtime.js +1613 -0
- package/dist/modules/dexbot_maintenance_runtime.js.map +1 -0
- package/dist/modules/env.d.ts +12 -0
- package/dist/modules/env.d.ts.map +1 -0
- package/dist/modules/env.js +57 -0
- package/dist/modules/env.js.map +1 -0
- package/dist/modules/fund_registry.d.ts +96 -0
- package/dist/modules/fund_registry.d.ts.map +1 -0
- package/dist/modules/fund_registry.js +261 -0
- package/dist/modules/fund_registry.js.map +1 -0
- package/dist/modules/general_settings.d.ts +36 -0
- package/dist/modules/general_settings.d.ts.map +1 -0
- package/dist/modules/general_settings.js +63 -0
- package/dist/modules/general_settings.js.map +1 -0
- package/dist/modules/graceful_shutdown.d.ts +86 -0
- package/dist/modules/graceful_shutdown.d.ts.map +1 -0
- package/dist/modules/graceful_shutdown.js +164 -0
- package/dist/modules/graceful_shutdown.js.map +1 -0
- package/dist/modules/key_store.d.ts +60 -0
- package/dist/modules/key_store.d.ts.map +1 -0
- package/dist/modules/key_store.js +215 -0
- package/dist/modules/key_store.js.map +1 -0
- package/dist/modules/launcher/bot_supervisor.d.ts +84 -0
- package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -0
- package/dist/modules/launcher/bot_supervisor.js +1067 -0
- package/dist/modules/launcher/bot_supervisor.js.map +1 -0
- package/dist/modules/launcher/child_env.d.ts +9 -0
- package/dist/modules/launcher/child_env.d.ts.map +1 -0
- package/dist/modules/launcher/child_env.js +78 -0
- package/dist/modules/launcher/child_env.js.map +1 -0
- package/dist/modules/launcher/credential_bootstrap.d.ts +22 -0
- package/dist/modules/launcher/credential_bootstrap.d.ts.map +1 -0
- package/dist/modules/launcher/credential_bootstrap.js +303 -0
- package/dist/modules/launcher/credential_bootstrap.js.map +1 -0
- package/dist/modules/launcher/credential_daemon.d.ts +32 -0
- package/dist/modules/launcher/credential_daemon.d.ts.map +1 -0
- package/dist/modules/launcher/credential_daemon.js +173 -0
- package/dist/modules/launcher/credential_daemon.js.map +1 -0
- package/dist/modules/launcher/credential_secret.d.ts +6 -0
- package/dist/modules/launcher/credential_secret.d.ts.map +1 -0
- package/dist/modules/launcher/credential_secret.js +15 -0
- package/dist/modules/launcher/credential_secret.js.map +1 -0
- package/dist/modules/launcher/foreign_cred_daemon.d.ts +2 -0
- package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -0
- package/dist/modules/launcher/foreign_cred_daemon.js +166 -0
- package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -0
- package/dist/modules/launcher/headless_password.d.ts +8 -0
- package/dist/modules/launcher/headless_password.d.ts.map +1 -0
- package/dist/modules/launcher/headless_password.js +33 -0
- package/dist/modules/launcher/headless_password.js.map +1 -0
- package/dist/modules/launcher/launch_modes.d.ts +36 -0
- package/dist/modules/launcher/launch_modes.d.ts.map +1 -0
- package/dist/modules/launcher/launch_modes.js +129 -0
- package/dist/modules/launcher/launch_modes.js.map +1 -0
- package/dist/modules/launcher/market_adapter_runtime.d.ts +43 -0
- package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -0
- package/dist/modules/launcher/market_adapter_runtime.js +217 -0
- package/dist/modules/launcher/market_adapter_runtime.js.map +1 -0
- package/dist/modules/launcher/market_adapter_watchdog.d.ts +26 -0
- package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -0
- package/dist/modules/launcher/market_adapter_watchdog.js +214 -0
- package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -0
- package/dist/modules/launcher/monolithic_runtime.d.ts +89 -0
- package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -0
- package/dist/modules/launcher/monolithic_runtime.js +425 -0
- package/dist/modules/launcher/monolithic_runtime.js.map +1 -0
- package/dist/modules/launcher/runtime_entry.d.ts +26 -0
- package/dist/modules/launcher/runtime_entry.d.ts.map +1 -0
- package/dist/modules/launcher/runtime_entry.js +49 -0
- package/dist/modules/launcher/runtime_entry.js.map +1 -0
- package/dist/modules/launcher/status_reporting.d.ts +48 -0
- package/dist/modules/launcher/status_reporting.d.ts.map +1 -0
- package/dist/modules/launcher/status_reporting.js +113 -0
- package/dist/modules/launcher/status_reporting.js.map +1 -0
- package/dist/modules/launcher/supervisor_control.d.ts +6 -0
- package/dist/modules/launcher/supervisor_control.d.ts.map +1 -0
- package/dist/modules/launcher/supervisor_control.js +59 -0
- package/dist/modules/launcher/supervisor_control.js.map +1 -0
- package/dist/modules/logger.d.ts +2 -0
- package/dist/modules/logger.d.ts.map +1 -0
- package/dist/modules/logger.js +71 -0
- package/dist/modules/logger.js.map +1 -0
- package/dist/modules/market_adapter_whitelist.d.ts +22 -0
- package/dist/modules/market_adapter_whitelist.d.ts.map +1 -0
- package/dist/modules/market_adapter_whitelist.js +82 -0
- package/dist/modules/market_adapter_whitelist.js.map +1 -0
- package/dist/modules/node_health_cache.d.ts +55 -0
- package/dist/modules/node_health_cache.d.ts.map +1 -0
- package/dist/modules/node_health_cache.js +134 -0
- package/dist/modules/node_health_cache.js.map +1 -0
- package/dist/modules/node_manager.d.ts +215 -0
- package/dist/modules/node_manager.d.ts.map +1 -0
- package/dist/modules/node_manager.js +628 -0
- package/dist/modules/node_manager.js.map +1 -0
- package/dist/modules/order/accounting.d.ts +349 -0
- package/dist/modules/order/accounting.d.ts.map +1 -0
- package/dist/modules/order/accounting.js +1191 -0
- package/dist/modules/order/accounting.js.map +1 -0
- package/dist/modules/order/async_lock.d.ts +126 -0
- package/dist/modules/order/async_lock.d.ts.map +1 -0
- package/dist/modules/order/async_lock.js +195 -0
- package/dist/modules/order/async_lock.js.map +1 -0
- package/dist/modules/order/export.d.ts +129 -0
- package/dist/modules/order/export.d.ts.map +1 -0
- package/dist/modules/order/export.js +316 -0
- package/dist/modules/order/export.js.map +1 -0
- package/dist/modules/order/format.d.ts +158 -0
- package/dist/modules/order/format.d.ts.map +1 -0
- package/dist/modules/order/format.js +232 -0
- package/dist/modules/order/format.js.map +1 -0
- package/dist/modules/order/grid.d.ts +549 -0
- package/dist/modules/order/grid.d.ts.map +1 -0
- package/dist/modules/order/grid.js +1746 -0
- package/dist/modules/order/grid.js.map +1 -0
- package/dist/modules/order/grid_reconcile.d.ts +154 -0
- package/dist/modules/order/grid_reconcile.d.ts.map +1 -0
- package/dist/modules/order/grid_reconcile.js +1192 -0
- package/dist/modules/order/grid_reconcile.js.map +1 -0
- package/dist/modules/order/index.d.ts +55 -0
- package/dist/modules/order/index.d.ts.map +1 -0
- package/dist/modules/order/index.js +79 -0
- package/dist/modules/order/index.js.map +1 -0
- package/dist/modules/order/logger.d.ts +136 -0
- package/dist/modules/order/logger.d.ts.map +1 -0
- package/dist/modules/order/logger.js +614 -0
- package/dist/modules/order/logger.js.map +1 -0
- package/dist/modules/order/logger_state.d.ts +133 -0
- package/dist/modules/order/logger_state.d.ts.map +1 -0
- package/dist/modules/order/logger_state.js +170 -0
- package/dist/modules/order/logger_state.js.map +1 -0
- package/dist/modules/order/manager.d.ts +413 -0
- package/dist/modules/order/manager.d.ts.map +1 -0
- package/dist/modules/order/manager.js +1605 -0
- package/dist/modules/order/manager.js.map +1 -0
- package/dist/modules/order/processed_fill_store.d.ts +135 -0
- package/dist/modules/order/processed_fill_store.d.ts.map +1 -0
- package/dist/modules/order/processed_fill_store.js +288 -0
- package/dist/modules/order/processed_fill_store.js.map +1 -0
- package/dist/modules/order/runner.d.ts +70 -0
- package/dist/modules/order/runner.d.ts.map +1 -0
- package/dist/modules/order/runner.js +140 -0
- package/dist/modules/order/runner.js.map +1 -0
- package/dist/modules/order/strategy.d.ts +196 -0
- package/dist/modules/order/strategy.d.ts.map +1 -0
- package/dist/modules/order/strategy.js +398 -0
- package/dist/modules/order/strategy.js.map +1 -0
- package/dist/modules/order/sync_engine.d.ts +386 -0
- package/dist/modules/order/sync_engine.d.ts.map +1 -0
- package/dist/modules/order/sync_engine.js +1459 -0
- package/dist/modules/order/sync_engine.js.map +1 -0
- package/dist/modules/order/utils/math.d.ts +677 -0
- package/dist/modules/order/utils/math.d.ts.map +1 -0
- package/dist/modules/order/utils/math.js +1172 -0
- package/dist/modules/order/utils/math.js.map +1 -0
- package/dist/modules/order/utils/order.d.ts +572 -0
- package/dist/modules/order/utils/order.d.ts.map +1 -0
- package/dist/modules/order/utils/order.js +1145 -0
- package/dist/modules/order/utils/order.js.map +1 -0
- package/dist/modules/order/utils/system.d.ts +268 -0
- package/dist/modules/order/utils/system.d.ts.map +1 -0
- package/dist/modules/order/utils/system.js +1261 -0
- package/dist/modules/order/utils/system.js.map +1 -0
- package/dist/modules/order/utils/validate.d.ts +280 -0
- package/dist/modules/order/utils/validate.d.ts.map +1 -0
- package/dist/modules/order/utils/validate.js +918 -0
- package/dist/modules/order/utils/validate.js.map +1 -0
- package/dist/modules/order/working_grid.d.ts +212 -0
- package/dist/modules/order/working_grid.d.ts.map +1 -0
- package/dist/modules/order/working_grid.js +279 -0
- package/dist/modules/order/working_grid.js.map +1 -0
- package/dist/modules/path_api.d.ts +32 -0
- package/dist/modules/path_api.d.ts.map +1 -0
- package/dist/modules/path_api.js +148 -0
- package/dist/modules/path_api.js.map +1 -0
- package/dist/modules/paths.d.ts +58 -0
- package/dist/modules/paths.d.ts.map +1 -0
- package/dist/modules/paths.js +82 -0
- package/dist/modules/paths.js.map +1 -0
- package/dist/modules/process_discovery.d.ts +58 -0
- package/dist/modules/process_discovery.d.ts.map +1 -0
- package/dist/modules/process_discovery.js +265 -0
- package/dist/modules/process_discovery.js.map +1 -0
- package/dist/modules/runtime.d.ts +34 -0
- package/dist/modules/runtime.d.ts.map +1 -0
- package/dist/modules/runtime.js +98 -0
- package/dist/modules/runtime.js.map +1 -0
- package/dist/modules/runtime_settings.d.ts +12 -0
- package/dist/modules/runtime_settings.d.ts.map +1 -0
- package/dist/modules/runtime_settings.js +122 -0
- package/dist/modules/runtime_settings.js.map +1 -0
- package/dist/modules/settings_merge.d.ts +38 -0
- package/dist/modules/settings_merge.d.ts.map +1 -0
- package/dist/modules/settings_merge.js +246 -0
- package/dist/modules/settings_merge.js.map +1 -0
- package/dist/modules/storage/browser_adapter.d.ts +56 -0
- package/dist/modules/storage/browser_adapter.d.ts.map +1 -0
- package/dist/modules/storage/browser_adapter.js +231 -0
- package/dist/modules/storage/browser_adapter.js.map +1 -0
- package/dist/modules/storage/index.d.ts +28 -0
- package/dist/modules/storage/index.d.ts.map +1 -0
- package/dist/modules/storage/index.js +52 -0
- package/dist/modules/storage/index.js.map +1 -0
- package/dist/modules/storage/node_adapter.d.ts +49 -0
- package/dist/modules/storage/node_adapter.d.ts.map +1 -0
- package/dist/modules/storage/node_adapter.js +167 -0
- package/dist/modules/storage/node_adapter.js.map +1 -0
- package/dist/modules/storage/types.d.ts +92 -0
- package/dist/modules/storage/types.d.ts.map +1 -0
- package/dist/modules/storage/types.js +3 -0
- package/dist/modules/storage/types.js.map +1 -0
- package/dist/modules/types.d.ts +1382 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/modules/types.js +11 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/modules/utils/base58check.d.ts +12 -0
- package/dist/modules/utils/base58check.d.ts.map +1 -0
- package/dist/modules/utils/base58check.js +112 -0
- package/dist/modules/utils/base58check.js.map +1 -0
- package/dist/modules/utils/build_dir.d.ts +7 -0
- package/dist/modules/utils/build_dir.d.ts.map +1 -0
- package/dist/modules/utils/build_dir.js +8 -0
- package/dist/modules/utils/build_dir.js.map +1 -0
- package/dist/modules/utils/fs_utils.d.ts +25 -0
- package/dist/modules/utils/fs_utils.d.ts.map +1 -0
- package/dist/modules/utils/fs_utils.js +27 -0
- package/dist/modules/utils/fs_utils.js.map +1 -0
- package/dist/modules/utils/math_utils.d.ts +10 -0
- package/dist/modules/utils/math_utils.d.ts.map +1 -0
- package/dist/modules/utils/math_utils.js +17 -0
- package/dist/modules/utils/math_utils.js.map +1 -0
- package/dist/modules/validate_profiles.d.ts +37 -0
- package/dist/modules/validate_profiles.d.ts.map +1 -0
- package/dist/modules/validate_profiles.js +369 -0
- package/dist/modules/validate_profiles.js.map +1 -0
- package/dist/pm2.d.ts +167 -0
- package/dist/pm2.d.ts.map +1 -0
- package/dist/pm2.js +998 -0
- package/dist/pm2.js.map +1 -0
- package/dist/scripts/analyze-git.d.ts +11 -0
- package/dist/scripts/analyze-git.d.ts.map +1 -0
- package/dist/scripts/analyze-git.js +851 -0
- package/dist/scripts/analyze-git.js.map +1 -0
- package/dist/scripts/analyze-orders.d.ts +17 -0
- package/dist/scripts/analyze-orders.d.ts.map +1 -0
- package/dist/scripts/analyze-orders.js +1568 -0
- package/dist/scripts/analyze-orders.js.map +1 -0
- package/dist/scripts/diagnose-kibana-candles.d.ts +3 -0
- package/dist/scripts/diagnose-kibana-candles.d.ts.map +1 -0
- package/dist/scripts/diagnose-kibana-candles.js +82 -0
- package/dist/scripts/diagnose-kibana-candles.js.map +1 -0
- package/dist/scripts/diagnose-pool-history.d.ts +3 -0
- package/dist/scripts/diagnose-pool-history.d.ts.map +1 -0
- package/dist/scripts/diagnose-pool-history.js +296 -0
- package/dist/scripts/diagnose-pool-history.js.map +1 -0
- package/dist/scripts/divergence-calc.d.ts +26 -0
- package/dist/scripts/divergence-calc.d.ts.map +1 -0
- package/dist/scripts/divergence-calc.js +119 -0
- package/dist/scripts/divergence-calc.js.map +1 -0
- package/dist/scripts/generate_lp_chart.d.ts +31 -0
- package/dist/scripts/generate_lp_chart.d.ts.map +1 -0
- package/dist/scripts/generate_lp_chart.js +92 -0
- package/dist/scripts/generate_lp_chart.js.map +1 -0
- package/dist/scripts/generate_mainnet_corpus_report.d.ts +24 -0
- package/dist/scripts/generate_mainnet_corpus_report.d.ts.map +1 -0
- package/dist/scripts/generate_mainnet_corpus_report.js +237 -0
- package/dist/scripts/generate_mainnet_corpus_report.js.map +1 -0
- package/dist/scripts/generate_market_adapter_whitelist.d.ts +2 -0
- package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +1 -0
- package/dist/scripts/generate_market_adapter_whitelist.js +111 -0
- package/dist/scripts/generate_market_adapter_whitelist.js.map +1 -0
- package/dist/scripts/migrate_bot_keys.d.ts +6 -0
- package/dist/scripts/migrate_bot_keys.d.ts.map +1 -0
- package/dist/scripts/migrate_bot_keys.js +301 -0
- package/dist/scripts/migrate_bot_keys.js.map +1 -0
- package/dist/scripts/native_release_gates.d.ts +3 -0
- package/dist/scripts/native_release_gates.d.ts.map +1 -0
- package/dist/scripts/native_release_gates.js +52 -0
- package/dist/scripts/native_release_gates.js.map +1 -0
- package/dist/scripts/print_grid.d.ts +16 -0
- package/dist/scripts/print_grid.d.ts.map +1 -0
- package/dist/scripts/print_grid.js +80 -0
- package/dist/scripts/print_grid.js.map +1 -0
- package/dist/scripts/run-tests.d.ts +2 -0
- package/dist/scripts/run-tests.d.ts.map +1 -0
- package/dist/scripts/run-tests.js +49 -0
- package/dist/scripts/run-tests.js.map +1 -0
- package/dist/scripts/sync-version.d.ts +14 -0
- package/dist/scripts/sync-version.d.ts.map +1 -0
- package/dist/scripts/sync-version.js +158 -0
- package/dist/scripts/sync-version.js.map +1 -0
- package/dist/scripts/test-credit-renewal.d.ts +2 -0
- package/dist/scripts/test-credit-renewal.d.ts.map +1 -0
- package/dist/scripts/test-credit-renewal.js +329 -0
- package/dist/scripts/test-credit-renewal.js.map +1 -0
- package/dist/scripts/update.d.ts +24 -0
- package/dist/scripts/update.d.ts.map +1 -0
- package/dist/scripts/update.js +650 -0
- package/dist/scripts/update.js.map +1 -0
- package/dist/scripts/validate_bots.d.ts +16 -0
- package/dist/scripts/validate_bots.d.ts.map +1 -0
- package/dist/scripts/validate_bots.js +106 -0
- package/dist/scripts/validate_bots.js.map +1 -0
- package/dist/scripts/verify-browser-bundle.d.ts +22 -0
- package/dist/scripts/verify-browser-bundle.d.ts.map +1 -0
- package/dist/scripts/verify-browser-bundle.js +339 -0
- package/dist/scripts/verify-browser-bundle.js.map +1 -0
- package/dist/unlock.d.ts +48 -0
- package/dist/unlock.d.ts.map +1 -0
- package/dist/unlock.js +925 -0
- package/dist/unlock.js.map +1 -0
- package/package.json +112 -0
- package/scripts/README.md +356 -0
- package/scripts/clear-all.sh +195 -0
- package/scripts/clear-logs.sh +95 -0
- package/scripts/clear-market-adapter.sh +196 -0
- package/scripts/clear-orders.sh +113 -0
- package/scripts/create-bot-symlinks.sh +51 -0
- package/scripts/postinstall.js +9 -0
- package/scripts/reset-settings.sh +118 -0
|
@@ -0,0 +1,1605 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* modules/order/manager.ts - OrderManager Engine
|
|
4
|
+
*
|
|
5
|
+
* Core grid-based order management system for DEXBot2.
|
|
6
|
+
* Uses utils/validate.ts, strategy.ts, and utils/order.ts for validation and rebalance logic.
|
|
7
|
+
*
|
|
8
|
+
* ===============================================================================
|
|
9
|
+
* TABLE OF CONTENTS
|
|
10
|
+
* ===============================================================================
|
|
11
|
+
*
|
|
12
|
+
* SECTION 1: EXTERNAL DEPENDENCIES
|
|
13
|
+
* SECTION 2: COW REBALANCE ENGINE
|
|
14
|
+
* SECTION 3: STATE MANAGER
|
|
15
|
+
* SECTION 4: ORDER MANAGER CLASS
|
|
16
|
+
* ===============================================================================
|
|
17
|
+
*/
|
|
18
|
+
// ===============================================================================
|
|
19
|
+
// SECTION 1: EXTERNAL DEPENDENCIES
|
|
20
|
+
// ===============================================================================
|
|
21
|
+
const { ORDER_TYPES, ORDER_STATES, REBALANCE_STATES, COW_ACTIONS, DEFAULT_CONFIG, TIMING, LOG_LEVEL, PIPELINE_TIMING, COW_PERFORMANCE } = require('../constants');
|
|
22
|
+
const { getMinAbsoluteOrderSize, computeChainFundTotals, hasValidAccountTotals, resolveConfigValue, resolveConfigValueWithRegistry, isExplicitZeroAllocation, floatToBlockchainInt, getPrecisionSlack } = require('./utils/math');
|
|
23
|
+
const { isOrderOnChain, isPhantomOrder, hasOnChainId, convertToSpreadPlaceholder } = require('./utils/order');
|
|
24
|
+
const { persistGridSnapshot, deepFreeze, cloneMap } = require('./utils/system');
|
|
25
|
+
const { validateOrder, validateGridForPersistence, calculateRequiredFunds, validateWorkingGridFunds, checkFundDrift, reconcileGrid, optimizeRebalanceActions, summarizeActions, projectTargetToWorkingGrid, buildStateUpdates, buildAbortedResult, buildSuccessResult, evaluateCommit } = require('./utils/validate');
|
|
26
|
+
const { WorkingGrid } = require('./working_grid');
|
|
27
|
+
const Logger = require('./logger');
|
|
28
|
+
const AsyncLock = require('./async_lock');
|
|
29
|
+
const Accountant = require('./accounting');
|
|
30
|
+
const StrategyEngine = require('./strategy');
|
|
31
|
+
const SyncEngine = require('./sync_engine');
|
|
32
|
+
const Grid = require('./grid');
|
|
33
|
+
const Format = require('./format');
|
|
34
|
+
const { toFiniteNumber, isValidNumber } = Format;
|
|
35
|
+
// ===============================================================================
|
|
36
|
+
// SECTION 2: COW REBALANCE ENGINE
|
|
37
|
+
// ===============================================================================
|
|
38
|
+
//
|
|
39
|
+
// COPY-ON-WRITE (COW) PATTERN FOR SAFE REBALANCING
|
|
40
|
+
//
|
|
41
|
+
// Problem Solved:
|
|
42
|
+
// Traditional approach: Modify orders in-place while calculating new grid
|
|
43
|
+
// Issue: If fills arrive DURING rebalance, they corrupt the working state
|
|
44
|
+
//
|
|
45
|
+
// Solution: Copy-on-Write pattern isolates rebalancing from incoming fills
|
|
46
|
+
//
|
|
47
|
+
// WORKFLOW:
|
|
48
|
+
// 1. Clone master grid → WorkingGrid (immutable during rebalance)
|
|
49
|
+
// 2. Calculate target state from strategy engine
|
|
50
|
+
// 3. Reconcile master vs target → generate COW_ACTIONS (CREATE/UPDATE/CANCEL/ROTATE)
|
|
51
|
+
// 4. Project target to working grid (working becomes target)
|
|
52
|
+
// 5. Validate funds and check for staleness (abort if fills arrived)
|
|
53
|
+
// 6. Build blockchain operations from delta
|
|
54
|
+
// 7. Atomic commit to master on broadcast success (or discard on failure)
|
|
55
|
+
//
|
|
56
|
+
// KEY INVARIANTS:
|
|
57
|
+
// 1. Master grid NEVER modified during planning (immutable during rebalance)
|
|
58
|
+
// 2. Fills that arrive during rebalance are QUEUED, not lost
|
|
59
|
+
// 3. Working grid is DISPOSABLE - if rebalance fails, discard it
|
|
60
|
+
// 4. Only ONE rebalance plan active at a time (StateManager.rebalance)
|
|
61
|
+
// 5. Staleness detection aborts if master changes (fills, manual commands)
|
|
62
|
+
//
|
|
63
|
+
// FILL HANDLING DURING REBALANCE:
|
|
64
|
+
// - SyncEngine.syncFromFillHistory() is called immediately on fill arrival
|
|
65
|
+
// - Updates to master grid only (not working grid)
|
|
66
|
+
// - Sets workingGrid.markStale() to signal version mismatch
|
|
67
|
+
// - Rebalance detects staleness → aborts → retries on next cycle
|
|
68
|
+
// - Fills are NEVER lost, just deferred until next rebalance cycle
|
|
69
|
+
//
|
|
70
|
+
// PERFORMANCE OPTIMIZATION:
|
|
71
|
+
// - COW_PERFORMANCE.WORKING_GRID_BYTES_PER_ORDER estimated memory per order
|
|
72
|
+
// - Modified Set only tracks changed order IDs (delta compression)
|
|
73
|
+
// - Lazy index calculation (prices, types, states) only on demand
|
|
74
|
+
// - Delta building is O(n) where n = modified orders count
|
|
75
|
+
//
|
|
76
|
+
// ===============================================================================
|
|
77
|
+
class COWRebalanceEngine {
|
|
78
|
+
strategy;
|
|
79
|
+
logger;
|
|
80
|
+
assets;
|
|
81
|
+
config;
|
|
82
|
+
constructor(deps) {
|
|
83
|
+
this.strategy = deps.strategy;
|
|
84
|
+
this.logger = deps.logger;
|
|
85
|
+
this.assets = deps.assets;
|
|
86
|
+
this.config = deps.config;
|
|
87
|
+
}
|
|
88
|
+
async execute({ masterGrid, gridVersion, boundaryIdx, funds, fills = [], excludeIds = new Set() }) {
|
|
89
|
+
const startTime = Date.now();
|
|
90
|
+
const workingGrid = new WorkingGrid(masterGrid, { baseVersion: gridVersion });
|
|
91
|
+
const strategyParams = {
|
|
92
|
+
frozenMasterGrid: masterGrid,
|
|
93
|
+
config: this.config,
|
|
94
|
+
accountAssets: this.assets,
|
|
95
|
+
funds,
|
|
96
|
+
excludeIds,
|
|
97
|
+
fills,
|
|
98
|
+
currentBoundaryIdx: boundaryIdx
|
|
99
|
+
};
|
|
100
|
+
const { targetGrid, boundaryIdx: targetBoundary } = this.strategy.calculateTargetGrid(strategyParams);
|
|
101
|
+
let dustThresholdPercent = this.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE;
|
|
102
|
+
const reconcileResult = reconcileGrid(masterGrid, targetGrid, targetBoundary, {
|
|
103
|
+
logger: (msg, level) => this.logger?.log(msg, level),
|
|
104
|
+
dustThresholdPercent
|
|
105
|
+
});
|
|
106
|
+
if (reconcileResult.aborted) {
|
|
107
|
+
return buildAbortedResult(reconcileResult.reason);
|
|
108
|
+
}
|
|
109
|
+
const optimizedActions = optimizeRebalanceActions(reconcileResult.actions, masterGrid);
|
|
110
|
+
projectTargetToWorkingGrid(workingGrid, targetGrid, { actions: optimizedActions });
|
|
111
|
+
const precisions = {
|
|
112
|
+
buyPrecision: this.assets?.assetB?.precision,
|
|
113
|
+
sellPrecision: this.assets?.assetA?.precision
|
|
114
|
+
};
|
|
115
|
+
const fundCheck = validateWorkingGridFunds(workingGrid, funds, precisions, this.assets);
|
|
116
|
+
if (!fundCheck.isValid) {
|
|
117
|
+
this.logger?.log(`[COW] Fund validation failed: ${fundCheck.reason}`, 'warn');
|
|
118
|
+
return buildAbortedResult(fundCheck.reason);
|
|
119
|
+
}
|
|
120
|
+
if (workingGrid.isStale()) {
|
|
121
|
+
const reason = workingGrid.getStaleReason() || 'Master grid changed during planning';
|
|
122
|
+
this.logger?.log(`[COW] Rebalance plan invalidated: ${reason}`, 'warn');
|
|
123
|
+
return buildAbortedResult(reason);
|
|
124
|
+
}
|
|
125
|
+
const stateUpdates = buildStateUpdates(optimizedActions, masterGrid);
|
|
126
|
+
const duration = Date.now() - startTime;
|
|
127
|
+
if (duration > 100) {
|
|
128
|
+
this.logger?.log(`[COW] Rebalance planning took ${duration}ms`, 'warn');
|
|
129
|
+
}
|
|
130
|
+
this.logger?.log(`[COW] Plan: Actions=${optimizedActions.length}, StateUpdates=${stateUpdates.length}`, 'info');
|
|
131
|
+
return buildSuccessResult({
|
|
132
|
+
actions: optimizedActions,
|
|
133
|
+
stateUpdates,
|
|
134
|
+
workingGrid,
|
|
135
|
+
workingBoundary: targetBoundary,
|
|
136
|
+
planningDuration: duration
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// ===============================================================================
|
|
141
|
+
// SECTION 3: STATE MANAGER
|
|
142
|
+
// ===============================================================================
|
|
143
|
+
class StateManager {
|
|
144
|
+
logger;
|
|
145
|
+
rebalance;
|
|
146
|
+
recovery;
|
|
147
|
+
gridRegen;
|
|
148
|
+
bootstrap;
|
|
149
|
+
broadcast;
|
|
150
|
+
signals;
|
|
151
|
+
pipeline;
|
|
152
|
+
constructor(options = {}) {
|
|
153
|
+
this.logger = options.logger || null;
|
|
154
|
+
this.reset();
|
|
155
|
+
}
|
|
156
|
+
reset() {
|
|
157
|
+
this.rebalance = {
|
|
158
|
+
state: REBALANCE_STATES.NORMAL,
|
|
159
|
+
currentWorkingGrid: null
|
|
160
|
+
};
|
|
161
|
+
this.recovery = {
|
|
162
|
+
attemptCount: 0,
|
|
163
|
+
lastAttemptAt: 0,
|
|
164
|
+
inFlight: false,
|
|
165
|
+
lastFailureAt: 0
|
|
166
|
+
};
|
|
167
|
+
this.gridRegen = {
|
|
168
|
+
buy: { armed: true, lastTriggeredAt: 0 },
|
|
169
|
+
sell: { armed: true, lastTriggeredAt: 0 }
|
|
170
|
+
};
|
|
171
|
+
this.bootstrap = {
|
|
172
|
+
isBootstrapping: false
|
|
173
|
+
};
|
|
174
|
+
this.broadcast = {
|
|
175
|
+
isBroadcasting: false,
|
|
176
|
+
startedAt: 0,
|
|
177
|
+
};
|
|
178
|
+
this.signals = {
|
|
179
|
+
lastIllegalState: null,
|
|
180
|
+
lastAccountingFailure: null
|
|
181
|
+
};
|
|
182
|
+
this.pipeline = {
|
|
183
|
+
blockedSince: null,
|
|
184
|
+
recoveryAttempted: false
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
getRebalanceState() {
|
|
188
|
+
return this.rebalance.state;
|
|
189
|
+
}
|
|
190
|
+
setRebalanceState(state) {
|
|
191
|
+
this.rebalance.state = state;
|
|
192
|
+
this.logger?.log(`[COW] Rebalance state: ${state}`, 'debug');
|
|
193
|
+
}
|
|
194
|
+
isRebalancing() {
|
|
195
|
+
return this.rebalance.state === REBALANCE_STATES.REBALANCING;
|
|
196
|
+
}
|
|
197
|
+
isBroadcasting() {
|
|
198
|
+
return this.rebalance.state === REBALANCE_STATES.BROADCASTING;
|
|
199
|
+
}
|
|
200
|
+
setWorkingGrid(workingGrid) {
|
|
201
|
+
this.rebalance.currentWorkingGrid = workingGrid;
|
|
202
|
+
}
|
|
203
|
+
getWorkingGrid() {
|
|
204
|
+
return this.rebalance.currentWorkingGrid;
|
|
205
|
+
}
|
|
206
|
+
clearWorkingGrid() {
|
|
207
|
+
this.rebalance.currentWorkingGrid = null;
|
|
208
|
+
}
|
|
209
|
+
recordRecoveryAttempt() {
|
|
210
|
+
this.recovery.attemptCount++;
|
|
211
|
+
this.recovery.lastAttemptAt = Date.now();
|
|
212
|
+
this.recovery.inFlight = true;
|
|
213
|
+
}
|
|
214
|
+
completeRecovery(success) {
|
|
215
|
+
this.recovery.inFlight = false;
|
|
216
|
+
if (!success) {
|
|
217
|
+
this.recovery.lastFailureAt = Date.now();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
isRecoveryInFlight() {
|
|
221
|
+
return this.recovery.inFlight;
|
|
222
|
+
}
|
|
223
|
+
getRecoveryStats() {
|
|
224
|
+
return { ...this.recovery };
|
|
225
|
+
}
|
|
226
|
+
isSideArmed(side) {
|
|
227
|
+
return this.gridRegen[side]?.armed ?? false;
|
|
228
|
+
}
|
|
229
|
+
disarmSide(side) {
|
|
230
|
+
if (this.gridRegen[side]) {
|
|
231
|
+
this.gridRegen[side].armed = false;
|
|
232
|
+
this.gridRegen[side].lastTriggeredAt = Date.now();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
armSide(side) {
|
|
236
|
+
if (this.gridRegen[side]) {
|
|
237
|
+
this.gridRegen[side].armed = true;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
startBootstrap() {
|
|
241
|
+
this.bootstrap.isBootstrapping = true;
|
|
242
|
+
this.logger?.log('[BOOTSTRAP] Started', 'debug');
|
|
243
|
+
}
|
|
244
|
+
finishBootstrap() {
|
|
245
|
+
this.bootstrap.isBootstrapping = false;
|
|
246
|
+
this.logger?.log('[BOOTSTRAP] Finished', 'debug');
|
|
247
|
+
}
|
|
248
|
+
isBootstrapping() {
|
|
249
|
+
return this.bootstrap.isBootstrapping;
|
|
250
|
+
}
|
|
251
|
+
startBroadcasting() {
|
|
252
|
+
this.broadcast.isBroadcasting = true;
|
|
253
|
+
this.broadcast.startedAt = Date.now();
|
|
254
|
+
this.logger?.log?.('[BROADCAST] Flag set — fill processing will be deferred until stopBroadcasting()', 'debug');
|
|
255
|
+
}
|
|
256
|
+
stopBroadcasting() {
|
|
257
|
+
this.broadcast.isBroadcasting = false;
|
|
258
|
+
this.broadcast.startedAt = 0;
|
|
259
|
+
}
|
|
260
|
+
isBroadcastingActive() {
|
|
261
|
+
if (this.broadcast.isBroadcasting && this.broadcast.startedAt > 0) {
|
|
262
|
+
const elapsed = Date.now() - this.broadcast.startedAt;
|
|
263
|
+
if (elapsed > 120000) {
|
|
264
|
+
this.logger?.log?.('[BROADCAST] Auto-clearing stale broadcast flag after 120s', 'warn');
|
|
265
|
+
this.broadcast.isBroadcasting = false;
|
|
266
|
+
this.broadcast.startedAt = 0;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return this.broadcast.isBroadcasting;
|
|
270
|
+
}
|
|
271
|
+
setIllegalStateSignal(signal) {
|
|
272
|
+
this.signals.lastIllegalState = {
|
|
273
|
+
...signal,
|
|
274
|
+
at: Date.now()
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
consumeIllegalStateSignal() {
|
|
278
|
+
const signal = this.signals.lastIllegalState;
|
|
279
|
+
this.signals.lastIllegalState = null;
|
|
280
|
+
return signal;
|
|
281
|
+
}
|
|
282
|
+
setAccountingFailureSignal(signal) {
|
|
283
|
+
this.signals.lastAccountingFailure = {
|
|
284
|
+
...signal,
|
|
285
|
+
at: Date.now()
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
consumeAccountingFailureSignal() {
|
|
289
|
+
const signal = this.signals.lastAccountingFailure;
|
|
290
|
+
this.signals.lastAccountingFailure = null;
|
|
291
|
+
return signal;
|
|
292
|
+
}
|
|
293
|
+
markPipelineBlocked() {
|
|
294
|
+
if (!this.pipeline.blockedSince) {
|
|
295
|
+
this.pipeline.blockedSince = Date.now();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
markPipelineClear() {
|
|
299
|
+
this.pipeline.blockedSince = null;
|
|
300
|
+
this.pipeline.recoveryAttempted = false;
|
|
301
|
+
}
|
|
302
|
+
getPipelineBlockedDuration() {
|
|
303
|
+
return this.pipeline.blockedSince ? Date.now() - this.pipeline.blockedSince : 0;
|
|
304
|
+
}
|
|
305
|
+
isPipelineBlocked() {
|
|
306
|
+
return this.pipeline.blockedSince !== null;
|
|
307
|
+
}
|
|
308
|
+
getState() {
|
|
309
|
+
return {
|
|
310
|
+
rebalance: { ...this.rebalance, currentWorkingGrid: null },
|
|
311
|
+
recovery: { ...this.recovery },
|
|
312
|
+
gridRegen: { ...this.gridRegen },
|
|
313
|
+
bootstrap: { ...this.bootstrap },
|
|
314
|
+
broadcast: { ...this.broadcast },
|
|
315
|
+
pipeline: { ...this.pipeline }
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// ===============================================================================
|
|
320
|
+
// SECTION 4: ORDER MANAGER CLASS
|
|
321
|
+
// ===============================================================================
|
|
322
|
+
class OrderManager {
|
|
323
|
+
config;
|
|
324
|
+
marketName;
|
|
325
|
+
logger;
|
|
326
|
+
orders;
|
|
327
|
+
boundaryIdx;
|
|
328
|
+
targetGrid;
|
|
329
|
+
accountant;
|
|
330
|
+
strategy;
|
|
331
|
+
sync;
|
|
332
|
+
_state;
|
|
333
|
+
_ordersByState;
|
|
334
|
+
_ordersByType;
|
|
335
|
+
targetSpreadCount;
|
|
336
|
+
currentSpreadCount;
|
|
337
|
+
outOfSpread;
|
|
338
|
+
assets;
|
|
339
|
+
accountId;
|
|
340
|
+
accountTotals;
|
|
341
|
+
funds;
|
|
342
|
+
_accountTotalsPromise;
|
|
343
|
+
_accountTotalsResolve;
|
|
344
|
+
_isFetchingTotals;
|
|
345
|
+
ordersNeedingPriceCorrection;
|
|
346
|
+
shadowOrderIds;
|
|
347
|
+
processedFillTracker;
|
|
348
|
+
processedFillStore;
|
|
349
|
+
_syncLock;
|
|
350
|
+
_fillProcessingLock;
|
|
351
|
+
_divergenceLock;
|
|
352
|
+
_gridLock;
|
|
353
|
+
_fundLock;
|
|
354
|
+
_recentlyRotatedOrderIds;
|
|
355
|
+
_gridSidesUpdated;
|
|
356
|
+
_pauseFundRecalc;
|
|
357
|
+
_pauseRecalcLogging;
|
|
358
|
+
_throwOnIllegalState;
|
|
359
|
+
_pipelineBlockedSince;
|
|
360
|
+
_recoveryAttempted;
|
|
361
|
+
_gridVersion;
|
|
362
|
+
_gridPersistenceSuspendedReason;
|
|
363
|
+
_pendingBroadcasts;
|
|
364
|
+
_gridDirty;
|
|
365
|
+
_gridDirtyReasons;
|
|
366
|
+
_gridDirtySince;
|
|
367
|
+
_metrics;
|
|
368
|
+
_currentWorkingGrid;
|
|
369
|
+
_cowEngine;
|
|
370
|
+
accountOrders;
|
|
371
|
+
btsBalance;
|
|
372
|
+
/**
|
|
373
|
+
* @param {Object} [config] - Configuration overrides
|
|
374
|
+
*/
|
|
375
|
+
constructor(config = {}) {
|
|
376
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
377
|
+
this.marketName = this.config.market || (this.config.assetA && this.config.assetB ? `${this.config.assetA}/${this.config.assetB}` : null);
|
|
378
|
+
const logFile = config.logFile || undefined;
|
|
379
|
+
const loggingConfig = this.config.logging;
|
|
380
|
+
this.logger = new Logger('DEXBot', {
|
|
381
|
+
level: loggingConfig?.level ?? LOG_LEVEL,
|
|
382
|
+
logFile,
|
|
383
|
+
configOverride: loggingConfig?.config ?? undefined
|
|
384
|
+
});
|
|
385
|
+
this.logger.marketName = this.marketName;
|
|
386
|
+
this.orders = Object.freeze(new Map());
|
|
387
|
+
this.boundaryIdx = null;
|
|
388
|
+
this.targetGrid = null;
|
|
389
|
+
this.accountant = new Accountant(this);
|
|
390
|
+
this.strategy = new StrategyEngine(this);
|
|
391
|
+
this.sync = new SyncEngine(this);
|
|
392
|
+
this._state = new StateManager({ logger: this.logger });
|
|
393
|
+
// Index Sets use mutable mutation patterns controlled via _applyOrderUpdate
|
|
394
|
+
// These are private implementation details and must NOT be mutated directly
|
|
395
|
+
// All external code must go through the COW pipeline
|
|
396
|
+
this._ordersByState = {
|
|
397
|
+
[ORDER_STATES.VIRTUAL]: new Set(),
|
|
398
|
+
[ORDER_STATES.ACTIVE]: new Set(),
|
|
399
|
+
[ORDER_STATES.PARTIAL]: new Set()
|
|
400
|
+
};
|
|
401
|
+
this._ordersByType = {
|
|
402
|
+
[ORDER_TYPES.BUY]: new Set(),
|
|
403
|
+
[ORDER_TYPES.SELL]: new Set(),
|
|
404
|
+
[ORDER_TYPES.SPREAD]: new Set()
|
|
405
|
+
};
|
|
406
|
+
this.resetFunds();
|
|
407
|
+
this.btsBalance = { free: 0, total: 0, locked: 0 };
|
|
408
|
+
this.targetSpreadCount = 0;
|
|
409
|
+
this.currentSpreadCount = 0;
|
|
410
|
+
this.outOfSpread = 0;
|
|
411
|
+
this.assets = null;
|
|
412
|
+
this._accountTotalsPromise = null;
|
|
413
|
+
this._accountTotalsResolve = null;
|
|
414
|
+
this._isFetchingTotals = false;
|
|
415
|
+
this.ordersNeedingPriceCorrection = [];
|
|
416
|
+
this.shadowOrderIds = new Map();
|
|
417
|
+
this.processedFillTracker = new Map();
|
|
418
|
+
this.processedFillStore = null;
|
|
419
|
+
// LOCK HIERARCHY (convention — not enforced at runtime to avoid false
|
|
420
|
+
// positives from async contention and multi-bot sharing a process).
|
|
421
|
+
// Acquire in ascending level order only:
|
|
422
|
+
// Level 0: _divergenceLock (divergence checks — outermost)
|
|
423
|
+
// Level 1: _fillProcessingLock (fill processing)
|
|
424
|
+
// Level 2: _gridLock (grid mutations)
|
|
425
|
+
// Level 3: _syncLock (sync operations)
|
|
426
|
+
// Level 4: _fundLock (fund operations — innermost)
|
|
427
|
+
// WARNING: AsyncLock is NOT reentrant.
|
|
428
|
+
this._divergenceLock = new AsyncLock({ level: 0 });
|
|
429
|
+
this._fillProcessingLock = new AsyncLock({ level: 1 });
|
|
430
|
+
this._gridLock = new AsyncLock({ level: 2 });
|
|
431
|
+
this._syncLock = new AsyncLock({ level: 3 });
|
|
432
|
+
this._fundLock = new AsyncLock({ level: 4, timeout: 30000 });
|
|
433
|
+
this._recentlyRotatedOrderIds = new Set();
|
|
434
|
+
this._gridSidesUpdated = new Set();
|
|
435
|
+
this._pauseFundRecalc = 0;
|
|
436
|
+
this._pauseRecalcLogging = false;
|
|
437
|
+
this._throwOnIllegalState = false;
|
|
438
|
+
this._pipelineBlockedSince = null;
|
|
439
|
+
this._recoveryAttempted = false;
|
|
440
|
+
this._gridVersion = 0;
|
|
441
|
+
this._gridPersistenceSuspendedReason = null;
|
|
442
|
+
this._pendingBroadcasts = new Map();
|
|
443
|
+
this._gridDirty = false;
|
|
444
|
+
this._gridDirtyReasons = new Map();
|
|
445
|
+
this._gridDirtySince = null;
|
|
446
|
+
this._metrics = {
|
|
447
|
+
fundRecalcCount: 0,
|
|
448
|
+
invariantViolations: { buy: 0, sell: 0 },
|
|
449
|
+
lockAcquisitions: 0,
|
|
450
|
+
lockContentionSkips: 0,
|
|
451
|
+
spreadRoleConversionBlocked: 0,
|
|
452
|
+
lastSyncDurationMs: 0,
|
|
453
|
+
metricsStartTime: Date.now()
|
|
454
|
+
};
|
|
455
|
+
this._state.startBootstrap();
|
|
456
|
+
this._currentWorkingGrid = null;
|
|
457
|
+
this._cowEngine = null;
|
|
458
|
+
this._cleanExpiredLocks();
|
|
459
|
+
}
|
|
460
|
+
_getCOWEngine() {
|
|
461
|
+
if (!this._cowEngine && this.assets) {
|
|
462
|
+
this._cowEngine = new COWRebalanceEngine({
|
|
463
|
+
strategy: this.strategy,
|
|
464
|
+
logger: this.logger,
|
|
465
|
+
assets: this.assets,
|
|
466
|
+
config: this.config
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
return this._cowEngine;
|
|
470
|
+
}
|
|
471
|
+
_clearWorkingGridRef() {
|
|
472
|
+
this._currentWorkingGrid = null;
|
|
473
|
+
this._state.clearWorkingGrid();
|
|
474
|
+
this._state.setRebalanceState(REBALANCE_STATES.NORMAL);
|
|
475
|
+
}
|
|
476
|
+
_setRebalanceState(state) {
|
|
477
|
+
this._state.setRebalanceState(state);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* @returns {boolean}
|
|
481
|
+
*/
|
|
482
|
+
isRebalancing() {
|
|
483
|
+
return this._state.isRebalancing();
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* @returns {boolean}
|
|
487
|
+
*/
|
|
488
|
+
isBroadcasting() {
|
|
489
|
+
return this._state.isBroadcasting();
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* @returns {boolean}
|
|
493
|
+
*/
|
|
494
|
+
isPlanningActive() {
|
|
495
|
+
return this.isRebalancing() || this.isBroadcasting();
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* @returns {void}
|
|
499
|
+
*/
|
|
500
|
+
startBootstrap() {
|
|
501
|
+
this._state.startBootstrap();
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* @returns {import('./types').BootstrapResult}
|
|
505
|
+
*/
|
|
506
|
+
finishBootstrap() {
|
|
507
|
+
const result = { hadDrift: false, driftInfo: null };
|
|
508
|
+
if (this._state.isBootstrapping()) {
|
|
509
|
+
this._state.finishBootstrap();
|
|
510
|
+
// Validate fund state at bootstrap completion - if drift exists here,
|
|
511
|
+
// it's not transient (grid is now stable) and indicates a potential bug
|
|
512
|
+
const driftCheck = this.checkFundDriftAfterFills();
|
|
513
|
+
if (!driftCheck.isValid) {
|
|
514
|
+
result.hadDrift = true;
|
|
515
|
+
result.driftInfo = driftCheck;
|
|
516
|
+
this.logger.log(`[BOOTSTRAP-END] Fund drift detected after bootstrap: ${driftCheck.reason}. ` +
|
|
517
|
+
`This may indicate a bug in grid initialization.`, 'warn');
|
|
518
|
+
}
|
|
519
|
+
this.logger.log("Bootstrap phase complete. Grid health monitoring and fund invariants active.", "info");
|
|
520
|
+
}
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* @returns {void}
|
|
525
|
+
*/
|
|
526
|
+
startBroadcasting() {
|
|
527
|
+
this._state.startBroadcasting();
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* @returns {void}
|
|
531
|
+
*/
|
|
532
|
+
stopBroadcasting() {
|
|
533
|
+
this._state.stopBroadcasting();
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* @returns {void}
|
|
537
|
+
*/
|
|
538
|
+
resetFunds() {
|
|
539
|
+
return this.accountant.resetFunds();
|
|
540
|
+
}
|
|
541
|
+
async _deductFromChainFree(orderType, size, operation) {
|
|
542
|
+
if (!this.accountant)
|
|
543
|
+
return;
|
|
544
|
+
return await this.accountant.tryDeductFromChainFree(orderType, size, operation);
|
|
545
|
+
}
|
|
546
|
+
async _addToChainFree(orderType, size, operation) {
|
|
547
|
+
if (!this.accountant)
|
|
548
|
+
return;
|
|
549
|
+
return await this.accountant.addToChainFree(orderType, size, operation);
|
|
550
|
+
}
|
|
551
|
+
_getGridTotal(side) {
|
|
552
|
+
return (this.funds?.committed?.grid?.[side] || 0) + (this.funds?.virtual?.[side] || 0);
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* @returns {import('./types').ChainFundsSnapshot}
|
|
556
|
+
*/
|
|
557
|
+
getChainFundsSnapshot() {
|
|
558
|
+
const totals = computeChainFundTotals(this.accountTotals, this.funds?.committed?.chain);
|
|
559
|
+
const allocatedBuy = toFiniteNumber(this.funds?.allocated?.buy, totals.chainTotalBuy);
|
|
560
|
+
const allocatedSell = toFiniteNumber(this.funds?.allocated?.sell, totals.chainTotalSell);
|
|
561
|
+
const btsBalance = (this.config.assetA !== 'BTS' && this.config.assetB !== 'BTS')
|
|
562
|
+
? (this.btsBalance || { free: 0, total: 0, locked: 0 })
|
|
563
|
+
: null;
|
|
564
|
+
return { ...totals, allocatedBuy, allocatedSell, btsBalance };
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* @param {number} [timeoutMs]
|
|
568
|
+
* @returns {Promise<void>}
|
|
569
|
+
*/
|
|
570
|
+
async waitForAccountTotals(timeoutMs = TIMING.ACCOUNT_TOTALS_TIMEOUT_MS) {
|
|
571
|
+
if (hasValidAccountTotals(this.accountTotals, true))
|
|
572
|
+
return;
|
|
573
|
+
let waitPromise = null;
|
|
574
|
+
await this._fundLock.acquire(async () => {
|
|
575
|
+
if (hasValidAccountTotals(this.accountTotals, true))
|
|
576
|
+
return;
|
|
577
|
+
if (!this._accountTotalsPromise) {
|
|
578
|
+
this._accountTotalsPromise = new Promise((resolve) => {
|
|
579
|
+
this._accountTotalsResolve = resolve;
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
waitPromise = this._accountTotalsPromise;
|
|
583
|
+
});
|
|
584
|
+
if (!waitPromise)
|
|
585
|
+
return;
|
|
586
|
+
await Promise.race([
|
|
587
|
+
waitPromise,
|
|
588
|
+
new Promise((resolve) => {
|
|
589
|
+
setTimeout(() => {
|
|
590
|
+
this.logger.log('[FUND] Timeout waiting for account totals', 'warn');
|
|
591
|
+
resolve();
|
|
592
|
+
}, timeoutMs);
|
|
593
|
+
})
|
|
594
|
+
]);
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* @param {string} [accountId] - Blockchain account ID
|
|
598
|
+
* @returns {Promise<void>}
|
|
599
|
+
*/
|
|
600
|
+
async fetchAccountTotals(accountId) {
|
|
601
|
+
if (accountId)
|
|
602
|
+
this.accountId = accountId;
|
|
603
|
+
await this._fetchAccountBalancesAndSetTotals();
|
|
604
|
+
}
|
|
605
|
+
async _fetchAccountBalancesAndSetTotals() {
|
|
606
|
+
return await this.sync.fetchAccountBalancesAndSetTotals();
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* @param {import('./types').AccountTotals} totals - Account balance totals
|
|
610
|
+
* @returns {Promise<void>}
|
|
611
|
+
*/
|
|
612
|
+
async setAccountTotals(totals = { buy: null, sell: null, buyFree: null, sellFree: null }) {
|
|
613
|
+
return await this._fundLock.acquire(async () => {
|
|
614
|
+
return await this._setAccountTotals(totals);
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
async _setAccountTotals(totals) {
|
|
618
|
+
this.accountTotals = { ...(this.accountTotals || {}), ...totals };
|
|
619
|
+
if (!this.funds)
|
|
620
|
+
this.resetFunds();
|
|
621
|
+
await this._recalculateFunds();
|
|
622
|
+
if (hasValidAccountTotals(this.accountTotals, true) && typeof this._accountTotalsResolve === 'function') {
|
|
623
|
+
try {
|
|
624
|
+
this._accountTotalsResolve();
|
|
625
|
+
}
|
|
626
|
+
catch (e) {
|
|
627
|
+
this.logger?.log?.(`Error resolving account totals promise: ${e.message}`, 'warn');
|
|
628
|
+
}
|
|
629
|
+
this._accountTotalsPromise = null;
|
|
630
|
+
this._accountTotalsResolve = null;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
_triggerAccountTotalsFetchIfNeeded() {
|
|
634
|
+
if (!this._isFetchingTotals) {
|
|
635
|
+
this._isFetchingTotals = true;
|
|
636
|
+
this._fetchAccountBalancesAndSetTotals().finally(() => {
|
|
637
|
+
this._isFetchingTotals = false;
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* @returns {void}
|
|
643
|
+
*/
|
|
644
|
+
applyBotFundsAllocation() {
|
|
645
|
+
if (!this.config.botFunds || !this.accountTotals)
|
|
646
|
+
return;
|
|
647
|
+
const { chainTotalBuy, chainTotalSell } = computeChainFundTotals(this.accountTotals, this.funds?.committed?.chain);
|
|
648
|
+
const account = this.config.preferredAccount;
|
|
649
|
+
const botName = this.config.botKey;
|
|
650
|
+
const allocatedBuy = resolveConfigValueWithRegistry(this.config.botFunds.buy, chainTotalBuy, account, botName, 'buy');
|
|
651
|
+
const allocatedSell = resolveConfigValueWithRegistry(this.config.botFunds.sell, chainTotalSell, account, botName, 'sell');
|
|
652
|
+
if (allocatedBuy === 0 && typeof this.config.botFunds.buy === 'string' && this.config.botFunds.buy.trim().endsWith('%')) {
|
|
653
|
+
if (chainTotalBuy === 0)
|
|
654
|
+
this._triggerAccountTotalsFetchIfNeeded();
|
|
655
|
+
}
|
|
656
|
+
if (allocatedSell === 0 && typeof this.config.botFunds.sell === 'string' && this.config.botFunds.sell.trim().endsWith('%')) {
|
|
657
|
+
if (chainTotalSell === 0)
|
|
658
|
+
this._triggerAccountTotalsFetchIfNeeded();
|
|
659
|
+
}
|
|
660
|
+
this.funds.allocated = { buy: allocatedBuy, sell: allocatedSell };
|
|
661
|
+
const shouldCapBuy = allocatedBuy > 0 || isExplicitZeroAllocation(this.config.botFunds.buy);
|
|
662
|
+
const shouldCapSell = allocatedSell > 0 || isExplicitZeroAllocation(this.config.botFunds.sell);
|
|
663
|
+
if (shouldCapBuy)
|
|
664
|
+
this.funds.available.buy = Math.min(this.funds.available.buy, Math.max(0, allocatedBuy));
|
|
665
|
+
if (shouldCapSell)
|
|
666
|
+
this.funds.available.sell = Math.min(this.funds.available.sell, Math.max(0, allocatedSell));
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* @returns {Promise<void>}
|
|
670
|
+
*/
|
|
671
|
+
async recalculateFunds() {
|
|
672
|
+
return await this._fundLock.acquire(async () => {
|
|
673
|
+
return await this._recalculateFunds();
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
async _recalculateFunds() {
|
|
677
|
+
if (!this.accountant)
|
|
678
|
+
return;
|
|
679
|
+
this._metrics.fundRecalcCount++;
|
|
680
|
+
await this.accountant.recalculateFunds();
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* @returns {void}
|
|
684
|
+
*/
|
|
685
|
+
pauseFundRecalc() {
|
|
686
|
+
this._pauseFundRecalc++;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* @returns {Promise<void>}
|
|
690
|
+
*/
|
|
691
|
+
async resumeFundRecalc() {
|
|
692
|
+
this._pauseFundRecalc = Math.max(0, this._pauseFundRecalc - 1);
|
|
693
|
+
if (this._pauseFundRecalc === 0) {
|
|
694
|
+
await this.recalculateFunds();
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* @returns {void}
|
|
699
|
+
*/
|
|
700
|
+
pauseRecalcLogging() {
|
|
701
|
+
this._pauseRecalcLogging = true;
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* @returns {void}
|
|
705
|
+
*/
|
|
706
|
+
resumeRecalcLogging() {
|
|
707
|
+
this._pauseRecalcLogging = false;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* @param {Array<import('./types').Order>} orders
|
|
711
|
+
* @param {Object} info
|
|
712
|
+
* @returns {Promise<import('./types').SyncResult>}
|
|
713
|
+
*/
|
|
714
|
+
syncFromOpenOrders(orders, info) {
|
|
715
|
+
return this.sync.syncFromOpenOrders(orders, info);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* @param {Object} fill - Fill event data
|
|
719
|
+
* @param {Object} [options]
|
|
720
|
+
* @returns {Promise<import('./types').SyncResult>}
|
|
721
|
+
*/
|
|
722
|
+
syncFromFillHistory(fill, options) {
|
|
723
|
+
return this.sync.syncFromFillHistory(fill, options);
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* @param {Object} data - Chain data to synchronize
|
|
727
|
+
* @param {string} src - Source identifier
|
|
728
|
+
* @returns {Promise<import('./types').SyncResult>}
|
|
729
|
+
*/
|
|
730
|
+
async synchronizeWithChain(data, src, options = {}) {
|
|
731
|
+
// _gridLock acquisition is delegated to sync.synchronizeWithChain itself.
|
|
732
|
+
// createOrder / cancelOrder acquire it inline; readOpenOrders and
|
|
733
|
+
// periodicBlockchainFetch acquire it inside syncFromOpenOrders.
|
|
734
|
+
return await this._applySync(data, src, options);
|
|
735
|
+
}
|
|
736
|
+
async _applySync(data, src, options = {}) {
|
|
737
|
+
return await this.sync.synchronizeWithChain(data, src, options);
|
|
738
|
+
}
|
|
739
|
+
async _initializeAssets() {
|
|
740
|
+
return await this.sync.initializeAssets();
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* @param {string[]|Set<string>} orderIds - Order IDs to lock
|
|
744
|
+
* @returns {void}
|
|
745
|
+
*/
|
|
746
|
+
lockOrders(orderIds) {
|
|
747
|
+
if (!orderIds)
|
|
748
|
+
return;
|
|
749
|
+
const expiration = Date.now() + TIMING.LOCK_TIMEOUT_MS;
|
|
750
|
+
for (const id of orderIds)
|
|
751
|
+
if (id)
|
|
752
|
+
this.shadowOrderIds.set(id, expiration);
|
|
753
|
+
this._cleanExpiredLocks();
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* @param {string[]|Set<string>} orderIds - Order IDs to unlock
|
|
757
|
+
* @returns {void}
|
|
758
|
+
*/
|
|
759
|
+
unlockOrders(orderIds) {
|
|
760
|
+
if (!orderIds)
|
|
761
|
+
return;
|
|
762
|
+
for (const id of orderIds)
|
|
763
|
+
if (id)
|
|
764
|
+
this.shadowOrderIds.delete(id);
|
|
765
|
+
this._cleanExpiredLocks();
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* @param {string} id - Order ID
|
|
769
|
+
* @returns {boolean}
|
|
770
|
+
*/
|
|
771
|
+
isOrderLocked(id) {
|
|
772
|
+
const expiresAt = this.shadowOrderIds.get(id);
|
|
773
|
+
if (!expiresAt)
|
|
774
|
+
return false;
|
|
775
|
+
if (Date.now() > expiresAt) {
|
|
776
|
+
this.shadowOrderIds.delete(id);
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
return true;
|
|
780
|
+
}
|
|
781
|
+
_cleanExpiredLocks() {
|
|
782
|
+
const now = Date.now();
|
|
783
|
+
for (const [id, expiresAt] of this.shadowOrderIds) {
|
|
784
|
+
if (now > expiresAt) {
|
|
785
|
+
this.shadowOrderIds.delete(id);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
_normalizeOrderUpdateOptions(options = {}) {
|
|
790
|
+
if (options === null || typeof options !== 'object' || Array.isArray(options)) {
|
|
791
|
+
throw new TypeError('Order update options must be an object');
|
|
792
|
+
}
|
|
793
|
+
return {
|
|
794
|
+
skipAccounting: options.skipAccounting === true,
|
|
795
|
+
fee: Number.isFinite(Number(options.fee)) ? Number(options.fee) : 0
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
_normalizeCommitOptions(options = {}) {
|
|
799
|
+
if (options === null || typeof options !== 'object' || Array.isArray(options)) {
|
|
800
|
+
throw new TypeError('Commit options must be an object');
|
|
801
|
+
}
|
|
802
|
+
return { skipRecalc: options.skipRecalc === true };
|
|
803
|
+
}
|
|
804
|
+
async _updateOrder(order, context = 'updateOrder', options = {}) {
|
|
805
|
+
const updateOptions = this._normalizeOrderUpdateOptions(options);
|
|
806
|
+
return await this._gridLock.acquire(async () => {
|
|
807
|
+
return await this._applyOrderUpdate(order, context, updateOptions);
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
async _applyOrderUpdate(order, context = 'updateOrder', options = {}) {
|
|
811
|
+
const updateOptions = this._normalizeOrderUpdateOptions(options);
|
|
812
|
+
const { skipAccounting, fee: normalizedFee } = updateOptions;
|
|
813
|
+
const oldOrder = this.orders.get(order.id);
|
|
814
|
+
const validation = validateOrder(order, oldOrder, context);
|
|
815
|
+
for (const warning of validation.warnings) {
|
|
816
|
+
this.logger.log(warning.message, 'warn');
|
|
817
|
+
}
|
|
818
|
+
if (!validation.isValid && validation.errors.length > 0) {
|
|
819
|
+
const fatalError = validation.errors.find(e => e.isFatal || e.code === 'ILLEGAL_SPREAD_STATE');
|
|
820
|
+
if (fatalError) {
|
|
821
|
+
this.logger.log(fatalError.message, 'error');
|
|
822
|
+
this._state.setIllegalStateSignal({
|
|
823
|
+
id: order.id,
|
|
824
|
+
context,
|
|
825
|
+
message: fatalError.message
|
|
826
|
+
});
|
|
827
|
+
if (this._throwOnIllegalState) {
|
|
828
|
+
const err = new Error(fatalError.message);
|
|
829
|
+
err.code = fatalError.code;
|
|
830
|
+
throw err;
|
|
831
|
+
}
|
|
832
|
+
return false;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
// Ensure a mutable copy before passing to updateOptimisticFreeBalance.
|
|
836
|
+
// validation.normalizedOrder may reference a frozen master-grid order,
|
|
837
|
+
// and _resolveBtsFeeLifecycle mutates btsFeeState on the order object.
|
|
838
|
+
let nextOrder = { ...validation.normalizedOrder };
|
|
839
|
+
// Apply phantom order auto-correction to the normalized order
|
|
840
|
+
const phantomError = validation.errors.find(e => e.code === 'PHANTOM_ORDER');
|
|
841
|
+
if (phantomError && phantomError.autoCorrect) {
|
|
842
|
+
nextOrder = { ...nextOrder, ...phantomError.autoCorrect };
|
|
843
|
+
}
|
|
844
|
+
if (this.accountant) {
|
|
845
|
+
await this.accountant.updateOptimisticFreeBalance(oldOrder, nextOrder, context, normalizedFee, skipAccounting);
|
|
846
|
+
}
|
|
847
|
+
const updatedOrder = deepFreeze({ ...nextOrder });
|
|
848
|
+
const id = order.id;
|
|
849
|
+
Object.values(this._ordersByState).forEach(set => set.delete(id));
|
|
850
|
+
Object.values(this._ordersByType).forEach(set => set.delete(id));
|
|
851
|
+
if (this._ordersByState[updatedOrder.state]) {
|
|
852
|
+
this._ordersByState[updatedOrder.state].add(id);
|
|
853
|
+
}
|
|
854
|
+
if (this._ordersByType[updatedOrder.type]) {
|
|
855
|
+
this._ordersByType[updatedOrder.type].add(id);
|
|
856
|
+
}
|
|
857
|
+
const newMap = cloneMap(this.orders);
|
|
858
|
+
newMap.set(id, updatedOrder);
|
|
859
|
+
this.orders = Object.freeze(newMap);
|
|
860
|
+
this._gridVersion++;
|
|
861
|
+
this._syncWorkingGridFromMasterMutation(id, context);
|
|
862
|
+
if (this._pauseFundRecalc === 0) {
|
|
863
|
+
await this.recalculateFunds();
|
|
864
|
+
}
|
|
865
|
+
this._markGridDirty(context, id);
|
|
866
|
+
return true;
|
|
867
|
+
}
|
|
868
|
+
_syncWorkingGridFromMasterMutation(orderId, context) {
|
|
869
|
+
if (!this._currentWorkingGrid || !this.isPlanningActive()) {
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
try {
|
|
873
|
+
this._currentWorkingGrid.markStale(`master mutation during ${this._rebalanceState.toLowerCase()} (${context})`);
|
|
874
|
+
this._currentWorkingGrid.syncFromMaster(this.orders, orderId, this._gridVersion);
|
|
875
|
+
}
|
|
876
|
+
catch (syncErr) {
|
|
877
|
+
this._currentWorkingGrid.markStale(`working-grid sync failure: ${syncErr.message}`);
|
|
878
|
+
this.logger.log(`[COW] Failed to sync working grid for order ${orderId}: ${syncErr.message}`, 'warn');
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* @param {Array<import('./types').Order>} updates - Order updates to apply
|
|
883
|
+
* @param {string} [context] - Update context label
|
|
884
|
+
* @param {import('./types').OrderUpdateOptions} [options]
|
|
885
|
+
* @returns {Promise<boolean>}
|
|
886
|
+
*/
|
|
887
|
+
async applyGridUpdateBatch(updates, context = 'batch-update', options = {}) {
|
|
888
|
+
const updateOptions = this._normalizeOrderUpdateOptions(options);
|
|
889
|
+
return await this._gridLock.acquire(async () => {
|
|
890
|
+
for (const update of updates) {
|
|
891
|
+
await this._applyOrderUpdate(update, context, updateOptions);
|
|
892
|
+
}
|
|
893
|
+
return true;
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Flag the in-memory master grid as dirty so the next flushGridDirty()
|
|
898
|
+
* call persists it. Internal helper — every successful _applyOrderUpdate
|
|
899
|
+
* call ends with this. External callers that mutate the grid through
|
|
900
|
+
* other paths (e.g. raw `this.orders.set(...)` from a refactor) should
|
|
901
|
+
* invoke this explicitly so the dirty-flag invariant still holds.
|
|
902
|
+
*
|
|
903
|
+
* @param {string} [reason='unknown'] - Context label for diagnostics
|
|
904
|
+
* @param {string} [orderId=null] - Order that triggered the mutation
|
|
905
|
+
* @returns {void}
|
|
906
|
+
*/
|
|
907
|
+
_markGridDirty(reason = 'unknown', orderId = null) {
|
|
908
|
+
this._gridDirty = true;
|
|
909
|
+
if (this._gridDirtySince == null) {
|
|
910
|
+
this._gridDirtySince = Date.now();
|
|
911
|
+
}
|
|
912
|
+
const key = orderId ? `${reason}:${orderId}` : reason;
|
|
913
|
+
this._gridDirtyReasons.set(key, (this._gridDirtyReasons.get(key) || 0) + 1);
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Clear the dirty flag after a successful flush. Internal helper.
|
|
917
|
+
* @returns {void}
|
|
918
|
+
*/
|
|
919
|
+
_clearGridDirty() {
|
|
920
|
+
this._gridDirty = false;
|
|
921
|
+
this._gridDirtySince = null;
|
|
922
|
+
this._gridDirtyReasons.clear();
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Public read-only access to the dirty flag. Used by tick-end safety
|
|
926
|
+
* nets and by tests/CI to verify the persistence invariant.
|
|
927
|
+
* @returns {boolean}
|
|
928
|
+
*/
|
|
929
|
+
isGridDirty() {
|
|
930
|
+
return this._gridDirty === true;
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* If the master grid has been mutated since the last successful
|
|
934
|
+
* persistGrid() call, persist it now. This is the end-of-tick safety
|
|
935
|
+
* net that catches direct _updateOrder() calls (e.g. partial-fill size
|
|
936
|
+
* updates) that never reach a COW rebalance and therefore never reach
|
|
937
|
+
* a known persistGrid() site.
|
|
938
|
+
*
|
|
939
|
+
* Idempotent: a no-op when the grid is not dirty. Honours
|
|
940
|
+
* suspendGridPersistence(). Returns the underlying persistGrid()
|
|
941
|
+
* result, or {skipped:true, reason:'not-dirty'} when the grid is clean.
|
|
942
|
+
*
|
|
943
|
+
* @param {string} [contextLabel='flush-grid-dirty'] - Label for logs
|
|
944
|
+
* @returns {Promise<{skipped?: boolean, suspended?: boolean, isValid?: boolean, reason?: string}>}
|
|
945
|
+
*/
|
|
946
|
+
async flushGridDirty(contextLabel = 'flush-grid-dirty') {
|
|
947
|
+
if (!this._gridDirty) {
|
|
948
|
+
return { skipped: true, reason: 'not-dirty' };
|
|
949
|
+
}
|
|
950
|
+
if (this._gridPersistenceSuspendedReason) {
|
|
951
|
+
this.logger?.log?.(`[PERSISTENCE-FLUSH] Skipping dirty-flush while suspended: ${this._gridPersistenceSuspendedReason}`, 'warn');
|
|
952
|
+
return { skipped: true, suspended: true, reason: this._gridPersistenceSuspendedReason };
|
|
953
|
+
}
|
|
954
|
+
const dirtyCount = this._gridDirtyReasons.size;
|
|
955
|
+
const dirtySince = this._gridDirtySince;
|
|
956
|
+
const result = await this.persistGrid(undefined);
|
|
957
|
+
if (result && result.skipped === true) {
|
|
958
|
+
// Persistence was deferred (suspension, validation, etc.) — keep
|
|
959
|
+
// the dirty flag so a later tick can retry.
|
|
960
|
+
return result;
|
|
961
|
+
}
|
|
962
|
+
if (result && result.isValid === false) {
|
|
963
|
+
this.logger?.log?.(`[PERSISTENCE-FLUSH] Dirty flush validation failed (${contextLabel}): ${result.reason || 'unknown'}`, 'warn');
|
|
964
|
+
return result;
|
|
965
|
+
}
|
|
966
|
+
this._clearGridDirty();
|
|
967
|
+
this.logger?.log?.(`[PERSISTENCE-FLUSH] Flushed ${dirtyCount} dirty mutation context(s) ` +
|
|
968
|
+
`(since ${new Date(dirtySince).toISOString()}) via ${contextLabel}`, 'info');
|
|
969
|
+
return result || { isValid: true };
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* @param {Array<import('./types').Order>} orders - Filled orders
|
|
973
|
+
* @param {Set<string>} [excl] - Order IDs to exclude
|
|
974
|
+
* @param {Object} [options]
|
|
975
|
+
* @returns {Promise<import('./types').CowRebalanceResult>}
|
|
976
|
+
*/
|
|
977
|
+
async processFilledOrders(orders, excl, options) {
|
|
978
|
+
// Step 1: Handle Fills (Accounting & State Updates)
|
|
979
|
+
await this.strategy.processFillsOnly(orders, excl);
|
|
980
|
+
// Step 2: Trigger Safe Rebalance only for actual fills.
|
|
981
|
+
const triggerFills = orders.filter(f => !f.isPartial || f.isDelayedRotationTrigger);
|
|
982
|
+
const shouldRebalance = triggerFills.length > 0;
|
|
983
|
+
if (shouldRebalance) {
|
|
984
|
+
const rebalanceResult = await this.performSafeRebalance(orders, excl);
|
|
985
|
+
return rebalanceResult;
|
|
986
|
+
}
|
|
987
|
+
const { WorkingGrid } = require('./working_grid');
|
|
988
|
+
const workingGrid = new WorkingGrid(this.orders, { baseVersion: this._gridVersion });
|
|
989
|
+
return {
|
|
990
|
+
actions: [],
|
|
991
|
+
stateUpdates: [],
|
|
992
|
+
hadRotation: false,
|
|
993
|
+
workingGrid,
|
|
994
|
+
workingIndexes: workingGrid.getIndexes(),
|
|
995
|
+
workingBoundary: this.boundaryIdx,
|
|
996
|
+
aborted: false
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* @returns {Array<import('./types').Order>}
|
|
1001
|
+
*/
|
|
1002
|
+
getInitialOrdersToActivate() {
|
|
1003
|
+
// Apply activeOrders limit from config
|
|
1004
|
+
const sellCount = Math.max(0, toFiniteNumber(this.config.activeOrders?.sell, 1));
|
|
1005
|
+
const buyCount = Math.max(0, toFiniteNumber(this.config.activeOrders?.buy, 1));
|
|
1006
|
+
// Get minimum sizes for validation
|
|
1007
|
+
const minOrderSizeFactor = this.config?.gridLimits?.MIN_ORDER_SIZE_FACTOR;
|
|
1008
|
+
const minSellSize = getMinAbsoluteOrderSize(ORDER_TYPES.SELL, this.assets, minOrderSizeFactor);
|
|
1009
|
+
const minBuySize = getMinAbsoluteOrderSize(ORDER_TYPES.BUY, this.assets, minOrderSizeFactor);
|
|
1010
|
+
// Use integer arithmetic for size comparisons to match blockchain behavior
|
|
1011
|
+
const sellPrecision = this.assets?.assetA?.precision;
|
|
1012
|
+
const buyPrecision = this.assets?.assetB?.precision;
|
|
1013
|
+
const minSellSizeInt = floatToBlockchainInt(minSellSize, sellPrecision);
|
|
1014
|
+
const minBuySizeInt = floatToBlockchainInt(minBuySize, buyPrecision);
|
|
1015
|
+
// Get closest virtual sells (lowest prices first = closest to market), limit to sellCount
|
|
1016
|
+
const vSells = this.getOrdersByTypeAndState(ORDER_TYPES.SELL, ORDER_STATES.VIRTUAL)
|
|
1017
|
+
.sort((a, b) => a.price - b.price)
|
|
1018
|
+
.slice(0, sellCount);
|
|
1019
|
+
// Filter by minimum size, then reverse for placement order (highest first)
|
|
1020
|
+
const validSells = vSells
|
|
1021
|
+
.filter(o => floatToBlockchainInt(o.size, sellPrecision) >= minSellSizeInt)
|
|
1022
|
+
.sort((a, b) => b.price - a.price);
|
|
1023
|
+
// Get closest virtual buys (highest prices first = closest to market), limit to buyCount
|
|
1024
|
+
const vBuys = this.getOrdersByTypeAndState(ORDER_TYPES.BUY, ORDER_STATES.VIRTUAL)
|
|
1025
|
+
.sort((a, b) => b.price - a.price)
|
|
1026
|
+
.slice(0, buyCount);
|
|
1027
|
+
// Filter by minimum size, then reverse for placement order (lowest first)
|
|
1028
|
+
const validBuys = vBuys
|
|
1029
|
+
.filter(o => floatToBlockchainInt(o.size, buyPrecision) >= minBuySizeInt)
|
|
1030
|
+
.sort((a, b) => a.price - b.price);
|
|
1031
|
+
return [...validSells, ...validBuys];
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Get orders matching the specified type and state.
|
|
1035
|
+
*
|
|
1036
|
+
* @param {string|null} type - Order type (ORDER_TYPES.BUY/SELL/SPREAD) or null for all types
|
|
1037
|
+
* @param {string} state - Order state (ORDER_STATES.ACTIVE/PARTIAL/VIRTUAL)
|
|
1038
|
+
* @returns {Array} Array of matching orders
|
|
1039
|
+
*/
|
|
1040
|
+
getOrdersByTypeAndState(type, state) {
|
|
1041
|
+
const result = [];
|
|
1042
|
+
const ids = this._ordersByState[state];
|
|
1043
|
+
if (!ids)
|
|
1044
|
+
return result;
|
|
1045
|
+
for (const id of ids) {
|
|
1046
|
+
const order = this.orders.get(id);
|
|
1047
|
+
// If type is null/undefined, return all orders with matching state
|
|
1048
|
+
// Otherwise, filter by both type and state
|
|
1049
|
+
if (order && order.state === state && (type == null || order.type === type)) {
|
|
1050
|
+
result.push(order);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return result;
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* @param {string} type - ORDER_TYPES.BUY or ORDER_TYPES.SELL
|
|
1057
|
+
* @returns {Array<import('./types').Order>}
|
|
1058
|
+
*/
|
|
1059
|
+
getPartialOrdersOnSide(type) {
|
|
1060
|
+
return this.getOrdersByTypeAndState(type, ORDER_STATES.PARTIAL);
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* @returns {boolean}
|
|
1064
|
+
*/
|
|
1065
|
+
validateIndices() {
|
|
1066
|
+
for (const [id, order] of this.orders) {
|
|
1067
|
+
if (!order) {
|
|
1068
|
+
this.logger.log(`Index corruption: ${id} exists in orders Map but is null/undefined`, 'error');
|
|
1069
|
+
return false;
|
|
1070
|
+
}
|
|
1071
|
+
if (!order.state) {
|
|
1072
|
+
this.logger.log(`Index corruption: ${id} has no state`, 'error');
|
|
1073
|
+
return false;
|
|
1074
|
+
}
|
|
1075
|
+
if (!order.type) {
|
|
1076
|
+
this.logger.log(`Index corruption: ${id} has no type`, 'error');
|
|
1077
|
+
return false;
|
|
1078
|
+
}
|
|
1079
|
+
if (!this._ordersByState[order.state]?.has(id)) {
|
|
1080
|
+
this.logger.log(`Index mismatch: ${id} not in _ordersByState[${order.state}]`, 'error');
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
if (!this._ordersByType[order.type]?.has(id)) {
|
|
1084
|
+
this.logger.log(`Index mismatch: ${id} not in _ordersByType[${order.type}]`, 'error');
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
for (const [state, orderIds] of Object.entries(this._ordersByState)) {
|
|
1089
|
+
for (const id of orderIds) {
|
|
1090
|
+
if (!id || !this.orders.has(id)) {
|
|
1091
|
+
this.logger.log(`Index orphan: ${id} in _ordersByState[${state}] but not in orders Map`, 'error');
|
|
1092
|
+
return false;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
for (const [type, orderIds] of Object.entries(this._ordersByType)) {
|
|
1097
|
+
for (const id of orderIds) {
|
|
1098
|
+
if (!id || !this.orders.has(id)) {
|
|
1099
|
+
this.logger.log(`Index orphan: ${id} in _ordersByType[${type}] but not in orders Map`, 'error');
|
|
1100
|
+
return false;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
return true;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* @returns {boolean}
|
|
1108
|
+
*/
|
|
1109
|
+
assertIndexConsistency() {
|
|
1110
|
+
if (!this.validateIndices()) {
|
|
1111
|
+
this.logger.log('CRITICAL: Index corruption detected! Attempting repair...', 'error');
|
|
1112
|
+
return this._repairIndices();
|
|
1113
|
+
}
|
|
1114
|
+
return true;
|
|
1115
|
+
}
|
|
1116
|
+
_repairIndices() {
|
|
1117
|
+
try {
|
|
1118
|
+
const rebuiltByState = {
|
|
1119
|
+
[ORDER_STATES.VIRTUAL]: new Set(),
|
|
1120
|
+
[ORDER_STATES.ACTIVE]: new Set(),
|
|
1121
|
+
[ORDER_STATES.PARTIAL]: new Set()
|
|
1122
|
+
};
|
|
1123
|
+
const rebuiltByType = {
|
|
1124
|
+
[ORDER_TYPES.BUY]: new Set(),
|
|
1125
|
+
[ORDER_TYPES.SELL]: new Set(),
|
|
1126
|
+
[ORDER_TYPES.SPREAD]: new Set()
|
|
1127
|
+
};
|
|
1128
|
+
for (const [id, order] of this.orders) {
|
|
1129
|
+
if (order && order.state && order.type) {
|
|
1130
|
+
rebuiltByState[order.state]?.add(id);
|
|
1131
|
+
rebuiltByType[order.type]?.add(id);
|
|
1132
|
+
}
|
|
1133
|
+
else {
|
|
1134
|
+
this.logger.log(`Skipping corrupted order ${id} during index repair`, 'warn');
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
this._ordersByState = rebuiltByState;
|
|
1138
|
+
this._ordersByType = rebuiltByType;
|
|
1139
|
+
if (this.validateIndices()) {
|
|
1140
|
+
this.logger.log('✓ Index repair successful', 'info');
|
|
1141
|
+
return true;
|
|
1142
|
+
}
|
|
1143
|
+
this.logger.log('✗ Index repair failed - structure is damaged', 'error');
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
catch (e) {
|
|
1147
|
+
this.logger.log(`Index repair failed with exception: ${e.message}`, 'error');
|
|
1148
|
+
return false;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* @returns {Object|null} The consumed signal or null
|
|
1153
|
+
*/
|
|
1154
|
+
consumeIllegalStateSignal() {
|
|
1155
|
+
return this._state.consumeIllegalStateSignal();
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* @returns {Object|null} The consumed signal or null
|
|
1159
|
+
*/
|
|
1160
|
+
consumeAccountingFailureSignal() {
|
|
1161
|
+
return this._state.consumeAccountingFailureSignal();
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* @param {Object} BitShares - BitShares API instance
|
|
1165
|
+
* @param {Function} batchCb - Batch callback
|
|
1166
|
+
* @returns {Promise<Object>}
|
|
1167
|
+
*/
|
|
1168
|
+
async checkSpreadCondition(BitShares, batchCb) {
|
|
1169
|
+
return await Grid.checkSpreadCondition(this, BitShares, batchCb);
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* @param {Function} batchCb - Batch callback
|
|
1173
|
+
* @returns {Promise<Object>}
|
|
1174
|
+
*/
|
|
1175
|
+
async checkGridHealth(batchCb) {
|
|
1176
|
+
return await Grid.checkGridHealth(this, batchCb);
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* @returns {Object} Current spread calculation
|
|
1180
|
+
*/
|
|
1181
|
+
calculateCurrentSpread() {
|
|
1182
|
+
return Grid.calculateCurrentSpread(this);
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* @returns {import('./types').DriftCheckResult}
|
|
1186
|
+
*/
|
|
1187
|
+
checkFundDriftAfterFills() {
|
|
1188
|
+
if (!this.assets || !hasValidAccountTotals(this.accountTotals)) {
|
|
1189
|
+
return { isValid: true, reason: 'Skipped: missing assets or totals' };
|
|
1190
|
+
}
|
|
1191
|
+
return checkFundDrift(this.orders, this.accountTotals, this.assets, this.config?.gridLimits ?? null);
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* @param {Object|number} [pipelineSignals] - Pipeline state signals or queue length
|
|
1195
|
+
* @returns {import('./types').PipelineEmptyResult}
|
|
1196
|
+
*/
|
|
1197
|
+
isPipelineEmpty(pipelineSignals = 0) {
|
|
1198
|
+
const normalizedSignals = (typeof pipelineSignals === 'number')
|
|
1199
|
+
? { incomingFillQueueLength: pipelineSignals }
|
|
1200
|
+
: (pipelineSignals || {});
|
|
1201
|
+
const incomingFillQueueLength = toFiniteNumber(normalizedSignals.incomingFillQueueLength);
|
|
1202
|
+
const shadowLocks = toFiniteNumber(normalizedSignals.shadowLocks);
|
|
1203
|
+
const batchInFlight = !!normalizedSignals.batchInFlight;
|
|
1204
|
+
const recoveryInFlight = !!normalizedSignals.recoveryInFlight;
|
|
1205
|
+
const broadcasting = !!normalizedSignals.broadcasting;
|
|
1206
|
+
this._cleanExpiredLocks();
|
|
1207
|
+
const reasons = [];
|
|
1208
|
+
// invariant: _gridSidesUpdated is pre-cleared by executeMaintenanceLogic
|
|
1209
|
+
// before calling isPipelineEmpty (see modules/dexbot_maintenance_runtime.ts:1378).
|
|
1210
|
+
// Any new caller must pre-clear or add its own gating to avoid a permanently
|
|
1211
|
+
// blocked pipeline.
|
|
1212
|
+
if (incomingFillQueueLength > 0) {
|
|
1213
|
+
reasons.push(`${incomingFillQueueLength} fills queued`);
|
|
1214
|
+
}
|
|
1215
|
+
if (this.ordersNeedingPriceCorrection.length > 0) {
|
|
1216
|
+
reasons.push(`${this.ordersNeedingPriceCorrection.length} corrections pending`);
|
|
1217
|
+
}
|
|
1218
|
+
if (shadowLocks > 0) {
|
|
1219
|
+
reasons.push(`${shadowLocks} shadow lock(s) active`);
|
|
1220
|
+
}
|
|
1221
|
+
if (batchInFlight) {
|
|
1222
|
+
reasons.push('batch broadcast in-flight');
|
|
1223
|
+
}
|
|
1224
|
+
if (recoveryInFlight) {
|
|
1225
|
+
reasons.push('recovery sync in-flight');
|
|
1226
|
+
}
|
|
1227
|
+
if (broadcasting || this._state.isBroadcastingActive()) {
|
|
1228
|
+
reasons.push('broadcasting active orders');
|
|
1229
|
+
}
|
|
1230
|
+
if (reasons.length > 0 && !this._pipelineBlockedSince) {
|
|
1231
|
+
this._pipelineBlockedSince = Date.now();
|
|
1232
|
+
this._state.markPipelineBlocked();
|
|
1233
|
+
}
|
|
1234
|
+
else if (reasons.length === 0) {
|
|
1235
|
+
this._pipelineBlockedSince = null;
|
|
1236
|
+
this._state.markPipelineClear();
|
|
1237
|
+
}
|
|
1238
|
+
return {
|
|
1239
|
+
isEmpty: reasons.length === 0,
|
|
1240
|
+
reasons
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* @returns {boolean} Whether stale operations were cleared
|
|
1245
|
+
*/
|
|
1246
|
+
clearStalePipelineOperations() {
|
|
1247
|
+
if (!this._pipelineBlockedSince)
|
|
1248
|
+
return false;
|
|
1249
|
+
const age = Date.now() - this._pipelineBlockedSince;
|
|
1250
|
+
if (age < PIPELINE_TIMING.TIMEOUT_MS)
|
|
1251
|
+
return false;
|
|
1252
|
+
this.ordersNeedingPriceCorrection = [];
|
|
1253
|
+
this._pipelineBlockedSince = null;
|
|
1254
|
+
this._state.markPipelineClear();
|
|
1255
|
+
return true;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* @returns {import('./types').PipelineHealth}
|
|
1259
|
+
*/
|
|
1260
|
+
getPipelineHealth() {
|
|
1261
|
+
const blockedDuration = this._pipelineBlockedSince
|
|
1262
|
+
? Date.now() - this._pipelineBlockedSince
|
|
1263
|
+
: 0;
|
|
1264
|
+
return {
|
|
1265
|
+
isBlocked: this._pipelineBlockedSince !== null,
|
|
1266
|
+
blockedDurationMs: blockedDuration,
|
|
1267
|
+
hasStalled: blockedDuration > PIPELINE_TIMING.TIMEOUT_MS,
|
|
1268
|
+
recoveryAttempted: this._recoveryAttempted,
|
|
1269
|
+
correctionsPending: this.ordersNeedingPriceCorrection.length,
|
|
1270
|
+
gridSidesUpdated: this._gridSidesUpdated?.size || 0
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* @param {Map<string, import('./types').Order>} targetGrid
|
|
1275
|
+
* @param {number} targetBoundary
|
|
1276
|
+
* @returns {Object}
|
|
1277
|
+
*/
|
|
1278
|
+
reconcileGrid(targetGrid, targetBoundary) {
|
|
1279
|
+
return reconcileGrid(this.orders, targetGrid, targetBoundary, {
|
|
1280
|
+
logger: (msg, level) => this.logger.log(msg, level),
|
|
1281
|
+
dustThresholdPercent: this.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* @param {Array} [fills] - Fill events triggering rebalance
|
|
1286
|
+
* @param {Set<string>} [excludeIds] - Order IDs to exclude
|
|
1287
|
+
* @returns {Promise<import('./types').CowRebalanceResult>}
|
|
1288
|
+
*/
|
|
1289
|
+
async performSafeRebalance(fills = [], excludeIds = new Set()) {
|
|
1290
|
+
this.logger.log("[SAFE-REBALANCE] Starting with COW...", "info");
|
|
1291
|
+
return await this._gridLock.acquire(async () => {
|
|
1292
|
+
return await this._applySafeRebalanceCOW(fills, excludeIds);
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
async _applySafeRebalanceCOW(fills = [], excludeIds = new Set()) {
|
|
1296
|
+
const cowEngine = this._getCOWEngine();
|
|
1297
|
+
if (!cowEngine) {
|
|
1298
|
+
return buildAbortedResult('COW Engine not initialized (assets not available)');
|
|
1299
|
+
}
|
|
1300
|
+
this._setRebalanceState(REBALANCE_STATES.REBALANCING);
|
|
1301
|
+
const result = await cowEngine.execute({
|
|
1302
|
+
masterGrid: this.orders,
|
|
1303
|
+
gridVersion: this._gridVersion,
|
|
1304
|
+
boundaryIdx: this.boundaryIdx,
|
|
1305
|
+
funds: this.getChainFundsSnapshot(),
|
|
1306
|
+
fills,
|
|
1307
|
+
excludeIds
|
|
1308
|
+
});
|
|
1309
|
+
if (result.aborted) {
|
|
1310
|
+
this._clearWorkingGridRef();
|
|
1311
|
+
return result;
|
|
1312
|
+
}
|
|
1313
|
+
this._currentWorkingGrid = result.workingGrid;
|
|
1314
|
+
return result;
|
|
1315
|
+
}
|
|
1316
|
+
_reconcileGridCOW(targetGrid, targetBoundary, workingGrid) {
|
|
1317
|
+
const result = this.reconcileGrid(targetGrid, targetBoundary);
|
|
1318
|
+
if (result.aborted)
|
|
1319
|
+
return result;
|
|
1320
|
+
const actions = optimizeRebalanceActions(result.actions || [], this.orders);
|
|
1321
|
+
projectTargetToWorkingGrid(workingGrid, targetGrid, { actions });
|
|
1322
|
+
return {
|
|
1323
|
+
...result,
|
|
1324
|
+
actions,
|
|
1325
|
+
...summarizeActions(actions)
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
_validateWorkingGridFunds(workingGrid, projectedFunds) {
|
|
1329
|
+
return validateWorkingGridFunds(workingGrid, projectedFunds, {
|
|
1330
|
+
buyPrecision: this.assets?.assetB?.precision,
|
|
1331
|
+
sellPrecision: this.assets?.assetA?.precision
|
|
1332
|
+
}, this.assets);
|
|
1333
|
+
}
|
|
1334
|
+
_calculateRequiredFundsFromGrid(workingGrid, precisions = {}) {
|
|
1335
|
+
return calculateRequiredFunds(workingGrid, {
|
|
1336
|
+
buyPrecision: precisions.buyPrecision || this.assets?.assetB?.precision,
|
|
1337
|
+
sellPrecision: precisions.sellPrecision || this.assets?.assetA?.precision
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
_getCowComparePrecisions() {
|
|
1341
|
+
const buyPrecisionRaw = this.assets?.assetB?.precision;
|
|
1342
|
+
const sellPrecisionRaw = this.assets?.assetA?.precision;
|
|
1343
|
+
const incrementPercentRaw = this.config?.incrementPercent;
|
|
1344
|
+
const buyPrecision = Number(buyPrecisionRaw);
|
|
1345
|
+
const sellPrecision = Number(sellPrecisionRaw);
|
|
1346
|
+
const incrementPercent = Number(incrementPercentRaw);
|
|
1347
|
+
if (!Number.isFinite(buyPrecision) || !Number.isFinite(sellPrecision)) {
|
|
1348
|
+
throw new Error(`CRITICAL: Missing asset precision for COW compare (buy=${buyPrecisionRaw}, sell=${sellPrecisionRaw}). ` +
|
|
1349
|
+
`Refusing commit-time delta comparison.`);
|
|
1350
|
+
}
|
|
1351
|
+
if (!Number.isFinite(incrementPercent) || incrementPercent <= 0) {
|
|
1352
|
+
throw new Error(`CRITICAL: Missing/invalid incrementPercent for COW compare (${incrementPercentRaw}). ` +
|
|
1353
|
+
`Refusing commit-time delta comparison.`);
|
|
1354
|
+
}
|
|
1355
|
+
// Relative price threshold = 1/10 of one configured increment step.
|
|
1356
|
+
// Example: incrementPercent=0.5 -> relative tolerance ratio=0.0005 (0.05%).
|
|
1357
|
+
const priceRelativeTolerance = incrementPercent / 1000;
|
|
1358
|
+
return {
|
|
1359
|
+
buyPrecision,
|
|
1360
|
+
sellPrecision,
|
|
1361
|
+
priceRelativeTolerance
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
_buildStateUpdates(actions, masterGrid) {
|
|
1365
|
+
return buildStateUpdates(actions, masterGrid);
|
|
1366
|
+
}
|
|
1367
|
+
_buildAbortedCOWResult(reason) {
|
|
1368
|
+
return buildAbortedResult(reason);
|
|
1369
|
+
}
|
|
1370
|
+
async _commitWorkingGrid(workingGrid, workingIndexes, workingBoundary, options = {}) {
|
|
1371
|
+
const { skipRecalc } = this._normalizeCommitOptions(options);
|
|
1372
|
+
const startTime = Date.now();
|
|
1373
|
+
const stats = workingGrid.getMemoryStats();
|
|
1374
|
+
let committed = false;
|
|
1375
|
+
let comparePrecisions;
|
|
1376
|
+
try {
|
|
1377
|
+
comparePrecisions = this._getCowComparePrecisions();
|
|
1378
|
+
}
|
|
1379
|
+
catch (precisionErr) {
|
|
1380
|
+
this.logger.log(`[COW] ${precisionErr.message}`, 'error');
|
|
1381
|
+
this._clearWorkingGridRef();
|
|
1382
|
+
return false;
|
|
1383
|
+
}
|
|
1384
|
+
const preCommitGuard = evaluateCommit(workingGrid, {
|
|
1385
|
+
hasLock: false,
|
|
1386
|
+
currentVersion: this._gridVersion,
|
|
1387
|
+
masterGrid: this.orders,
|
|
1388
|
+
comparePrecisions
|
|
1389
|
+
});
|
|
1390
|
+
if (!preCommitGuard.canCommit) {
|
|
1391
|
+
this.logger.log(`[COW] ${preCommitGuard.reason}`, preCommitGuard.level || 'warn');
|
|
1392
|
+
this._clearWorkingGridRef();
|
|
1393
|
+
return false;
|
|
1394
|
+
}
|
|
1395
|
+
await this._gridLock.acquire(async () => {
|
|
1396
|
+
const lockCommitGuard = evaluateCommit(workingGrid, {
|
|
1397
|
+
hasLock: true,
|
|
1398
|
+
currentVersion: this._gridVersion,
|
|
1399
|
+
masterGrid: this.orders,
|
|
1400
|
+
comparePrecisions
|
|
1401
|
+
});
|
|
1402
|
+
if (!lockCommitGuard.canCommit) {
|
|
1403
|
+
this.logger.log(`[COW] ${lockCommitGuard.reason}`, lockCommitGuard.level || 'warn');
|
|
1404
|
+
this._clearWorkingGridRef();
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
this.logger.log(`[COW] Committing working grid: ${stats.size} orders, ${stats.modified} modified`, 'debug');
|
|
1408
|
+
const finalMap = workingGrid.toMap();
|
|
1409
|
+
// RC-4: Deep-freeze all modified orders before committing to master state
|
|
1410
|
+
// Ensures COW immutability invariants are maintained for all grid entries.
|
|
1411
|
+
for (const [id, order] of finalMap.entries()) {
|
|
1412
|
+
if (order && !Object.isFrozen(order)) {
|
|
1413
|
+
deepFreeze(order);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
this.orders = Object.freeze(finalMap);
|
|
1417
|
+
this.boundaryIdx = workingBoundary;
|
|
1418
|
+
this._gridVersion++;
|
|
1419
|
+
committed = true;
|
|
1420
|
+
const freshIndexes = workingGrid.getIndexes();
|
|
1421
|
+
this._ordersByState = {
|
|
1422
|
+
[ORDER_STATES.VIRTUAL]: freshIndexes[ORDER_STATES.VIRTUAL] || new Set(),
|
|
1423
|
+
[ORDER_STATES.ACTIVE]: freshIndexes[ORDER_STATES.ACTIVE] || new Set(),
|
|
1424
|
+
[ORDER_STATES.PARTIAL]: freshIndexes[ORDER_STATES.PARTIAL] || new Set()
|
|
1425
|
+
};
|
|
1426
|
+
this._ordersByType = {
|
|
1427
|
+
[ORDER_TYPES.BUY]: freshIndexes[ORDER_TYPES.BUY] || new Set(),
|
|
1428
|
+
[ORDER_TYPES.SELL]: freshIndexes[ORDER_TYPES.SELL] || new Set(),
|
|
1429
|
+
[ORDER_TYPES.SPREAD]: freshIndexes[ORDER_TYPES.SPREAD] || new Set()
|
|
1430
|
+
};
|
|
1431
|
+
});
|
|
1432
|
+
if (!committed) {
|
|
1433
|
+
this._clearWorkingGridRef();
|
|
1434
|
+
return false;
|
|
1435
|
+
}
|
|
1436
|
+
try {
|
|
1437
|
+
if (!skipRecalc) {
|
|
1438
|
+
await this.recalculateFunds();
|
|
1439
|
+
}
|
|
1440
|
+
const duration = Date.now() - startTime;
|
|
1441
|
+
this.logger.log(`[COW] Grid committed in ${duration}ms`, 'debug');
|
|
1442
|
+
if (stats.size > COW_PERFORMANCE.GRID_MEMORY_WARNING) {
|
|
1443
|
+
this.logger.log(`[COW] Warning: Large grid size (${stats.size} orders). Peak memory: ~${Math.round(stats.estimatedBytes / 1024)}KB`, 'warn');
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
catch (recalcErr) {
|
|
1447
|
+
this.logger.log(`[COW] Fund recalculation failed post-commit: ${recalcErr.message}`, 'error');
|
|
1448
|
+
this._recoveryState = this._recoveryState || {};
|
|
1449
|
+
this._recoveryState.lastFailureAt = Date.now();
|
|
1450
|
+
}
|
|
1451
|
+
finally {
|
|
1452
|
+
this._clearWorkingGridRef();
|
|
1453
|
+
}
|
|
1454
|
+
return true;
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* @param {Object} [options]
|
|
1458
|
+
* @param {boolean} [options.allowBootstrapTransient]
|
|
1459
|
+
* @returns {import('./types').PersistenceValidationResult}
|
|
1460
|
+
*/
|
|
1461
|
+
validateGridStateForPersistence(options = {}) {
|
|
1462
|
+
const result = validateGridForPersistence(this.orders, this.accountTotals);
|
|
1463
|
+
const allowBootstrapTransient = options.allowBootstrapTransient !== false;
|
|
1464
|
+
if (!result.isValid && allowBootstrapTransient && this._state.isBootstrapping()) {
|
|
1465
|
+
this.logger.log(`[BOOTSTRAP] Transient state (expected): ${result.reason}`, 'debug');
|
|
1466
|
+
return { isValid: true, reason: null };
|
|
1467
|
+
}
|
|
1468
|
+
return result;
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* @param {string} [reason]
|
|
1472
|
+
* @returns {void}
|
|
1473
|
+
*/
|
|
1474
|
+
suspendGridPersistence(reason = 'suspended') {
|
|
1475
|
+
this._gridPersistenceSuspendedReason = reason;
|
|
1476
|
+
}
|
|
1477
|
+
/**
|
|
1478
|
+
* @param {string} [reason]
|
|
1479
|
+
* @returns {void}
|
|
1480
|
+
*/
|
|
1481
|
+
resumeGridPersistence(reason = null) {
|
|
1482
|
+
if (!this._gridPersistenceSuspendedReason)
|
|
1483
|
+
return;
|
|
1484
|
+
this.logger.log(`[PERSISTENCE-GATE] Resuming grid persistence${reason ? ` (${reason})` : ''}`, 'info');
|
|
1485
|
+
this._gridPersistenceSuspendedReason = null;
|
|
1486
|
+
}
|
|
1487
|
+
/**
|
|
1488
|
+
* @param {Array<Object>} [snapshotOrders] - Optional explicit orders to persist.
|
|
1489
|
+
* When provided, this list is persisted as-is and the live `manager.orders`
|
|
1490
|
+
* map is not touched. This is the only race-free way to persist a freshly
|
|
1491
|
+
* built grid (e.g. from the startup `storeGrid` callback) without briefly
|
|
1492
|
+
* swapping the live map and exposing it to concurrent readers.
|
|
1493
|
+
* @returns {Promise<import('./types').PersistenceValidationResult>}
|
|
1494
|
+
*/
|
|
1495
|
+
async persistGrid(snapshotOrders) {
|
|
1496
|
+
if (this._gridPersistenceSuspendedReason) {
|
|
1497
|
+
this.logger.log(`[PERSISTENCE-GATE] Skipping grid persistence while suspended: ${this._gridPersistenceSuspendedReason}`, 'warn');
|
|
1498
|
+
return { isValid: true, skipped: true, suspended: true, reason: this._gridPersistenceSuspendedReason };
|
|
1499
|
+
}
|
|
1500
|
+
const validation = this.validateGridStateForPersistence();
|
|
1501
|
+
if (!validation.isValid) {
|
|
1502
|
+
this.logger.log(`[PERSISTENCE-GATE] Skipping persistence of corrupted state: ${validation.reason}`, 'warn');
|
|
1503
|
+
return validation;
|
|
1504
|
+
}
|
|
1505
|
+
await persistGridSnapshot(this, this.accountOrders, snapshotOrders);
|
|
1506
|
+
// On a successful live-grid persist (the default — no explicit
|
|
1507
|
+
// snapshotOrders was passed in), clear the dirty flag so that
|
|
1508
|
+
// a subsequent end-of-tick flushGridDirty() call sees the grid
|
|
1509
|
+
// as clean and skips the second snapshot write. When the caller
|
|
1510
|
+
// passes an explicit snapshotOrders (e.g. from the startup
|
|
1511
|
+
// storeGrid callback), the dirty flag is for the LIVE grid, not
|
|
1512
|
+
// the supplied snapshot, so we leave it alone.
|
|
1513
|
+
if (snapshotOrders === undefined && this._gridDirty) {
|
|
1514
|
+
this._clearGridDirty();
|
|
1515
|
+
}
|
|
1516
|
+
return validation;
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* @returns {import('./types').Metrics}
|
|
1520
|
+
*/
|
|
1521
|
+
getMetrics() {
|
|
1522
|
+
return {
|
|
1523
|
+
...this._metrics,
|
|
1524
|
+
state: this._state.getState(),
|
|
1525
|
+
currentTime: Date.now()
|
|
1526
|
+
};
|
|
1527
|
+
}
|
|
1528
|
+
_projectTargetToWorkingGrid(workingGrid, targetGrid) {
|
|
1529
|
+
return projectTargetToWorkingGrid(workingGrid, targetGrid);
|
|
1530
|
+
}
|
|
1531
|
+
_summarizeCowActions(actions) {
|
|
1532
|
+
return summarizeActions(actions);
|
|
1533
|
+
}
|
|
1534
|
+
_evaluateWorkingGridCommit(workingGrid, hasLock = false) {
|
|
1535
|
+
let comparePrecisions;
|
|
1536
|
+
try {
|
|
1537
|
+
comparePrecisions = this._getCowComparePrecisions();
|
|
1538
|
+
}
|
|
1539
|
+
catch (precisionErr) {
|
|
1540
|
+
return {
|
|
1541
|
+
canCommit: false,
|
|
1542
|
+
reason: precisionErr.message,
|
|
1543
|
+
level: 'error'
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
return evaluateCommit(workingGrid, {
|
|
1547
|
+
hasLock,
|
|
1548
|
+
currentVersion: this._gridVersion,
|
|
1549
|
+
masterGrid: this.orders,
|
|
1550
|
+
comparePrecisions
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
get _rebalanceState() {
|
|
1554
|
+
return this._state.getRebalanceState();
|
|
1555
|
+
}
|
|
1556
|
+
set _rebalanceState(value) {
|
|
1557
|
+
this._state.setRebalanceState(value);
|
|
1558
|
+
}
|
|
1559
|
+
get _lastIllegalState() {
|
|
1560
|
+
return this._state.signals?.lastIllegalState || null;
|
|
1561
|
+
}
|
|
1562
|
+
set _lastIllegalState(value) {
|
|
1563
|
+
if (value) {
|
|
1564
|
+
this._state.setIllegalStateSignal(value);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
get _lastAccountingFailure() {
|
|
1568
|
+
return this._state.signals?.lastAccountingFailure || null;
|
|
1569
|
+
}
|
|
1570
|
+
set _lastAccountingFailure(value) {
|
|
1571
|
+
if (value) {
|
|
1572
|
+
this._state.setAccountingFailureSignal(value);
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
get _recoveryState() {
|
|
1576
|
+
return this._state.recovery;
|
|
1577
|
+
}
|
|
1578
|
+
set _recoveryState(value) {
|
|
1579
|
+
const fallback = {
|
|
1580
|
+
attemptCount: 0,
|
|
1581
|
+
lastAttemptAt: 0,
|
|
1582
|
+
inFlight: false,
|
|
1583
|
+
lastFailureAt: 0,
|
|
1584
|
+
structuralResyncRequested: false
|
|
1585
|
+
};
|
|
1586
|
+
this._state.recovery = {
|
|
1587
|
+
...fallback,
|
|
1588
|
+
...(value && typeof value === 'object' ? value : {})
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
get _gridRegenState() {
|
|
1592
|
+
return this._state.gridRegen;
|
|
1593
|
+
}
|
|
1594
|
+
set _gridRegenState(value) {
|
|
1595
|
+
if (!value || typeof value !== 'object')
|
|
1596
|
+
return;
|
|
1597
|
+
const defaultSide = { armed: true, lastTriggeredAt: 0 };
|
|
1598
|
+
this._state.gridRegen = {
|
|
1599
|
+
buy: { ...defaultSide, ...(value.buy || {}) },
|
|
1600
|
+
sell: { ...defaultSide, ...(value.sell || {}) }
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
module.exports = { OrderManager };
|
|
1605
|
+
//# sourceMappingURL=manager.js.map
|