dexbot 1.4.20 → 1.4.22

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.
Files changed (674) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +23 -13
  3. package/analysis/ama_fitting/analyze_ama_price_changes.ts +7 -3
  4. package/analysis/ama_fitting/analyze_lambda_vs_slow.ts +3 -3
  5. package/analysis/ama_fitting/calibrate_convergence_er.ts +8 -6
  6. package/analysis/ama_fitting/fetch_lp_candles.ts +8 -3
  7. package/analysis/ama_fitting/generate_unified_comparison_chart.ts +30 -67
  8. package/analysis/ama_fitting/optimizer_high_resolution.ts +22 -13
  9. package/analysis/ama_fitting/package.json +1 -1
  10. package/analysis/analyze_derivatives.ts +4 -4
  11. package/analysis/analyze_dynamic_weight.ts +21 -5
  12. package/analysis/analyze_kalman.ts +54 -25
  13. package/analysis/analyze_regime.ts +2 -2
  14. package/analysis/analyze_regime_windows.ts +27 -19
  15. package/analysis/analyze_risk_profile.ts +3 -3
  16. package/analysis/analyze_trade_heatmap.ts +3 -3
  17. package/analysis/analyze_volatility.ts +2 -2
  18. package/analysis/bot_fitting/README.md +93 -19
  19. package/analysis/bot_fitting/backtest_ama_sweep.ts +316 -199
  20. package/analysis/bot_fitting/backtest_bot_fitting.ts +520 -85
  21. package/analysis/bot_fitting/shared_utils.ts +16 -10
  22. package/analysis/bot_key_utils.ts +14 -11
  23. package/analysis/bot_usage/discover_bot_accounts.ts +5 -3
  24. package/analysis/bot_usage/kibana_bot_queries.ts +2 -257
  25. package/analysis/chart_css.ts +6 -4
  26. package/analysis/chart_ui.ts +0 -1
  27. package/analysis/chart_utils.ts +11 -2
  28. package/analysis/derivative_chart_generator.ts +2 -2
  29. package/analysis/math_utils.ts +1 -8
  30. package/analysis/price_sources.ts +8 -2
  31. package/analysis/resolve_source.ts +1 -1
  32. package/analysis/results/ama_sweep_results_lp_pool_133_1h.json +2455 -0
  33. package/analysis/results/bot_fitting_results_lp_pool_133_1h.json +218 -0
  34. package/analysis/trade_profitability.ts +61 -28
  35. package/analysis/tradingview/analyze_tradingview.ts +1 -1
  36. package/analysis/tradingview/h-bts_tradingview.html +1570 -0
  37. package/analysis/tradingview/t-bts_tradingview.html +1570 -0
  38. package/analysis/tradingview/tradingview_uplot_chart_generator.ts +302 -74
  39. package/analysis/trend_detection/DYNAMIC_WEIGHT_RESEARCH.md +1 -1
  40. package/analysis/trend_detection/derivative_analyzer.ts +12 -3
  41. package/analysis/trend_detection/dynamic_weight_chart_generator.ts +25 -27
  42. package/analysis/trend_detection/hurst_analyzer.ts +1 -1
  43. package/analysis/trend_detection/kalman_chart_generator.ts +42 -14
  44. package/analysis/trend_detection/package.json +1 -1
  45. package/analysis/trend_detection/regime_chart_generator.ts +39 -19
  46. package/analysis/trend_detection/tests/test_kalman_trend.ts +1 -1
  47. package/analysis/trend_detection/tests/test_kalman_velocity_smoothing.ts +1 -1
  48. package/analysis/trend_detection/volatility_chart_generator.ts +1 -1
  49. package/claw/ecosystem.config.cjs +2 -3
  50. package/claw/examples/memu_integration_example.ts +17 -17
  51. package/claw/index.ts +1 -1
  52. package/claw/modules/chain_actions.ts +51 -54
  53. package/claw/modules/chain_broadcast.ts +66 -104
  54. package/claw/modules/claw_bridge.ts +63 -83
  55. package/claw/modules/claw_catalog.ts +48 -17
  56. package/claw/modules/claw_infra.ts +1 -5
  57. package/claw/modules/claw_launcher.ts +48 -50
  58. package/claw/modules/claw_skill_md.ts +15 -21
  59. package/claw/modules/credit_runtime_adapter.ts +3 -19
  60. package/claw/modules/decision_loop.ts +9 -9
  61. package/claw/modules/dexbot_bridge.ts +8 -8
  62. package/claw/modules/dexbot_profiles.ts +5 -21
  63. package/claw/modules/feed_price_source.ts +1 -1
  64. package/claw/modules/honest_ecosystem.ts +24 -8
  65. package/claw/modules/kibana_price_source.ts +1 -1
  66. package/claw/modules/launcher_mode_detector.ts +1 -1
  67. package/claw/modules/launcher_paths.ts +1 -1
  68. package/claw/modules/liquidity_pools.ts +10 -3
  69. package/claw/modules/mcp_utils.ts +109 -0
  70. package/claw/modules/memu_bridge.ts +76 -54
  71. package/claw/modules/mpa_utils.ts +26 -3
  72. package/claw/modules/position_discovery.ts +17 -28
  73. package/claw/modules/position_health.ts +1 -1
  74. package/claw/modules/position_manager.ts +32 -41
  75. package/claw/modules/position_manager_watch.ts +3 -2
  76. package/claw/modules/short_mpa_strategy.ts +1 -9
  77. package/claw/modules/skill_utils.ts +5 -3
  78. package/claw/modules/utils.ts +9 -1
  79. package/claw/package.json +3 -3
  80. package/claw/runtimes/openclaw-plugin/index.ts +27 -10
  81. package/claw/runtimes/openclaw-plugin/openclaw.plugin.json +1 -1
  82. package/claw/runtimes/openclaw-plugin/package.json +1 -1
  83. package/claw/scripts/claw_bridge.ts +1 -1
  84. package/claw/scripts/claw_mcp_server.ts +19 -78
  85. package/claw/scripts/honest_assets_report.ts +19 -84
  86. package/claw/scripts/memu_mcp_server.ts +57 -155
  87. package/claw/skills/launcher-ops/references/launcher-workflow.md +2 -2
  88. package/claw/tests/package.json +1 -1
  89. package/claw/tests/test_claw_bridge.ts +47 -19
  90. package/claw/tests/test_claw_catalog_and_credentials.ts +8 -4
  91. package/claw/tests/test_claw_chain_layer.ts +39 -19
  92. package/claw/tests/test_claw_data_flow.ts +28 -20
  93. package/claw/tests/test_claw_domain_logic.ts +25 -19
  94. package/claw/tests/test_claw_manifest_and_matrix.ts +23 -3
  95. package/claw/tests/test_claw_mcp_transport.ts +13 -8
  96. package/claw/tests/test_claw_regressions.ts +254 -128
  97. package/claw/tests/test_claw_skill_generation.ts +1 -1
  98. package/claw/tests/test_nullclaw_tmp_integration.ts +2 -3
  99. package/claw/tests/test_position_health.ts +1 -77
  100. package/claw/tests/test_position_manager.ts +20 -18
  101. package/claw/tests/test_position_manager_watch_health.ts +39 -43
  102. package/claw/tests/test_short_mpa_strategy.ts +20 -17
  103. package/claw/tsconfig.json +4 -3
  104. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js +7 -3
  105. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js.map +1 -1
  106. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js +3 -3
  107. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js.map +1 -1
  108. package/dist/analysis/ama_fitting/calibrate_convergence_er.js +8 -6
  109. package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +1 -1
  110. package/dist/analysis/ama_fitting/fetch_lp_candles.js +8 -3
  111. package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +1 -1
  112. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts +2 -2
  113. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts.map +1 -1
  114. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js +31 -75
  115. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js.map +1 -1
  116. package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts.map +1 -1
  117. package/dist/analysis/ama_fitting/optimizer_high_resolution.js +21 -13
  118. package/dist/analysis/ama_fitting/optimizer_high_resolution.js.map +1 -1
  119. package/dist/analysis/analyze_derivatives.d.ts +0 -18
  120. package/dist/analysis/analyze_derivatives.d.ts.map +1 -1
  121. package/dist/analysis/analyze_derivatives.js +4 -4
  122. package/dist/analysis/analyze_derivatives.js.map +1 -1
  123. package/dist/analysis/analyze_dynamic_weight.d.ts +0 -11
  124. package/dist/analysis/analyze_dynamic_weight.d.ts.map +1 -1
  125. package/dist/analysis/analyze_dynamic_weight.js +19 -5
  126. package/dist/analysis/analyze_dynamic_weight.js.map +1 -1
  127. package/dist/analysis/analyze_kalman.d.ts +0 -10
  128. package/dist/analysis/analyze_kalman.d.ts.map +1 -1
  129. package/dist/analysis/analyze_kalman.js +51 -26
  130. package/dist/analysis/analyze_kalman.js.map +1 -1
  131. package/dist/analysis/analyze_regime.d.ts +0 -17
  132. package/dist/analysis/analyze_regime.d.ts.map +1 -1
  133. package/dist/analysis/analyze_regime.js +2 -2
  134. package/dist/analysis/analyze_regime.js.map +1 -1
  135. package/dist/analysis/analyze_regime_windows.d.ts +0 -16
  136. package/dist/analysis/analyze_regime_windows.d.ts.map +1 -1
  137. package/dist/analysis/analyze_regime_windows.js +28 -21
  138. package/dist/analysis/analyze_regime_windows.js.map +1 -1
  139. package/dist/analysis/analyze_risk_profile.js +3 -3
  140. package/dist/analysis/analyze_risk_profile.js.map +1 -1
  141. package/dist/analysis/analyze_trade_heatmap.js +3 -3
  142. package/dist/analysis/analyze_trade_heatmap.js.map +1 -1
  143. package/dist/analysis/analyze_volatility.d.ts +0 -19
  144. package/dist/analysis/analyze_volatility.d.ts.map +1 -1
  145. package/dist/analysis/analyze_volatility.js +2 -2
  146. package/dist/analysis/analyze_volatility.js.map +1 -1
  147. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts +30 -14
  148. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts.map +1 -1
  149. package/dist/analysis/bot_fitting/backtest_ama_sweep.js +330 -193
  150. package/dist/analysis/bot_fitting/backtest_ama_sweep.js.map +1 -1
  151. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts +136 -1
  152. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts.map +1 -1
  153. package/dist/analysis/bot_fitting/backtest_bot_fitting.js +527 -83
  154. package/dist/analysis/bot_fitting/backtest_bot_fitting.js.map +1 -1
  155. package/dist/analysis/bot_fitting/shared_utils.d.ts +2 -13
  156. package/dist/analysis/bot_fitting/shared_utils.d.ts.map +1 -1
  157. package/dist/analysis/bot_fitting/shared_utils.js +15 -9
  158. package/dist/analysis/bot_fitting/shared_utils.js.map +1 -1
  159. package/dist/analysis/bot_key_utils.d.ts +1 -1
  160. package/dist/analysis/bot_key_utils.d.ts.map +1 -1
  161. package/dist/analysis/bot_key_utils.js +14 -11
  162. package/dist/analysis/bot_key_utils.js.map +1 -1
  163. package/dist/analysis/bot_usage/discover_bot_accounts.js +5 -3
  164. package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -1
  165. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +1 -337
  166. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -1
  167. package/dist/analysis/bot_usage/kibana_bot_queries.js +2 -242
  168. package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -1
  169. package/dist/analysis/chart_css.d.ts +2 -14
  170. package/dist/analysis/chart_css.d.ts.map +1 -1
  171. package/dist/analysis/chart_css.js +6 -3
  172. package/dist/analysis/chart_css.js.map +1 -1
  173. package/dist/analysis/chart_ui.d.ts.map +1 -1
  174. package/dist/analysis/chart_ui.js.map +1 -1
  175. package/dist/analysis/chart_utils.d.ts.map +1 -1
  176. package/dist/analysis/chart_utils.js +15 -2
  177. package/dist/analysis/chart_utils.js.map +1 -1
  178. package/dist/analysis/derivative_chart_generator.js +2 -2
  179. package/dist/analysis/derivative_chart_generator.js.map +1 -1
  180. package/dist/analysis/math_utils.d.ts +3 -5
  181. package/dist/analysis/math_utils.d.ts.map +1 -1
  182. package/dist/analysis/math_utils.js +3 -5
  183. package/dist/analysis/math_utils.js.map +1 -1
  184. package/dist/analysis/price_sources.d.ts +1 -0
  185. package/dist/analysis/price_sources.d.ts.map +1 -1
  186. package/dist/analysis/price_sources.js +8 -2
  187. package/dist/analysis/price_sources.js.map +1 -1
  188. package/dist/analysis/resolve_source.d.ts.map +1 -1
  189. package/dist/analysis/resolve_source.js +1 -1
  190. package/dist/analysis/resolve_source.js.map +1 -1
  191. package/dist/analysis/trade_profitability.d.ts.map +1 -1
  192. package/dist/analysis/trade_profitability.js +58 -29
  193. package/dist/analysis/trade_profitability.js.map +1 -1
  194. package/dist/analysis/tradingview/analyze_tradingview.js +1 -1
  195. package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -1
  196. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -1
  197. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +302 -74
  198. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -1
  199. package/dist/analysis/trend_detection/derivative_analyzer.d.ts +1 -0
  200. package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +1 -1
  201. package/dist/analysis/trend_detection/derivative_analyzer.js +12 -3
  202. package/dist/analysis/trend_detection/derivative_analyzer.js.map +1 -1
  203. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +1 -1
  204. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +26 -27
  205. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +1 -1
  206. package/dist/analysis/trend_detection/hurst_analyzer.d.ts +1 -1
  207. package/dist/analysis/trend_detection/hurst_analyzer.d.ts.map +1 -1
  208. package/dist/analysis/trend_detection/hurst_analyzer.js +1 -1
  209. package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -1
  210. package/dist/analysis/trend_detection/kalman_chart_generator.d.ts.map +1 -1
  211. package/dist/analysis/trend_detection/kalman_chart_generator.js +41 -13
  212. package/dist/analysis/trend_detection/kalman_chart_generator.js.map +1 -1
  213. package/dist/analysis/trend_detection/regime_chart_generator.d.ts.map +1 -1
  214. package/dist/analysis/trend_detection/regime_chart_generator.js +38 -19
  215. package/dist/analysis/trend_detection/regime_chart_generator.js.map +1 -1
  216. package/dist/analysis/trend_detection/tests/test_kalman_trend.js +1 -1
  217. package/dist/analysis/trend_detection/tests/test_kalman_trend.js.map +1 -1
  218. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js +1 -1
  219. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js.map +1 -1
  220. package/dist/analysis/trend_detection/volatility_chart_generator.js +1 -1
  221. package/dist/analysis/trend_detection/volatility_chart_generator.js.map +1 -1
  222. package/dist/bot.js +3 -3
  223. package/dist/bot.js.map +1 -1
  224. package/dist/credential-daemon.d.ts +1 -1
  225. package/dist/credential-daemon.js +2 -2
  226. package/dist/credential-daemon.js.map +1 -1
  227. package/dist/dexbot.d.ts.map +1 -1
  228. package/dist/dexbot.js +25 -22
  229. package/dist/dexbot.js.map +1 -1
  230. package/dist/market_adapter/ama_signal_runner.js +6 -4
  231. package/dist/market_adapter/ama_signal_runner.js.map +1 -1
  232. package/dist/market_adapter/candle_utils.d.ts +1 -3
  233. package/dist/market_adapter/candle_utils.d.ts.map +1 -1
  234. package/dist/market_adapter/candle_utils.js +1 -11
  235. package/dist/market_adapter/candle_utils.js.map +1 -1
  236. package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -1
  237. package/dist/market_adapter/core/asymmetric_bounds.js +33 -30
  238. package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -1
  239. package/dist/market_adapter/core/config_normalizers.d.ts.map +1 -1
  240. package/dist/market_adapter/core/config_normalizers.js +10 -1
  241. package/dist/market_adapter/core/config_normalizers.js.map +1 -1
  242. package/dist/market_adapter/core/kibana_candles.d.ts +18 -42
  243. package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -1
  244. package/dist/market_adapter/core/kibana_candles.js +101 -7
  245. package/dist/market_adapter/core/kibana_candles.js.map +1 -1
  246. package/dist/market_adapter/core/kibana_client.d.ts +1 -17
  247. package/dist/market_adapter/core/kibana_client.d.ts.map +1 -1
  248. package/dist/market_adapter/core/kibana_client.js +40 -7
  249. package/dist/market_adapter/core/kibana_client.js.map +1 -1
  250. package/dist/market_adapter/core/kibana_market_candles.d.ts +0 -27
  251. package/dist/market_adapter/core/kibana_market_candles.d.ts.map +1 -1
  252. package/dist/market_adapter/core/kibana_market_candles.js +1 -1
  253. package/dist/market_adapter/core/kibana_market_candles.js.map +1 -1
  254. package/dist/market_adapter/core/market_adapter_service.d.ts +22 -13
  255. package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -1
  256. package/dist/market_adapter/core/market_adapter_service.js +96 -38
  257. package/dist/market_adapter/core/market_adapter_service.js.map +1 -1
  258. package/dist/market_adapter/core/signals/hurst_analyzer.d.ts +10 -1
  259. package/dist/market_adapter/core/signals/hurst_analyzer.d.ts.map +1 -1
  260. package/dist/market_adapter/core/signals/hurst_analyzer.js +28 -17
  261. package/dist/market_adapter/core/signals/hurst_analyzer.js.map +1 -1
  262. package/dist/market_adapter/core/signals/kalman_trend_analyzer.d.ts +5 -0
  263. package/dist/market_adapter/core/signals/kalman_trend_analyzer.d.ts.map +1 -1
  264. package/dist/market_adapter/core/signals/kalman_trend_analyzer.js +24 -24
  265. package/dist/market_adapter/core/signals/kalman_trend_analyzer.js.map +1 -1
  266. package/dist/market_adapter/core/signals/kalman_velocity_smoothing.d.ts.map +1 -1
  267. package/dist/market_adapter/core/signals/kalman_velocity_smoothing.js +5 -1
  268. package/dist/market_adapter/core/signals/kalman_velocity_smoothing.js.map +1 -1
  269. package/dist/market_adapter/core/signals/permutation_entropy_analyzer.d.ts.map +1 -1
  270. package/dist/market_adapter/core/signals/permutation_entropy_analyzer.js +20 -3
  271. package/dist/market_adapter/core/signals/permutation_entropy_analyzer.js.map +1 -1
  272. package/dist/market_adapter/core/strategies/ama.js +1 -1
  273. package/dist/market_adapter/core/strategies/ama.js.map +1 -1
  274. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts +2 -2
  275. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts.map +1 -1
  276. package/dist/market_adapter/core/strategies/ama_slope_model.js +16 -4
  277. package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -1
  278. package/dist/market_adapter/core/strategies/atr/calculator.d.ts +4 -3
  279. package/dist/market_adapter/core/strategies/atr/calculator.d.ts.map +1 -1
  280. package/dist/market_adapter/core/strategies/atr/calculator.js +16 -8
  281. package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -1
  282. package/dist/market_adapter/core/strategies/collateral_manager.d.ts.map +1 -1
  283. package/dist/market_adapter/core/strategies/collateral_manager.js +8 -3
  284. package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -1
  285. package/dist/market_adapter/core/strategies/dynamic_weight_series.d.ts +40 -1
  286. package/dist/market_adapter/core/strategies/dynamic_weight_series.d.ts.map +1 -1
  287. package/dist/market_adapter/core/strategies/dynamic_weight_series.js +116 -2
  288. package/dist/market_adapter/core/strategies/dynamic_weight_series.js.map +1 -1
  289. package/dist/market_adapter/core/strategies/regime_gate.d.ts +1 -2
  290. package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -1
  291. package/dist/market_adapter/core/strategies/regime_gate.js +27 -21
  292. package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -1
  293. package/dist/market_adapter/core/strategies/volatility_shift.d.ts.map +1 -1
  294. package/dist/market_adapter/core/strategies/volatility_shift.js +3 -0
  295. package/dist/market_adapter/core/strategies/volatility_shift.js.map +1 -1
  296. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +71 -57
  297. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -1
  298. package/dist/market_adapter/inputs/fetch_lp_data.d.ts +0 -26
  299. package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
  300. package/dist/market_adapter/inputs/fetch_lp_data.js +72 -19
  301. package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
  302. package/dist/market_adapter/inputs/kibana_source.d.ts +5 -30
  303. package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -1
  304. package/dist/market_adapter/inputs/kibana_source.js +6 -3
  305. package/dist/market_adapter/inputs/kibana_source.js.map +1 -1
  306. package/dist/market_adapter/lp_chart_core.js +1 -1
  307. package/dist/market_adapter/lp_chart_core.js.map +1 -1
  308. package/dist/market_adapter/lp_chart_runner.d.ts +10 -1
  309. package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -1
  310. package/dist/market_adapter/lp_chart_runner.js +2 -2
  311. package/dist/market_adapter/lp_chart_runner.js.map +1 -1
  312. package/dist/market_adapter/lp_chart_strategy_loader.d.ts +1 -2
  313. package/dist/market_adapter/lp_chart_strategy_loader.d.ts.map +1 -1
  314. package/dist/market_adapter/lp_chart_strategy_loader.js +5 -5
  315. package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -1
  316. package/dist/market_adapter/market_adapter.d.ts +1 -2
  317. package/dist/market_adapter/market_adapter.d.ts.map +1 -1
  318. package/dist/market_adapter/market_adapter.js +5 -7
  319. package/dist/market_adapter/market_adapter.js.map +1 -1
  320. package/dist/market_adapter/test_helpers.d.ts +3 -3
  321. package/dist/market_adapter/test_helpers.d.ts.map +1 -1
  322. package/dist/market_adapter/test_helpers.js +3 -3
  323. package/dist/market_adapter/test_helpers.js.map +1 -1
  324. package/dist/market_adapter/utils/adapter_client.js +1 -1
  325. package/dist/market_adapter/utils/adapter_client.js.map +1 -1
  326. package/dist/market_adapter/utils/atomic_write.js +1 -1
  327. package/dist/market_adapter/utils/atomic_write.js.map +1 -1
  328. package/dist/market_adapter/utils/chain.d.ts +0 -2
  329. package/dist/market_adapter/utils/chain.d.ts.map +1 -1
  330. package/dist/market_adapter/utils/chain.js +2 -3
  331. package/dist/market_adapter/utils/chain.js.map +1 -1
  332. package/dist/market_adapter/utils/data_discovery.d.ts.map +1 -1
  333. package/dist/market_adapter/utils/data_discovery.js +24 -8
  334. package/dist/market_adapter/utils/data_discovery.js.map +1 -1
  335. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -1
  336. package/dist/market_adapter/utils/dynamic_grid_snapshot.js +2 -5
  337. package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -1
  338. package/dist/market_adapter/utils/file_lock.d.ts +4 -1
  339. package/dist/market_adapter/utils/file_lock.d.ts.map +1 -1
  340. package/dist/market_adapter/utils/file_lock.js +89 -25
  341. package/dist/market_adapter/utils/file_lock.js.map +1 -1
  342. package/dist/market_adapter/utils/native_history.d.ts.map +1 -1
  343. package/dist/market_adapter/utils/native_history.js +5 -1
  344. package/dist/market_adapter/utils/native_history.js.map +1 -1
  345. package/dist/modules/account_bots.d.ts +3 -0
  346. package/dist/modules/account_bots.d.ts.map +1 -1
  347. package/dist/modules/account_bots.js +157 -47
  348. package/dist/modules/account_bots.js.map +1 -1
  349. package/dist/modules/account_orders.d.ts +1 -7
  350. package/dist/modules/account_orders.d.ts.map +1 -1
  351. package/dist/modules/account_orders.js +9 -17
  352. package/dist/modules/account_orders.js.map +1 -1
  353. package/dist/modules/authority_resolver.js +1 -1
  354. package/dist/modules/authority_resolver.js.map +1 -1
  355. package/dist/modules/bitshares-native/chain_client.js +1 -1
  356. package/dist/modules/bitshares-native/chain_client.js.map +1 -1
  357. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts +0 -12
  358. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -1
  359. package/dist/modules/bitshares-native/crypto/ecc.browser.js +1 -1
  360. package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -1
  361. package/dist/modules/bitshares-native/crypto/ecc_selector.js +1 -1
  362. package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -1
  363. package/dist/modules/bitshares-native/index.d.ts.map +1 -1
  364. package/dist/modules/bitshares-native/index.js +1 -1
  365. package/dist/modules/bitshares-native/index.js.map +1 -1
  366. package/dist/modules/bitshares-native/lru_cache.js +1 -1
  367. package/dist/modules/bitshares-native/lru_cache.js.map +1 -1
  368. package/dist/modules/bitshares-native/resolvers.d.ts +0 -2
  369. package/dist/modules/bitshares-native/resolvers.d.ts.map +1 -1
  370. package/dist/modules/bitshares-native/resolvers.js +18 -4
  371. package/dist/modules/bitshares-native/resolvers.js.map +1 -1
  372. package/dist/modules/bitshares-native/serial/chain_constants.js +1 -1
  373. package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -1
  374. package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -1
  375. package/dist/modules/bitshares-native/serial/index.js +1 -1
  376. package/dist/modules/bitshares-native/serial/index.js.map +1 -1
  377. package/dist/modules/bitshares-native/serial/operations.js +1 -1
  378. package/dist/modules/bitshares-native/serial/operations.js.map +1 -1
  379. package/dist/modules/bitshares-native/serial/serializer.js +1 -1
  380. package/dist/modules/bitshares-native/serial/serializer.js.map +1 -1
  381. package/dist/modules/bitshares-native/serial/types.js +1 -1
  382. package/dist/modules/bitshares-native/serial/types.js.map +1 -1
  383. package/dist/modules/bitshares-native/signing_client.js +2 -2
  384. package/dist/modules/bitshares-native/signing_client.js.map +1 -1
  385. package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -1
  386. package/dist/modules/bitshares-native/subscriptions.js +5 -14
  387. package/dist/modules/bitshares-native/subscriptions.js.map +1 -1
  388. package/dist/modules/bitshares-native/transport.js +1 -1
  389. package/dist/modules/bitshares-native/transport.js.map +1 -1
  390. package/dist/modules/bitshares-native/tx/builder.js +1 -1
  391. package/dist/modules/bitshares-native/tx/builder.js.map +1 -1
  392. package/dist/modules/bitshares-native/tx/tx_cache.d.ts +3 -2
  393. package/dist/modules/bitshares-native/tx/tx_cache.d.ts.map +1 -1
  394. package/dist/modules/bitshares-native/tx/tx_cache.js +7 -4
  395. package/dist/modules/bitshares-native/tx/tx_cache.js.map +1 -1
  396. package/dist/modules/bitshares_client.d.ts +2 -14
  397. package/dist/modules/bitshares_client.d.ts.map +1 -1
  398. package/dist/modules/bitshares_client.js +32 -41
  399. package/dist/modules/bitshares_client.js.map +1 -1
  400. package/dist/modules/bot_settings.d.ts.map +1 -1
  401. package/dist/modules/bot_settings.js +12 -19
  402. package/dist/modules/bot_settings.js.map +1 -1
  403. package/dist/modules/bots_file_lock.d.ts +1 -1
  404. package/dist/modules/bots_file_lock.js +1 -1
  405. package/dist/modules/broadcast_failure.d.ts +13 -0
  406. package/dist/modules/broadcast_failure.d.ts.map +1 -1
  407. package/dist/modules/broadcast_failure.js +0 -13
  408. package/dist/modules/broadcast_failure.js.map +1 -1
  409. package/dist/modules/chain_keys.js +2 -2
  410. package/dist/modules/chain_keys.js.map +1 -1
  411. package/dist/modules/chain_orders.d.ts +2 -3
  412. package/dist/modules/chain_orders.d.ts.map +1 -1
  413. package/dist/modules/chain_orders.js +23 -42
  414. package/dist/modules/chain_orders.js.map +1 -1
  415. package/dist/modules/config.d.ts.map +1 -1
  416. package/dist/modules/config.js +5 -2
  417. package/dist/modules/config.js.map +1 -1
  418. package/dist/modules/constants.d.ts +21 -21
  419. package/dist/modules/constants.d.ts.map +1 -1
  420. package/dist/modules/constants.js +53 -60
  421. package/dist/modules/constants.js.map +1 -1
  422. package/dist/modules/cr_planner.d.ts +1 -7
  423. package/dist/modules/cr_planner.d.ts.map +1 -1
  424. package/dist/modules/cr_planner.js +3 -77
  425. package/dist/modules/cr_planner.js.map +1 -1
  426. package/dist/modules/credential_policy.d.ts +0 -4
  427. package/dist/modules/credential_policy.d.ts.map +1 -1
  428. package/dist/modules/credential_policy.js +18 -3
  429. package/dist/modules/credential_policy.js.map +1 -1
  430. package/dist/modules/credit_runtime.d.ts +0 -7
  431. package/dist/modules/credit_runtime.d.ts.map +1 -1
  432. package/dist/modules/credit_runtime.js +21 -60
  433. package/dist/modules/credit_runtime.js.map +1 -1
  434. package/dist/modules/crypto/index.d.ts +0 -2
  435. package/dist/modules/crypto/index.d.ts.map +1 -1
  436. package/dist/modules/crypto/index.js +0 -2
  437. package/dist/modules/crypto/index.js.map +1 -1
  438. package/dist/modules/crypto/sync.js.map +1 -1
  439. package/dist/modules/daemon_node_health.js +1 -1
  440. package/dist/modules/daemon_node_health.js.map +1 -1
  441. package/dist/modules/dexbot_class.d.ts +8 -134
  442. package/dist/modules/dexbot_class.d.ts.map +1 -1
  443. package/dist/modules/dexbot_class.js +39 -199
  444. package/dist/modules/dexbot_class.js.map +1 -1
  445. package/dist/modules/dexbot_credential_client.js +1 -1
  446. package/dist/modules/dexbot_credential_client.js.map +1 -1
  447. package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -1
  448. package/dist/modules/dexbot_fill_runtime.js +3 -6
  449. package/dist/modules/dexbot_fill_runtime.js.map +1 -1
  450. package/dist/modules/dexbot_maintenance_runtime.d.ts +6 -34
  451. package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
  452. package/dist/modules/dexbot_maintenance_runtime.js +27 -19
  453. package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
  454. package/dist/modules/dexbot_startup_runtime.d.ts.map +1 -1
  455. package/dist/modules/dexbot_startup_runtime.js +31 -15
  456. package/dist/modules/dexbot_startup_runtime.js.map +1 -1
  457. package/dist/modules/dexbot_state_recovery.d.ts +2 -2
  458. package/dist/modules/dexbot_state_recovery.d.ts.map +1 -1
  459. package/dist/modules/dexbot_state_recovery.js +11 -7
  460. package/dist/modules/dexbot_state_recovery.js.map +1 -1
  461. package/dist/modules/fund_registry.d.ts.map +1 -1
  462. package/dist/modules/fund_registry.js +24 -6
  463. package/dist/modules/fund_registry.js.map +1 -1
  464. package/dist/modules/general_settings.d.ts +1 -2
  465. package/dist/modules/general_settings.d.ts.map +1 -1
  466. package/dist/modules/general_settings.js +1 -2
  467. package/dist/modules/general_settings.js.map +1 -1
  468. package/dist/modules/graceful_shutdown.d.ts.map +1 -1
  469. package/dist/modules/graceful_shutdown.js +10 -1
  470. package/dist/modules/graceful_shutdown.js.map +1 -1
  471. package/dist/modules/grid_price_source.d.ts +19 -0
  472. package/dist/modules/grid_price_source.d.ts.map +1 -0
  473. package/dist/modules/grid_price_source.js +23 -0
  474. package/dist/modules/grid_price_source.js.map +1 -0
  475. package/dist/modules/key_store.d.ts +0 -5
  476. package/dist/modules/key_store.d.ts.map +1 -1
  477. package/dist/modules/key_store.js +1 -14
  478. package/dist/modules/key_store.js.map +1 -1
  479. package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -1
  480. package/dist/modules/launcher/bot_supervisor.js +15 -26
  481. package/dist/modules/launcher/bot_supervisor.js.map +1 -1
  482. package/dist/modules/launcher/child_env.d.ts +1 -2
  483. package/dist/modules/launcher/child_env.d.ts.map +1 -1
  484. package/dist/modules/launcher/child_env.js +1 -1
  485. package/dist/modules/launcher/child_env.js.map +1 -1
  486. package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -1
  487. package/dist/modules/launcher/foreign_cred_daemon.js +7 -13
  488. package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -1
  489. package/dist/modules/launcher/market_adapter_runtime.d.ts +3 -4
  490. package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -1
  491. package/dist/modules/launcher/market_adapter_runtime.js +10 -29
  492. package/dist/modules/launcher/market_adapter_runtime.js.map +1 -1
  493. package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -1
  494. package/dist/modules/launcher/market_adapter_watchdog.js +3 -2
  495. package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -1
  496. package/dist/modules/launcher/monolithic_runtime.d.ts +0 -1
  497. package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
  498. package/dist/modules/launcher/monolithic_runtime.js +4 -18
  499. package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
  500. package/dist/modules/launcher/runtime_entry.d.ts.map +1 -1
  501. package/dist/modules/launcher/runtime_entry.js +4 -5
  502. package/dist/modules/launcher/runtime_entry.js.map +1 -1
  503. package/dist/modules/launcher/status_reporting.d.ts +1 -2
  504. package/dist/modules/launcher/status_reporting.d.ts.map +1 -1
  505. package/dist/modules/launcher/status_reporting.js +2 -5
  506. package/dist/modules/launcher/status_reporting.js.map +1 -1
  507. package/dist/modules/launcher/supervisor_control.js +1 -1
  508. package/dist/modules/launcher/supervisor_control.js.map +1 -1
  509. package/dist/modules/market_adapter_whitelist.d.ts +2 -2
  510. package/dist/modules/market_adapter_whitelist.d.ts.map +1 -1
  511. package/dist/modules/market_adapter_whitelist.js +12 -6
  512. package/dist/modules/market_adapter_whitelist.js.map +1 -1
  513. package/dist/modules/node_failure_ledger.d.ts +23 -0
  514. package/dist/modules/node_failure_ledger.d.ts.map +1 -1
  515. package/dist/modules/node_failure_ledger.js +0 -23
  516. package/dist/modules/node_failure_ledger.js.map +1 -1
  517. package/dist/modules/node_manager.d.ts.map +1 -1
  518. package/dist/modules/node_manager.js +3 -3
  519. package/dist/modules/node_manager.js.map +1 -1
  520. package/dist/modules/order/accounting.js +3 -3
  521. package/dist/modules/order/accounting.js.map +1 -1
  522. package/dist/modules/order/async_lock.d.ts +6 -0
  523. package/dist/modules/order/async_lock.d.ts.map +1 -1
  524. package/dist/modules/order/async_lock.js +11 -0
  525. package/dist/modules/order/async_lock.js.map +1 -1
  526. package/dist/modules/order/export.d.ts +1 -1
  527. package/dist/modules/order/export.js +10 -10
  528. package/dist/modules/order/export.js.map +1 -1
  529. package/dist/modules/order/format.d.ts +1 -8
  530. package/dist/modules/order/format.d.ts.map +1 -1
  531. package/dist/modules/order/format.js +0 -14
  532. package/dist/modules/order/format.js.map +1 -1
  533. package/dist/modules/order/grid.d.ts +2 -12
  534. package/dist/modules/order/grid.d.ts.map +1 -1
  535. package/dist/modules/order/grid.js +23 -24
  536. package/dist/modules/order/grid.js.map +1 -1
  537. package/dist/modules/order/grid_reconcile.d.ts +1 -1
  538. package/dist/modules/order/grid_reconcile.js +1 -1
  539. package/dist/modules/order/grid_reconcile_internal.js +1 -1
  540. package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
  541. package/dist/modules/order/logger.d.ts +3 -0
  542. package/dist/modules/order/logger.d.ts.map +1 -1
  543. package/dist/modules/order/logger.js +23 -14
  544. package/dist/modules/order/logger.js.map +1 -1
  545. package/dist/modules/order/logger_state.d.ts +5 -22
  546. package/dist/modules/order/logger_state.d.ts.map +1 -1
  547. package/dist/modules/order/logger_state.js +6 -25
  548. package/dist/modules/order/logger_state.js.map +1 -1
  549. package/dist/modules/order/manager.d.ts +1 -4
  550. package/dist/modules/order/manager.d.ts.map +1 -1
  551. package/dist/modules/order/manager.js +34 -33
  552. package/dist/modules/order/manager.js.map +1 -1
  553. package/dist/modules/order/processed_fill_store.d.ts +0 -5
  554. package/dist/modules/order/processed_fill_store.d.ts.map +1 -1
  555. package/dist/modules/order/processed_fill_store.js +10 -15
  556. package/dist/modules/order/processed_fill_store.js.map +1 -1
  557. package/dist/modules/order/strategy.d.ts +6 -4
  558. package/dist/modules/order/strategy.d.ts.map +1 -1
  559. package/dist/modules/order/strategy.js +6 -4
  560. package/dist/modules/order/strategy.js.map +1 -1
  561. package/dist/modules/order/sync_engine.d.ts.map +1 -1
  562. package/dist/modules/order/sync_engine.js +17 -10
  563. package/dist/modules/order/sync_engine.js.map +1 -1
  564. package/dist/modules/order/utils/math.d.ts +7 -1
  565. package/dist/modules/order/utils/math.d.ts.map +1 -1
  566. package/dist/modules/order/utils/math.js +19 -1
  567. package/dist/modules/order/utils/math.js.map +1 -1
  568. package/dist/modules/order/utils/order.d.ts.map +1 -1
  569. package/dist/modules/order/utils/order.js +11 -4
  570. package/dist/modules/order/utils/order.js.map +1 -1
  571. package/dist/modules/order/utils/system.d.ts +3 -8
  572. package/dist/modules/order/utils/system.d.ts.map +1 -1
  573. package/dist/modules/order/utils/system.js +14 -4
  574. package/dist/modules/order/utils/system.js.map +1 -1
  575. package/dist/modules/order/utils/validate.js +1 -1
  576. package/dist/modules/order/utils/validate.js.map +1 -1
  577. package/dist/modules/path_api.js +1 -1
  578. package/dist/modules/path_api.js.map +1 -1
  579. package/dist/modules/paths.d.ts +1 -7
  580. package/dist/modules/paths.d.ts.map +1 -1
  581. package/dist/modules/paths.js +1 -1
  582. package/dist/modules/paths.js.map +1 -1
  583. package/dist/modules/process_discovery.d.ts +3 -0
  584. package/dist/modules/process_discovery.d.ts.map +1 -1
  585. package/dist/modules/process_discovery.js +15 -1
  586. package/dist/modules/process_discovery.js.map +1 -1
  587. package/dist/modules/runtime_settings.js +4 -2
  588. package/dist/modules/runtime_settings.js.map +1 -1
  589. package/dist/modules/settings_merge.d.ts +5 -1
  590. package/dist/modules/settings_merge.d.ts.map +1 -1
  591. package/dist/modules/settings_merge.js +17 -4
  592. package/dist/modules/settings_merge.js.map +1 -1
  593. package/dist/modules/socket_json_client.d.ts.map +1 -1
  594. package/dist/modules/socket_json_client.js +12 -2
  595. package/dist/modules/socket_json_client.js.map +1 -1
  596. package/dist/modules/storage/browser_adapter.d.ts +8 -3
  597. package/dist/modules/storage/browser_adapter.d.ts.map +1 -1
  598. package/dist/modules/storage/browser_adapter.js +58 -7
  599. package/dist/modules/storage/browser_adapter.js.map +1 -1
  600. package/dist/modules/storage/index.d.ts +1 -1
  601. package/dist/modules/storage/index.js +1 -1
  602. package/dist/modules/types.d.ts +1 -1
  603. package/dist/modules/types.d.ts.map +1 -1
  604. package/dist/modules/utils/sanitize_key.d.ts +7 -0
  605. package/dist/modules/utils/sanitize_key.d.ts.map +1 -0
  606. package/dist/modules/utils/sanitize_key.js +15 -0
  607. package/dist/modules/utils/sanitize_key.js.map +1 -0
  608. package/dist/modules/validate_profiles.d.ts.map +1 -1
  609. package/dist/modules/validate_profiles.js +6 -8
  610. package/dist/modules/validate_profiles.js.map +1 -1
  611. package/dist/pm2.d.ts.map +1 -1
  612. package/dist/pm2.js +8 -9
  613. package/dist/pm2.js.map +1 -1
  614. package/dist/scripts/analyze-git.d.ts +1 -1
  615. package/dist/scripts/analyze-git.js +1 -1
  616. package/dist/scripts/analyze-orders.d.ts +2 -2
  617. package/dist/scripts/analyze-orders.d.ts.map +1 -1
  618. package/dist/scripts/analyze-orders.js +39 -28
  619. package/dist/scripts/analyze-orders.js.map +1 -1
  620. package/dist/scripts/diagnose-pool-history.js +1 -1
  621. package/dist/scripts/divergence-calc.d.ts +1 -1
  622. package/dist/scripts/divergence-calc.js +3 -3
  623. package/dist/scripts/native_release_gates.js +4 -2
  624. package/dist/scripts/native_release_gates.js.map +1 -1
  625. package/dist/scripts/print_grid.d.ts +1 -1
  626. package/dist/scripts/print_grid.js +1 -1
  627. package/dist/scripts/run-tests.js +38 -19
  628. package/dist/scripts/run-tests.js.map +1 -1
  629. package/dist/scripts/runner.d.ts +3 -5
  630. package/dist/scripts/runner.d.ts.map +1 -1
  631. package/dist/scripts/runner.js +4 -6
  632. package/dist/scripts/runner.js.map +1 -1
  633. package/dist/scripts/sync-version.d.ts +2 -2
  634. package/dist/scripts/sync-version.js +2 -2
  635. package/dist/scripts/update.d.ts +1 -1
  636. package/dist/scripts/update.js +2 -2
  637. package/dist/scripts/update.js.map +1 -1
  638. package/dist/scripts/validate_bots.d.ts +1 -1
  639. package/dist/scripts/validate_bots.js +1 -1
  640. package/dist/scripts/verify-browser-bundle.d.ts +1 -1
  641. package/dist/scripts/verify-browser-bundle.js +1 -1
  642. package/dist/unlock.js +4 -4
  643. package/dist/unlock.js.map +1 -1
  644. package/docs/BITSHARES_ONBOARDING.md +63 -18
  645. package/docs/COPY_ON_WRITE_MASTER_PLAN.md +14 -23
  646. package/docs/COW_INVARIANTS.md +4 -4
  647. package/docs/CREDENTIAL_SECURITY.md +0 -11
  648. package/docs/DEXBOT_COMPARISON.md +12 -12
  649. package/docs/EVOLUTION.md +17 -43
  650. package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +27 -83
  651. package/docs/GRID_RECALCULATION.md +1 -13
  652. package/docs/GRID_RECONCILE.md +24 -24
  653. package/docs/LIFECYCLE.md +4 -4
  654. package/docs/LOGGING.md +1 -1
  655. package/docs/MPA_CREDIT_USAGE.md +3 -3
  656. package/docs/README.md +2 -2
  657. package/docs/WORKFLOW.md +2 -2
  658. package/docs/architecture.md +48 -43
  659. package/docs/developer_guide.md +22 -24
  660. package/market_adapter/README.md +0 -2
  661. package/modules/README.md +2 -1
  662. package/package.json +22 -14
  663. package/scripts/README.md +34 -8
  664. package/scripts/clean-dist.js +10 -2
  665. package/tests/README.md +4 -3
  666. package/claw/openclaw.plugin.json +0 -13
  667. package/dist/market_adapter/merge_lp_data.d.ts +0 -3
  668. package/dist/market_adapter/merge_lp_data.d.ts.map +0 -1
  669. package/dist/market_adapter/merge_lp_data.js +0 -125
  670. package/dist/market_adapter/merge_lp_data.js.map +0 -1
  671. package/dist/market_adapter/utils/paths.d.ts +0 -3
  672. package/dist/market_adapter/utils/paths.d.ts.map +0 -1
  673. package/dist/market_adapter/utils/paths.js +0 -5
  674. package/dist/market_adapter/utils/paths.js.map +0 -1
@@ -1,31 +1,41 @@
1
+ 'use strict';
1
2
  import path from 'node:path';
2
3
  import os from 'node:os';
3
- import { pathToFileURL } from 'node:url';
4
+ import { pathToFileURL, fileURLToPath } from 'node:url';
4
5
  import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';
5
- import { calculateAMA } from '../../market_adapter/core/strategies/ama.js';
6
+ import { calculateAMA, getAmaWarmupBars } from '../../market_adapter/core/strategies/ama.js';
7
+ import { computeAverageAmaSlopePct } from '../../market_adapter/core/strategies/ama_slope_model.js';
6
8
  import { range } from '../math_utils.js';
7
9
  import { parseListOrRange, loadLpData, fmt } from './shared_utils.js';
8
10
  import { getStorage } from '../../modules/storage/index.js';
9
11
  import { PATHS } from '../../modules/paths.js';
12
+ import { GRID_LIMITS, MARKET_ADAPTER } from '../../modules/constants.js';
13
+ // Production grid geometry + slope-ratio offset — shared with bot_fitting so
14
+ // both tools build byte-identical grids for identical params (#12).
15
+ import { buildProductionGrid, computeGridPriceOffsetPct } from './backtest_bot_fitting.js';
10
16
  const { readJSON, writeJSON } = getStorage();
11
- 'use strict';
12
17
  /**
13
18
  * AMA SWEEP BACKTEST — persistent grid simulation
14
19
  *
15
20
  * Models the real bot mechanics:
16
21
  * - Orders sit at FIXED chain prices until canceled or filled
17
- * - When AMA drifts past reposition threshold, grid re-centers
18
- * - Grid compression: AMA shift pushes one side's orders closer to market
22
+ * - Slot rotation: a filled buy re-offers its base ONE RAIL STEP UP; when
23
+ * that refill sells, one increment (minus fees) is booked and the freed
24
+ * quote re-bids one rail step down — anchor-&-refill cycling
25
+ * - Unlinked (initial-grid) sells execute only against held inventory;
26
+ * bought-and-held base carries across resets as a weighted-average-entry
27
+ * position whose final mark is reported informationally, not scored
19
28
  * - Order sizing depends on capital, ratio (range width), and weight profile
20
29
  * - Three weight profiles: valley, neutral, mountain (symmetric buy/sell)
21
30
  *
22
31
  * Usage:
23
- * tsx analysis/bot_fitting/backtest_ama_sweep.ts --data <path-to-lp-candles.json>
24
- * tsx analysis/bot_fitting/backtest_ama_sweep.ts --data <path-to-lp-candles.json> --spread 4:16:1 --increment 0.5:4:0.25
32
+ * node dist/analysis/bot_fitting/backtest_ama_sweep.js --data <path-to-lp-candles.json>
33
+ * node dist/analysis/bot_fitting/backtest_ama_sweep.js --data <path-to-lp-candles.json> --spread 4:16:1 --increment 0.5:4:0.25
25
34
  */
26
- const DEFAULT_MAX_ORDERS = 20; // matches bot default activeOrders per side
35
+ const DEFAULT_MAX_ORDERS = 20; // weight-profile sizing cap per side (search abstraction)
27
36
  const DEFAULT_FEE_ROUNDTRIP_PCT = 0.20;
28
- const DEFAULT_MIN_SPREAD_FACTOR = 2.1;
37
+ // Canonical spread floor from production grid limits (modules/constants.ts).
38
+ const DEFAULT_MIN_SPREAD_FACTOR = GRID_LIMITS.MIN_SPREAD_FACTOR;
29
39
  const DEFAULT_CAPITAL = 10000; // notional units per side
30
40
  const DEFAULT_BTS_CREATE_FEE = 0.48260;
31
41
  const DEFAULT_BTS_CANCEL_FEE = 0.00482;
@@ -41,13 +51,20 @@ const WEIGHT_PROFILES = {
41
51
  mountain: 1.5, // strong decay → inner levels get more
42
52
  };
43
53
  // Search grid defaults — centered around bot defaults (spread=2%, increment=0.5%)
44
- // Spread = distance from center to first order on each side (half the bid-ask gap)
45
- // Increment = distance between successive orders on the same side
54
+ // Spread = targetSpreadPercent for the gapSlots spread zone (production
55
+ // semantics, matching bot_fitting — the legacy half-spread dead zone is gone).
56
+ // Increment = geometric rail step between successive orders on the same side.
46
57
  const DEFAULT_SPREAD_VALUES = [...range(0.5, 4, 0.25), ...range(5, 12, 1)];
47
58
  const DEFAULT_INCREMENT_VALUES = [...range(0.2, 2, 0.1), ...range(2.5, 8, 0.5)];
48
59
  const DEFAULT_RATIO_VALUES = [1.05, 1.1, 1.15, 1.2, 1.3, 1.5, 2, 3, 5, 10];
49
- // Reposition threshold: AMA must move this fraction from last grid center to trigger re-center
50
- const DEFAULT_REPOSITION_PCT = 2.5;
60
+ // Reposition threshold: production default (MARKET_ADAPTER
61
+ // AMA_DELTA_THRESHOLD_PERCENT = 1%); --reposition overrides.
62
+ const DEFAULT_REPOSITION_PCT = MARKET_ADAPTER.AMA_DELTA_THRESHOLD_PERCENT;
63
+ // Trigger B / grid-price offset (asymmetricBounds whitelist) — same constants
64
+ // as bot_fitting, shared semantics with the live adapter.
65
+ const SLOPE_TRIGGER_FACTOR = MARKET_ADAPTER.AMA_SLOPE_DELTA_THRESHOLD_PERCENT;
66
+ const SLOPE_MAX_PCT = MARKET_ADAPTER.DYNAMIC_WEIGHT_AMA_MAX_SLOPE_PCT;
67
+ const SLOPE_LOOKBACK_BARS = MARKET_ADAPTER.DYNAMIC_WEIGHT_AMA_LOOKBACK_BARS;
51
68
  function parseArgs() {
52
69
  const args = process.argv.slice(2);
53
70
  const out = {
@@ -61,6 +78,7 @@ function parseArgs() {
61
78
  minSpreadFactor: DEFAULT_MIN_SPREAD_FACTOR,
62
79
  capital: DEFAULT_CAPITAL,
63
80
  repositionPct: DEFAULT_REPOSITION_PCT,
81
+ asymmetricBounds: false,
64
82
  btsCreateFee: DEFAULT_BTS_CREATE_FEE,
65
83
  btsCancelFee: DEFAULT_BTS_CANCEL_FEE,
66
84
  makerCreateFactor: DEFAULT_BTS_MAKER_CREATE_FACTOR,
@@ -69,6 +87,10 @@ function parseArgs() {
69
87
  };
70
88
  for (let i = 0; i < args.length; i++) {
71
89
  const arg = args[i];
90
+ if (arg === '--asymmetric-bounds') {
91
+ out.asymmetricBounds = true;
92
+ continue;
93
+ }
72
94
  const val = args[i + 1];
73
95
  if (arg === '--help' || arg === '-h') {
74
96
  printHelp();
@@ -156,14 +178,15 @@ function printHelp() {
156
178
  console.log('Options:');
157
179
  console.log(' --data <path> LP candle JSON');
158
180
  console.log(' --results <path> AMA optimizer results JSON');
159
- console.log(' --spread <spec> Spread values (% ): 1:10:0.5 or 2,4,8');
181
+ console.log(' --spread <spec> Target spread % (gapSlots zone): 1:10:0.5 or 2,4,8');
160
182
  console.log(' --increment <spec> Increment values (%): 0.5:5:0.5 or 1,2,3');
161
183
  console.log(' --ratio <spec> Max/min ratio: 1.5,2,3,5');
162
- console.log(' --max-orders <n> Max orders per side (default: 20, actual limited by ratio+increment)');
184
+ console.log(' --max-orders <n> Size cap per side (default: 20)');
163
185
  console.log(' --fee <pct> Round-trip fee % (default: 0.20)');
164
186
  console.log(' --min-spread-factor <n> Spread >= factor * increment (default: 2.1)');
165
187
  console.log(' --capital <n> Notional capital per side (default: 10000)');
166
- console.log(' --reposition <pct> AMA drift % to trigger re-center (default: 2.5)');
188
+ console.log(' --reposition <pct> AMA drift % to trigger re-center (default: 1.00, production)');
189
+ console.log(' --asymmetric-bounds Enable slope-delta reset (B) + grid price offset (whitelist semantics)');
167
190
  console.log(' --bts-create-fee <n> BTS create fee (default: 0.48260)');
168
191
  console.log(' --bts-cancel-fee <n> BTS cancel fee (default: 0.00482)');
169
192
  console.log(' --maker-create-factor Maker share of create fee (default: 0.10)');
@@ -223,111 +246,129 @@ function allocateFundsByWeights(totalFunds, n, weight, incrementFactor) {
223
246
  }
224
247
  // ── Persistent grid simulation ───────────────────────────────────────────────
225
248
  /**
226
- * Build a fresh grid centered at `center`.
227
- *
228
- * Grid placement (matches real bot):
229
- * Level k (1-based):
230
- * offset_k = spreadPct/2/100 + (k-1) * incrementPct
231
- * buyPrice = center * (1 - offset_k)
232
- * sellPrice = center * (1 + offset_k)
233
- *
234
- * So spread controls the dead zone around center (no orders within spread/2),
235
- * and increment is the gap between successive orders on the same side.
249
+ * Build a fresh grid centered at `center` using the SHARED production
250
+ * geometry (buildProductionGrid from backtest_bot_fitting — createOrderGrid
251
+ * port): master rail at √(1±inc) offsets bounded by [center/ratio,
252
+ * center*ratio] with a calculateGapSlots spread zone. This guarantees the
253
+ * sweep and bot_fitting build byte-identical grids for identical params
254
+ * (#12). Weight-profile sizing is applied over the capped nearest-to-gap
255
+ * levels, index 0 = closest to the gap.
236
256
  *
237
257
  * Returns arrays of buy and sell order objects with fixed chain prices and sizes.
238
258
  */
239
259
  function buildGrid(center, params, capitalPerSide, weightFactor) {
240
260
  const { incrementPct, maxMinRatio, maxOrders, spreadPct } = params;
241
- const minBound = center / maxMinRatio;
242
- const maxBound = center * maxMinRatio;
243
- const halfSpread = spreadPct / 200; // as fraction
244
- const buys = [];
245
- const sells = [];
246
- // Fill as many levels as fit within ratio bounds (up to maxOrders cap)
247
- for (let k = 1; k <= maxOrders; k++) {
248
- const offset = halfSpread + (k - 1) * incrementPct;
249
- if (offset >= 0.95)
250
- continue;
251
- const buyPrice = center * (1 - offset);
252
- const sellPrice = center * (1 + offset);
253
- // Bounds check — skip levels outside ratio range
254
- if (buyPrice < minBound || sellPrice > maxBound)
255
- continue;
256
- buys.push({ level: k, price: buyPrice, filledBar: -1, size: 0 });
257
- sells.push({ level: k, price: sellPrice, filledBar: -1, size: 0 });
258
- }
259
- // Size allocation — index 0 = closest to center
260
- const buySizes = allocateFundsByWeights(capitalPerSide, buys.length, weightFactor, incrementPct);
261
- const sellSizes = allocateFundsByWeights(capitalPerSide, sells.length, weightFactor, incrementPct);
262
- buys.forEach((o, i) => { o.size = buySizes[i] || 0; });
263
- sells.forEach((o, i) => { o.size = sellSizes[i] || 0; });
264
- return { buys, sells };
265
- }
266
- function closeFilledInventoryAtPrice(openBuys, openSells, exitPrice, feeRoundtripPct) {
267
- if (!Number.isFinite(exitPrice) || exitPrice <= 0) {
268
- return { grossUnits: 0, profitUnits: 0, closedOrders: 0 };
269
- }
270
- let grossUnits = 0;
271
- let profitUnits = 0;
272
- let closedOrders = 0;
273
- for (const order of openBuys.values()) {
274
- if (!order?.filled || !Number.isFinite(order.price) || order.price <= 0)
275
- continue;
276
- if (!Number.isFinite(order.size) || order.size <= 0)
277
- continue;
278
- const grossPct = (exitPrice / order.price - 1) * 100;
279
- const netPct = grossPct - feeRoundtripPct;
280
- grossUnits += order.size * (grossPct / 100);
281
- profitUnits += order.size * (netPct / 100);
282
- closedOrders++;
283
- }
284
- for (const order of openSells.values()) {
285
- if (!order?.filled || !Number.isFinite(order.price) || order.price <= 0)
286
- continue;
287
- if (!Number.isFinite(order.size) || order.size <= 0)
288
- continue;
289
- const grossPct = (order.price / exitPrice - 1) * 100;
290
- const netPct = grossPct - feeRoundtripPct;
291
- grossUnits += order.size * (grossPct / 100);
292
- profitUnits += order.size * (netPct / 100);
293
- closedOrders++;
294
- }
295
- return { grossUnits, profitUnits, closedOrders };
261
+ const built = buildProductionGrid(center, spreadPct, incrementPct, maxMinRatio, maxOrders);
262
+ const buySizes = allocateFundsByWeights(capitalPerSide, built.buys.length, weightFactor, incrementPct);
263
+ const sellSizes = allocateFundsByWeights(capitalPerSide, built.sells.length, weightFactor, incrementPct);
264
+ // Level k = k-th slot from the gap on each side. Each placed slot also
265
+ // carries its MASTER-RAIL index so rotation hops land on adjacent rail
266
+ // nodes (live anchor-&-refill hop) instead of a flat ×(1+inc).
267
+ const buys = built.buys.map((price, i) => {
268
+ const k = built.buys.length - i;
269
+ return { level: k, price, railIdx: built.buySliceStart + i, cooldownUntil: -1, size: buySizes[k - 1] || 0 };
270
+ });
271
+ const sells = built.sells.map((price, i) => ({
272
+ level: i + 1, price, railIdx: built.sellStartIdx + i, cooldownUntil: -1, size: sellSizes[i] || 0,
273
+ }));
274
+ return { buys, sells, rail: built.rail };
296
275
  }
297
- function countCancelableOrders(openBuys, openSells) {
298
- let count = 0;
299
- for (const order of openBuys.values()) {
300
- if (!order?.filled)
301
- count++;
302
- }
303
- for (const order of openSells.values()) {
304
- if (!order?.filled)
305
- count++;
276
+ /**
277
+ * Mark the held inventory position to `markPrice` in capital units.
278
+ *
279
+ * Carried bags are a REAL risk the drawdown tracker should see bar-by-bar,
280
+ * but their mark is informational for scoring: realized rotation profit plus
281
+ * op fees drive netProfit, and the end-of-run position is reported separately
282
+ * instead of being dumped into totals.
283
+ */
284
+ function markInventoryAtPrice(inventory, exitPrice, feeRoundtripPct) {
285
+ if (!Number.isFinite(exitPrice) || exitPrice <= 0 || inventory.units <= 0) {
286
+ return { grossUnits: 0, profitUnits: 0 };
306
287
  }
307
- return count;
288
+ const avgEntry = inventory.cost / inventory.units;
289
+ const grossUnits = (exitPrice - avgEntry) * inventory.units;
290
+ const feeUnits = avgEntry * inventory.units * ((feeRoundtripPct / 2) / 100);
291
+ return { grossUnits, profitUnits: grossUnits - feeUnits };
308
292
  }
309
293
  function simulatePersistentGrid(candles, amaValues, params, weightName, weightFactor) {
310
- const { spreadPct, incrementPct, maxMinRatio, maxOrders, feeRoundtripPct, capital, repositionThreshold, btsCreateFee, btsCancelFee, makerCreateFactor, txFeePrice } = params;
311
- const skip = Math.max(20, Math.floor(candles.length * 0.1));
294
+ const { spreadPct, incrementPct, maxMinRatio, feeRoundtripPct, capital, repositionThreshold, asymmetricBounds, btsCreateFee, btsCancelFee, makerCreateFactor, txFeePrice } = params;
295
+ // Warmup follows production AMA seeding/convergence (getAmaWarmupBars,
296
+ // passed via params.warmupBars from sweepOneAma) instead of an arbitrary
297
+ // fraction of the dataset. Direct callers that omit warmupBars fall back
298
+ // to the legacy 10% cut.
299
+ const warmupParam = Number.isFinite(params.warmupBars)
300
+ ? params.warmupBars
301
+ : Math.max(20, Math.floor(candles.length * 0.1));
302
+ const skip = Math.min(warmupParam, Math.max(0, candles.length - 2));
312
303
  const capitalPerSide = capital;
313
- // State
314
- let gridCenter = amaValues[skip];
315
- let grid = buildGrid(gridCenter, params, capitalPerSide, weightFactor);
316
- let lastRepositionBar = skip;
317
- // Open orders: maps level -> { price, size, bar, side }
318
- const openBuys = new Map();
319
- const openSells = new Map();
320
- // Place initial orders
321
- for (const o of grid.buys)
322
- openBuys.set(o.level, { price: o.price, size: o.size, bar: skip });
323
- for (const o of grid.sells)
324
- openSells.set(o.level, { price: o.price, size: o.size, bar: skip });
304
+ const makerCreateFeeBts = btsCreateFee * makerCreateFactor;
305
+ const slopeDeltaThresholdPct = (SLOPE_TRIGGER_FACTOR / 100) * SLOPE_MAX_PCT;
306
+ // First tradable bar: need a finite positive AMA to anchor the grid.
307
+ let startIdx = Math.min(skip, candles.length - 1);
308
+ let gridCenter = Number.NaN;
309
+ for (let j = startIdx; j < candles.length; j++) {
310
+ const v = amaValues[j];
311
+ if (Number.isFinite(v) && v > 0) {
312
+ gridCenter = v;
313
+ startIdx = j;
314
+ break;
315
+ }
316
+ }
317
+ // Production AMA slope series (%/bar averaged over the lookback window) —
318
+ // feeds trigger B and the grid price offset when asymmetricBounds is on.
319
+ const slopeAt = new Array(candles.length).fill(null);
320
+ for (let j = SLOPE_LOOKBACK_BARS; j < candles.length; j++) {
321
+ const s = computeAverageAmaSlopePct(amaValues[j], amaValues[j - SLOPE_LOOKBACK_BARS], SLOPE_LOOKBACK_BARS);
322
+ if (s != null && Number.isFinite(s))
323
+ slopeAt[j] = s;
324
+ }
325
+ // State — slot-rotation engine (mirrors simulateForParams in
326
+ // backtest_bot_fitting, with weight-profile sized orders):
327
+ // orders: id -> { side, price, size, linkedBuyPrice, linkedEntryBar,
328
+ // cooldownUntil }. linkedBuyPrice != null marks an armed
329
+ // refill sell created by a specific filled buy (one-increment rotation).
330
+ const orders = new Map();
331
+ let nextOrderId = 0;
332
+ // Bought-and-held base across the whole run (weighted-average entry pool).
333
+ // Never negative — unfundable sells stay pending instead of shorting.
334
+ const inventory = { units: 0, cost: 0 };
335
+ const stepUpFrac = 1 + incrementPct; // one-rail-step rotation distance
336
+ let btsFeesBts = 0;
337
+ let offsetAppliedCount = 0;
338
+ // Master rail of the CURRENT epoch — rotation hops read adjacent nodes.
339
+ let activeRail = [];
340
+ const placeInitialGrid = (center, slopePct) => {
341
+ const offsetPct = (asymmetricBounds && slopePct != null)
342
+ ? computeGridPriceOffsetPct(slopePct, spreadPct)
343
+ : 0;
344
+ if (offsetPct !== 0)
345
+ offsetAppliedCount++;
346
+ const effCenter = center * (1 + offsetPct / 100);
347
+ const grid = buildGrid(effCenter, params, capitalPerSide, weightFactor);
348
+ activeRail = grid.rail;
349
+ orders.clear();
350
+ for (const o of grid.buys) {
351
+ orders.set(nextOrderId++, { side: 'buy', price: o.price, size: o.size, railIdx: o.railIdx, linkedBuyPrice: null, linkedEntryBar: -1, cooldownUntil: -1 });
352
+ }
353
+ for (const o of grid.sells) {
354
+ orders.set(nextOrderId++, { side: 'sell', price: o.price, size: o.size, railIdx: o.railIdx, linkedBuyPrice: null, linkedEntryBar: -1, cooldownUntil: -1 });
355
+ }
356
+ btsFeesBts += (grid.buys.length + grid.sells.length) * makerCreateFeeBts;
357
+ };
358
+ if (Number.isFinite(gridCenter))
359
+ placeInitialGrid(gridCenter, slopeAt[startIdx]);
360
+ let lastRepositionBar = startIdx;
325
361
  let matchedPairs = 0;
326
- let totalProfitUnits = 0; // profit in capital units (size * netPct)
362
+ let cyclesTotal = 0;
363
+ let rotationCount = 0; // linked ping-pong rotations (buy → refill sell)
364
+ let inventorySaleCount = 0; // unlinked sells executed against held bags
365
+ let totalProfitUnits = 0; // REALIZED profit in capital units (size * netPct)
327
366
  let totalGrossUnits = 0;
328
367
  let touchedOrders = 0;
329
368
  let canceledOnReposition = 0;
330
369
  let repositionCount = 0;
370
+ let driftTriggerCount = 0;
371
+ let slopeTriggerCount = 0;
331
372
  let peakOpenOrders = 0;
332
373
  let imbalanceSum = 0;
333
374
  let imbalanceSamples = 0;
@@ -341,19 +382,29 @@ function simulatePersistentGrid(candles, amaValues, params, weightName, weightFa
341
382
  let runningProfit = 0;
342
383
  let peakEquityProfit = 0;
343
384
  let maxDrawdown = 0;
344
- // Track inventory risk: net exposure from filled-but-unmatched orders
345
- let inventoryExposure = 0; // positive = long (bought), negative = short (sold)
385
+ // Track inventory risk: bought-and-held base, carried across resets —
386
+ // resets never realize inventory (#4). Long-only (no unfunded shorts).
387
+ let inventoryExposure = 0; // held base units (long-only, ≥ 0)
346
388
  let maxInventoryExposure = 0;
347
- const liveBars = candles.length - skip - 1;
348
- const ordersPerSide = grid.buys.length; // actual orders placed per side (clipped by ratio)
349
- const makerCreateFeeBts = btsCreateFee * makerCreateFactor;
350
- const newOrdersPerReposition = ordersPerSide * 2;
351
- for (let i = skip + 1; i < candles.length; i++) {
389
+ const invAvgEntry = () => (inventory.units > 0 ? inventory.cost / inventory.units : 0);
390
+ const liveBars = candles.length - startIdx - 1;
391
+ const ordersPerSide = [...orders.values()].filter((o) => o.side === 'buy').length;
392
+ // Slope-delta baseline: mirrors botState.gridRangeScalingAmaSlope —
393
+ // seeded at bootstrap and re-seeded on every reset.
394
+ let slopeBaseline = null;
395
+ for (let j = startIdx + 1; j < candles.length; j++) {
396
+ if (slopeAt[j] != null) {
397
+ slopeBaseline = slopeAt[j];
398
+ break;
399
+ }
400
+ }
401
+ for (let i = startIdx + 1; i < candles.length; i++) {
352
402
  const ama = amaValues[i];
353
403
  const hi = candles[i].high;
354
404
  const lo = candles[i].low;
355
405
  const gridAgeBars = i - lastRepositionBar;
356
- // ── Reposition check: AMA drifted too far from grid center ──────
406
+ // ── Reposition check: trigger A (AMA drift, ratchet) or trigger B
407
+ // (slope delta, only under the asymmetricBounds whitelist gate).
357
408
  const drift = Math.abs(ama - gridCenter) / gridCenter;
358
409
  const driftPct = drift * 100;
359
410
  centerDriftSumPct += driftPct;
@@ -364,101 +415,160 @@ function simulatePersistentGrid(candles, amaValues, params, weightName, weightFa
364
415
  maxGridAgeBars = gridAgeBars;
365
416
  if (drift >= repositionThreshold * 0.5)
366
417
  nearThresholdBars++;
367
- if (drift >= repositionThreshold) {
418
+ let shouldReposition = drift >= repositionThreshold;
419
+ if (shouldReposition) {
368
420
  triggerDriftSumPct += driftPct;
369
- canceledOnReposition += countCancelableOrders(openBuys, openSells);
421
+ driftTriggerCount++;
422
+ }
423
+ if (!shouldReposition && asymmetricBounds && slopeBaseline != null && slopeAt[i] != null) {
424
+ const slopeDeltaPct = Math.abs(slopeAt[i] - slopeBaseline);
425
+ if (slopeDeltaPct >= slopeDeltaThresholdPct) {
426
+ shouldReposition = true;
427
+ slopeTriggerCount++;
428
+ }
429
+ }
430
+ if (shouldReposition && Number.isFinite(ama) && ama > 0) {
431
+ canceledOnReposition += orders.size;
432
+ btsFeesBts += orders.size * btsCancelFee;
433
+ orders.clear(); // inventory survives — resync never market-sells
370
434
  repositionCount++;
371
- const exitPrice = Number.isFinite(ama) && ama > 0 ? ama : candles[i].close;
372
- const forcedClose = closeFilledInventoryAtPrice(openBuys, openSells, exitPrice, feeRoundtripPct);
373
- totalGrossUnits += forcedClose.grossUnits;
374
- totalProfitUnits += forcedClose.profitUnits;
375
- runningProfit += forcedClose.profitUnits;
376
- // Unmatched inventory is realized on reposition (position closed at market)
377
- inventoryExposure = 0;
378
- openBuys.clear();
379
- openSells.clear();
380
435
  // Re-center grid
381
436
  gridCenter = ama;
382
- grid = buildGrid(gridCenter, params, capitalPerSide, weightFactor);
437
+ if (slopeAt[i] != null)
438
+ slopeBaseline = slopeAt[i];
439
+ placeInitialGrid(gridCenter, slopeAt[i]);
383
440
  lastRepositionBar = i;
384
- for (const o of grid.buys)
385
- openBuys.set(o.level, { price: o.price, size: o.size, bar: i });
386
- for (const o of grid.sells)
387
- openSells.set(o.level, { price: o.price, size: o.size, bar: i });
388
441
  }
389
442
  // ── Track imbalance & peak ──────────────────────────────────────
390
- const currentOpen = openBuys.size + openSells.size;
443
+ const currentOpen = orders.size;
391
444
  if (currentOpen > peakOpenOrders)
392
445
  peakOpenOrders = currentOpen;
393
- imbalanceSum += Math.abs(openBuys.size - openSells.size);
446
+ let buyCountNow = 0;
447
+ for (const [, o] of orders) {
448
+ if (o.side === 'buy')
449
+ buyCountNow++;
450
+ }
451
+ imbalanceSum += Math.abs(buyCountNow - (orders.size - buyCountNow));
394
452
  imbalanceSamples++;
395
- // ── Check fills on PERSISTENT orders (fixed chain prices) ───────
396
- // Only check UNFILLED orders (skip already-filled pending match)
453
+ // ── Fill detection against FIXED chain prices ───────────────────
397
454
  const filledBuysThisBar = [];
398
455
  const filledSellsThisBar = [];
399
- for (const [lvl, order] of openBuys) {
400
- if (!order.filled && lo <= order.price) {
401
- filledBuysThisBar.push({ lvl, order });
402
- }
403
- }
404
- for (const [lvl, order] of openSells) {
405
- if (!order.filled && hi >= order.price) {
406
- filledSellsThisBar.push({ lvl, order });
407
- }
456
+ for (const [id, o] of orders) {
457
+ if (i < o.cooldownUntil || !(o.size > 0))
458
+ continue;
459
+ if (o.side === 'buy' && lo <= o.price)
460
+ filledBuysThisBar.push({ id, order: o });
461
+ else if (o.side === 'sell' && hi >= o.price)
462
+ filledSellsThisBar.push({ id, order: o });
408
463
  }
409
- // Process buy fills
464
+ touchedOrders += filledBuysThisBar.length + filledSellsThisBar.length;
465
+ // Base held BEFORE this bar's intakes — unlinked sells may only
466
+ // dispose against pre-existing funds (same-bar funding not assumed).
467
+ const disposablesAtBarStart = inventory.units;
468
+ // ── Buy intakes first: base enters the inventory pool, refill armed
469
+ // at the ADJACENT MASTER-RAIL NODE above (cooldown blocks same-bar).
410
470
  for (const fb of filledBuysThisBar) {
411
- touchedOrders++;
412
- inventoryExposure += fb.order.size; // bought → long exposure
413
- // Mark as filled, waiting for paired sell at same level
414
- openBuys.set(fb.lvl, { ...fb.order, filled: true, filledBar: i, side: 'buy' });
471
+ orders.delete(fb.id);
472
+ inventory.units += fb.order.size;
473
+ inventory.cost += fb.order.price * fb.order.size;
474
+ const upIdx = (fb.order.railIdx ?? -1) + 1;
475
+ const refillPrice = activeRail[upIdx] ?? fb.order.price * stepUpFrac;
476
+ orders.set(nextOrderId++, {
477
+ side: 'sell',
478
+ price: refillPrice,
479
+ size: fb.order.size,
480
+ railIdx: upIdx,
481
+ linkedBuyPrice: fb.order.price,
482
+ linkedEntryBar: i,
483
+ cooldownUntil: i + 1,
484
+ });
485
+ btsFeesBts += makerCreateFeeBts;
415
486
  }
416
- // Process sell fills
487
+ // ── Sell disposals: linked refills book the one-rail-hop rotation;
488
+ // unlinked sells need held inventory. Linked resolve FIRST.
489
+ filledSellsThisBar.sort((a, b) => ((a.order.linkedBuyPrice != null ? 0 : 1) - (b.order.linkedBuyPrice != null ? 0 : 1)));
490
+ let disposables = disposablesAtBarStart;
417
491
  for (const fs of filledSellsThisBar) {
418
- touchedOrders++;
419
- inventoryExposure -= fs.order.size; // sold → short exposure
420
- // Mark as filled, waiting for paired buy at same level
421
- openSells.set(fs.lvl, { ...fs.order, filled: true, filledBar: i, side: 'sell' });
422
- }
423
- // Match completed pairs: both buy AND sell at same level are filled
424
- for (let k = 1; k <= maxOrders; k++) {
425
- const buyEntry = openBuys.get(k);
426
- const sellEntry = openSells.get(k);
427
- if (!buyEntry?.filled || !sellEntry?.filled)
428
- continue;
429
- // Matched pair!
430
- openBuys.delete(k);
431
- openSells.delete(k);
432
- matchedPairs++;
433
- const duration = Math.abs(sellEntry.filledBar - buyEntry.filledBar);
434
- matchedOpenDurationBars += duration;
435
- const avgSize = (buyEntry.size + sellEntry.size) / 2;
436
- const pairGrossPct = (sellEntry.price / buyEntry.price - 1) * 100;
437
- const pairNetPct = pairGrossPct - feeRoundtripPct;
438
- const profitUnits = avgSize * (pairNetPct / 100);
439
- totalGrossUnits += avgSize * (pairGrossPct / 100);
440
- totalProfitUnits += profitUnits;
441
- runningProfit += profitUnits;
492
+ const order = fs.order;
493
+ const size = order.size;
494
+ if (order.linkedBuyPrice != null) {
495
+ const grossPct = (order.price / order.linkedBuyPrice - 1) * 100;
496
+ const netPct = grossPct - feeRoundtripPct;
497
+ totalGrossUnits += size * (grossPct / 100);
498
+ totalProfitUnits += size * (netPct / 100);
499
+ runningProfit += size * (netPct / 100);
500
+ cyclesTotal++;
501
+ rotationCount++;
502
+ matchedPairs++;
503
+ matchedOpenDurationBars += Math.abs(i - order.linkedEntryBar);
504
+ // Dispose the base this rotation bought (at pool-average cost).
505
+ const applied = Math.min(size, inventory.units);
506
+ inventory.cost -= applied * invAvgEntry();
507
+ inventory.units -= applied;
508
+ // Its disposal also drains the pre-bar funding budget —
509
+ // otherwise later unlinked sales could overspend stock.
510
+ disposables -= applied;
511
+ // Freed quote re-bids the ADJACENT RAIL NODE below.
512
+ const downIdx = (order.railIdx ?? 0) - 1;
513
+ const rebidPrice = activeRail[downIdx] ?? order.price / stepUpFrac;
514
+ orders.delete(fs.id);
515
+ orders.set(nextOrderId++, {
516
+ side: 'buy',
517
+ price: rebidPrice,
518
+ size,
519
+ railIdx: downIdx,
520
+ linkedBuyPrice: null,
521
+ linkedEntryBar: -1,
522
+ cooldownUntil: i + 1,
523
+ });
524
+ btsFeesBts += makerCreateFeeBts;
525
+ }
526
+ else if (disposables >= size - 1e-12) {
527
+ const avgEntry = invAvgEntry();
528
+ const grossPct = (order.price / avgEntry - 1) * 100;
529
+ const netPct = grossPct - feeRoundtripPct;
530
+ totalGrossUnits += size * (grossPct / 100);
531
+ totalProfitUnits += size * (netPct / 100);
532
+ runningProfit += size * (netPct / 100);
533
+ cyclesTotal++;
534
+ inventorySaleCount++;
535
+ matchedPairs++;
536
+ inventory.cost -= avgEntry * size;
537
+ inventory.units -= size;
538
+ disposables -= size;
539
+ orders.delete(fs.id); // sold bag is gone; slot not re-armed
540
+ }
541
+ else {
542
+ // Unfundable (not enough base): stays open, retries next bar.
543
+ order.cooldownUntil = i + 1;
544
+ }
442
545
  }
443
- // Track max inventory exposure
444
- const absExposure = Math.abs(inventoryExposure);
445
- if (absExposure > maxInventoryExposure)
446
- maxInventoryExposure = absExposure;
546
+ // Track max inventory exposure (long-only)
547
+ if (inventory.units > maxInventoryExposure)
548
+ maxInventoryExposure = inventory.units;
447
549
  // ── Drawdown tracking ───────────────────────────────────────────
448
- const markPrice = Number.isFinite(candles[i].close) && candles[i].close > 0
449
- ? candles[i].close
450
- : ((Number.isFinite(ama) && ama > 0) ? ama : gridCenter);
451
- const unrealized = closeFilledInventoryAtPrice(openBuys, openSells, markPrice, feeRoundtripPct).profitUnits;
452
- const equityProfit = runningProfit + unrealized;
550
+ // Realized equity only: carried bags are reported informationally and
551
+ // excluded from scoring, so their (unbounded, balance-free) marks must
552
+ // not distort the risk term either. Bag risk stays visible via
553
+ // finalInventoryUnits / finalInventoryMarkUnits.
554
+ const equityProfit = runningProfit;
453
555
  if (equityProfit > peakEquityProfit)
454
556
  peakEquityProfit = equityProfit;
455
557
  const dd = peakEquityProfit - equityProfit;
456
558
  if (dd > maxDrawdown)
457
559
  maxDrawdown = dd;
458
560
  }
459
- const fillEfficiency = touchedOrders > 0 ? (matchedPairs / touchedOrders) * 100 : 0;
561
+ // ── End-of-run inventory mark (informational, NOT in profit) ────────
562
+ // Bought-and-held base is real carried risk but unrealized bag marks are
563
+ // excluded from netProfit/scoring so trend combos can't dump phantom
564
+ // paper profit into the objective. Drawdown likewise tracks REALIZED
565
+ // equity only; bag risk stays visible through these info fields.
566
+ inventoryExposure = inventory.units;
567
+ const lastClose = candles.length > 0 ? candles[candles.length - 1].close : NaN;
568
+ const finalInventoryMark = markInventoryAtPrice(inventory, lastClose, feeRoundtripPct);
569
+ const fillEfficiency = touchedOrders > 0 ? (cyclesTotal / touchedOrders) * 100 : 0;
460
570
  const pairsPerDay = liveBars > 0 ? matchedPairs / (liveBars / 24) : 0;
461
- const avgOpenDurationBars = matchedPairs > 0 ? matchedOpenDurationBars / matchedPairs : 0;
571
+ const avgOpenDurationBars = rotationCount > 0 ? matchedOpenDurationBars / rotationCount : 0;
462
572
  const avgImbalance = imbalanceSamples > 0 ? imbalanceSum / imbalanceSamples : 0;
463
573
  const avgProfitPerPair = matchedPairs > 0 ? totalProfitUnits / matchedPairs : 0;
464
574
  const profitPerCapital = capital > 0 ? totalProfitUnits / (capital * 2) : 0; // total capital = 2 sides
@@ -468,9 +578,11 @@ function simulatePersistentGrid(candles, amaValues, params, weightName, weightFa
468
578
  const nearThresholdBarsPct = liveBars > 0 ? (nearThresholdBars / liveBars) * 100 : 0;
469
579
  const avgTriggerDriftPct = repositionCount > 0 ? triggerDriftSumPct / repositionCount : 0;
470
580
  const avgCancelOrdersPerReposition = repositionCount > 0 ? canceledOnReposition / repositionCount : 0;
471
- const estimatedFeePerRepositionBts = newOrdersPerReposition * makerCreateFeeBts + avgCancelOrdersPerReposition * btsCancelFee;
472
- const totalRepositionFeesBts = repositionCount * estimatedFeePerRepositionBts;
581
+ // Exact BTS fee totals (creates + cancels + per-cycle refills), not an
582
+ // estimate — the live bot pays the same per-op fees.
583
+ const totalRepositionFeesBts = btsFeesBts;
473
584
  const feePerDayBts = liveBars > 0 ? totalRepositionFeesBts / (liveBars / 24) : 0;
585
+ const estimatedFeePerRepositionBts = repositionCount > 0 ? totalRepositionFeesBts / repositionCount : 0;
474
586
  const totalRepositionFeeUnits = totalRepositionFeesBts * txFeePrice;
475
587
  const netProfitUnits = totalProfitUnits - totalRepositionFeeUnits;
476
588
  const netProfitPerCapital = capital > 0 ? netProfitUnits / (capital * 2) : 0;
@@ -485,10 +597,16 @@ function simulatePersistentGrid(candles, amaValues, params, weightName, weightFa
485
597
  incrementPct: incrementPct * 100, // store as %
486
598
  maxMinRatio,
487
599
  matchedPairs,
600
+ cyclesTotal,
601
+ rotationCount,
602
+ inventorySaleCount,
488
603
  touchedOrders,
489
604
  fillEfficiency,
490
605
  totalProfitUnits,
491
606
  totalGrossUnits,
607
+ finalInventoryUnits: inventoryExposure,
608
+ finalInventoryAvgEntry: inventory.units > 0 ? inventory.cost / inventory.units : 0,
609
+ finalInventoryMarkUnits: finalInventoryMark.profitUnits, // informational
492
610
  profitPerCapital,
493
611
  pairsPerDay,
494
612
  avgOpenDurationBars,
@@ -497,6 +615,8 @@ function simulatePersistentGrid(candles, amaValues, params, weightName, weightFa
497
615
  avgImbalance,
498
616
  canceledOnReposition,
499
617
  repositionCount,
618
+ driftTriggerCount,
619
+ slopeTriggerCount,
500
620
  maxDrawdown,
501
621
  maxDrawdownPct,
502
622
  maxInventoryExposure,
@@ -506,6 +626,7 @@ function simulatePersistentGrid(candles, amaValues, params, weightName, weightFa
506
626
  maxCenterDriftPct,
507
627
  nearThresholdBarsPct,
508
628
  avgTriggerDriftPct,
629
+ offsetAppliedCount,
509
630
  makerCreateFeeBts,
510
631
  btsCancelFee,
511
632
  avgCancelOrdersPerReposition,
@@ -523,6 +644,8 @@ function simulatePersistentGrid(candles, amaValues, params, weightName, weightFa
523
644
  // ── Per-AMA sweep logic (runs in main thread or worker) ─────────────────────
524
645
  function sweepOneAma(strategy, candles, closes, weightEntries, cfg) {
525
646
  const amaValues = calculateAMA(closes, { erPeriod: strategy.er, fastPeriod: strategy.fast, slowPeriod: strategy.slow });
647
+ // Production-aligned warmup: ER window + convergence (getAmaWarmupBars).
648
+ const warmupBars = getAmaWarmupBars(strategy.er, strategy.slow, 0, strategy.fast);
526
649
  let best = null;
527
650
  const top5 = [];
528
651
  const allSims = [];
@@ -545,10 +668,12 @@ function sweepOneAma(strategy, candles, closes, weightEntries, cfg) {
545
668
  feeRoundtripPct: cfg.feeRoundtripPct,
546
669
  capital: cfg.capital,
547
670
  repositionThreshold: cfg.repositionPct / 100,
671
+ asymmetricBounds: cfg.asymmetricBounds,
548
672
  btsCreateFee: cfg.btsCreateFee,
549
673
  btsCancelFee: cfg.btsCancelFee,
550
674
  makerCreateFactor: cfg.makerCreateFactor,
551
675
  txFeePrice: cfg.txFeePrice,
676
+ warmupBars,
552
677
  }, weightName, weightFactor);
553
678
  if (!best || sim.score > best.score)
554
679
  best = sim;
@@ -574,7 +699,9 @@ if (!isMainThread) {
574
699
  const { strategy, candles, closes, weightEntries, cfg } = workerData;
575
700
  const result = sweepOneAma(strategy, candles, closes, weightEntries, cfg);
576
701
  parentPort.postMessage(result);
577
- process.exit(0);
702
+ // Exit naturally: an explicit process.exit(0) here can race the
703
+ // postMessage flush and silently drop the result (same pattern as
704
+ // optimizer_high_resolution.ts workers, which exit on their own).
578
705
  }
579
706
  // ── Parallel dispatch (main thread) ─────────────────────────────────────────
580
707
  function runParallel(strategies, candles, closes, weightEntries, cfg) {
@@ -582,7 +709,9 @@ function runParallel(strategies, candles, closes, weightEntries, cfg) {
582
709
  console.log(` Workers: ${numCpus} threads (${os.cpus().length} CPUs available)\n`);
583
710
  return Promise.all(strategies.map((strategy) => {
584
711
  return new Promise((resolve, reject) => {
585
- const worker = new Worker(__filename, {
712
+ // ESM: resolve this module's path from import.meta.url
713
+ // (__filename is undefined in ES modules).
714
+ const worker = new Worker(fileURLToPath(import.meta.url), {
586
715
  workerData: { strategy, candles, closes, weightEntries, cfg },
587
716
  });
588
717
  worker.on('message', resolve);
@@ -613,9 +742,11 @@ async function run() {
613
742
  console.log(` Spread: ${cfg.spreadValues[0]}..${cfg.spreadValues[cfg.spreadValues.length - 1]}% (${cfg.spreadValues.length})`);
614
743
  console.log(` Increment: ${cfg.incrementValues[0]}..${cfg.incrementValues[cfg.incrementValues.length - 1]}% (${cfg.incrementValues.length})`);
615
744
  console.log(` Ratio: ${cfg.ratioValues[0]}..${cfg.ratioValues[cfg.ratioValues.length - 1]} (${cfg.ratioValues.length})`);
616
- console.log(` Max orders: ${cfg.maxOrders}/side (actual count from ratio+increment) | Capital: ${cfg.capital}/side | Fee: ${cfg.feeRoundtripPct}%`);
745
+ console.log(` Max orders: ${cfg.maxOrders}/side (size cap) | Capital: ${cfg.capital}/side | Fee: ${cfg.feeRoundtripPct}%`);
617
746
  console.log(` Spread floor: > fee (${cfg.feeRoundtripPct}%)`);
618
- console.log(` Reposition: ${cfg.repositionPct}% AMA drift from grid center`);
747
+ console.log(` Reset (A): ${cfg.repositionPct}% AMA drift from grid center (ratchet)`);
748
+ console.log(` Asym. bounds: ${cfg.asymmetricBounds ? 'ON — slope reset (B) + grid price offset enabled (whitelist semantics)' : 'OFF — typical non-whitelisted bot (production default)'}`);
749
+ console.log(` Reset (B): |slope - slope@lastReset| >= ${fmt((SLOPE_TRIGGER_FACTOR / 100) * SLOPE_MAX_PCT, 4)}% (lookback ${SLOPE_LOOKBACK_BARS})${cfg.asymmetricBounds ? '' : ' [gated off]'}`);
619
750
  console.log(` Tx model: create=${fmt(cfg.btsCreateFee, 5)} BTS, cancel=${fmt(cfg.btsCancelFee, 5)} BTS, maker=${fmt(cfg.makerCreateFactor * 100, 1)}%, 1 BTS=${fmt(cfg.txFeePrice, 2)} units`);
620
751
  console.log(` Combos/AMA: ${totalCombos} | Total: ${totalCombos * strategies.length}\n`);
621
752
  // ── Run AMA sweeps in parallel (one worker per AMA strategy) ──────
@@ -735,7 +866,9 @@ async function run() {
735
866
  console.log(` Repositions: ${winner.sim.repositionCount}`);
736
867
  console.log(` Grid age: avg ${fmt(winner.sim.avgGridAgeBars, 1)} bars | max ${fmt(winner.sim.maxGridAgeBars, 0)} bars`);
737
868
  console.log(` Drift: avg ${fmt(winner.sim.avgCenterDriftPct, 2)}% | max ${fmt(winner.sim.maxCenterDriftPct, 2)}% | near-threshold ${fmt(winner.sim.nearThresholdBarsPct, 1)}%`);
738
- console.log(` Tx burn: ${fmt(winner.sim.estimatedFeePerRepositionBts, 4)} BTS/reposition | ${fmt(winner.sim.feePerDayBts, 2)} BTS/day`);
869
+ console.log(` Tx burn: ${fmt(winner.sim.estimatedFeePerRepositionBts, 4)} BTS/reposition | ${fmt(winner.sim.feePerDayBts, 2)} BTS/day (exact per-op totals)`);
870
+ console.log(` Cycles: ${winner.sim.cyclesTotal} rotations (${winner.sim.rotationCount} rail-step + ${winner.sim.inventorySaleCount} inventory sales)`);
871
+ console.log(` Carried: ${fmt(winner.sim.finalInventoryUnits, 4)} base @ ${fmt(winner.sim.finalInventoryAvgEntry, 6)} avg (mark ${fmt(winner.sim.finalInventoryMarkUnits, 2)} units — info only, not scored)`);
739
872
  console.log(` Score: ${fmt(winner.sim.score, 2)}`);
740
873
  // ── Save JSON ───────────────────────────────────────────────────────────
741
874
  const outName = `ama_sweep_results_${path.basename(cfg.dataPath, '.json')}.json`;
@@ -751,6 +884,7 @@ async function run() {
751
884
  capitalPerSide: cfg.capital,
752
885
  feeRoundtripPct: cfg.feeRoundtripPct,
753
886
  repositionPct: cfg.repositionPct,
887
+ asymmetricBounds: cfg.asymmetricBounds,
754
888
  btsCreateFee: cfg.btsCreateFee,
755
889
  btsCancelFee: cfg.btsCancelFee,
756
890
  makerCreateFactor: cfg.makerCreateFactor,
@@ -765,6 +899,7 @@ async function run() {
765
899
  totalCombos: totalCombos * strategies.length,
766
900
  },
767
901
  scoring: 'netProfitPerCapital * 100 * log10(max(1, matchedPairs)) - maxDrawdownPct * 0.5',
902
+ gridModel: 'production createOrderGrid port (shared with bot_fitting): master rail sqrt(1±inc) + gapSlots spread zone; slot rotation (filled buy re-offers one rail step up, freed quote re-bids one step down, ~increment% per completed rotation); unlinked sells execute only against held inventory at weighted-average entry; bought base carries across resets and the end-of-run inventory mark is informational (excluded from scoring); exact per-op BTS fees',
768
903
  },
769
904
  strategies,
770
905
  perAma: byAma.map((row) => ({
@@ -786,8 +921,10 @@ async function run() {
786
921
  });
787
922
  console.log(`\nSaved: ${path.relative(process.cwd(), outPath)}`);
788
923
  }
789
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
924
+ // Main-thread only: workers inherit process.argv[1], so the entry guard alone
925
+ // would also match inside workers and re-run main() there.
926
+ if (isMainThread && process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
790
927
  run().catch((err) => { console.error(err); process.exit(1); });
791
928
  }
792
- export { WEIGHT_PROFILES, allocateFundsByWeights, buildGrid, closeFilledInventoryAtPrice, countCancelableOrders, simulatePersistentGrid, sweepOneAma };
929
+ export { WEIGHT_PROFILES, allocateFundsByWeights, buildGrid, markInventoryAtPrice, simulatePersistentGrid, sweepOneAma };
793
930
  //# sourceMappingURL=backtest_ama_sweep.js.map