dexbot 1.4.10 → 1.4.12

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 (502) hide show
  1. package/README.md +6 -5
  2. package/dist/analysis/chart_utils.d.ts.map +1 -1
  3. package/dist/analysis/chart_utils.js +9 -18
  4. package/dist/analysis/chart_utils.js.map +1 -1
  5. package/dist/analysis/math_utils.d.ts.map +1 -1
  6. package/dist/analysis/math_utils.js +6 -16
  7. package/dist/analysis/math_utils.js.map +1 -1
  8. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +1 -1
  9. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -1
  10. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +31 -38
  11. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -1
  12. package/dist/analysis/trend_detection/hurst_analyzer.js +7 -10
  13. package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -1
  14. package/dist/analysis/trend_detection/kalman_trend_analyzer.js +10 -14
  15. package/dist/analysis/trend_detection/kalman_trend_analyzer.js.map +1 -1
  16. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js +10 -15
  17. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js.map +1 -1
  18. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js +7 -10
  19. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js.map +1 -1
  20. package/dist/bot.d.ts.map +1 -1
  21. package/dist/bot.js +4 -12
  22. package/dist/bot.js.map +1 -1
  23. package/dist/credential-daemon.d.ts +0 -1
  24. package/dist/credential-daemon.d.ts.map +1 -1
  25. package/dist/credential-daemon.js +3 -123
  26. package/dist/credential-daemon.js.map +1 -1
  27. package/dist/dexbot.d.ts +0 -87
  28. package/dist/dexbot.d.ts.map +1 -1
  29. package/dist/dexbot.js +54 -23
  30. package/dist/dexbot.js.map +1 -1
  31. package/dist/market_adapter/ama_signal_runner.js +8 -9
  32. package/dist/market_adapter/ama_signal_runner.js.map +1 -1
  33. package/dist/market_adapter/candle_utils.js +1 -7
  34. package/dist/market_adapter/candle_utils.js.map +1 -1
  35. package/dist/market_adapter/core/asymmetric_bounds.js +1 -4
  36. package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -1
  37. package/dist/market_adapter/core/config_normalizers.js +5 -9
  38. package/dist/market_adapter/core/config_normalizers.js.map +1 -1
  39. package/dist/market_adapter/core/kibana_candles.js +8 -15
  40. package/dist/market_adapter/core/kibana_candles.js.map +1 -1
  41. package/dist/market_adapter/core/kibana_client.js +7 -13
  42. package/dist/market_adapter/core/kibana_client.js.map +1 -1
  43. package/dist/market_adapter/core/kibana_market_candles.js +6 -12
  44. package/dist/market_adapter/core/kibana_market_candles.js.map +1 -1
  45. package/dist/market_adapter/core/market_adapter_service.d.ts +2 -0
  46. package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -1
  47. package/dist/market_adapter/core/market_adapter_service.js +100 -101
  48. package/dist/market_adapter/core/market_adapter_service.js.map +1 -1
  49. package/dist/market_adapter/core/strategies/ama.js +5 -10
  50. package/dist/market_adapter/core/strategies/ama.js.map +1 -1
  51. package/dist/market_adapter/core/strategies/ama_slope_model.js +21 -24
  52. package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -1
  53. package/dist/market_adapter/core/strategies/atr/calculator.js +3 -5
  54. package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -1
  55. package/dist/market_adapter/core/strategies/collateral_manager.js +4 -6
  56. package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -1
  57. package/dist/market_adapter/core/strategies/regime_gate.js +15 -22
  58. package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -1
  59. package/dist/market_adapter/index.d.ts +23 -23
  60. package/dist/market_adapter/index.d.ts.map +1 -1
  61. package/dist/market_adapter/index.js +24 -82
  62. package/dist/market_adapter/index.js.map +1 -1
  63. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +2 -1
  64. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -1
  65. package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
  66. package/dist/market_adapter/inputs/fetch_lp_data.js +59 -98
  67. package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
  68. package/dist/market_adapter/inputs/kibana_source.js +11 -17
  69. package/dist/market_adapter/inputs/kibana_source.js.map +1 -1
  70. package/dist/market_adapter/interval_utils.js +1 -2
  71. package/dist/market_adapter/interval_utils.js.map +1 -1
  72. package/dist/market_adapter/log_format.js +1 -7
  73. package/dist/market_adapter/log_format.js.map +1 -1
  74. package/dist/market_adapter/lp_chart_core.js +20 -22
  75. package/dist/market_adapter/lp_chart_core.js.map +1 -1
  76. package/dist/market_adapter/lp_chart_runner.d.ts +1 -1
  77. package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -1
  78. package/dist/market_adapter/lp_chart_runner.js +41 -57
  79. package/dist/market_adapter/lp_chart_runner.js.map +1 -1
  80. package/dist/market_adapter/lp_chart_strategy_loader.js +30 -34
  81. package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -1
  82. package/dist/market_adapter/market_adapter.d.ts +2 -2
  83. package/dist/market_adapter/market_adapter.d.ts.map +1 -1
  84. package/dist/market_adapter/market_adapter.js +163 -222
  85. package/dist/market_adapter/market_adapter.js.map +1 -1
  86. package/dist/market_adapter/merge_lp_data.js +17 -18
  87. package/dist/market_adapter/merge_lp_data.js.map +1 -1
  88. package/dist/market_adapter/test_helpers.js +3 -14
  89. package/dist/market_adapter/test_helpers.js.map +1 -1
  90. package/dist/market_adapter/utils/adapter_client.js +7 -16
  91. package/dist/market_adapter/utils/adapter_client.js.map +1 -1
  92. package/dist/market_adapter/utils/atomic_write.js +3 -5
  93. package/dist/market_adapter/utils/atomic_write.js.map +1 -1
  94. package/dist/market_adapter/utils/chain.d.ts.map +1 -1
  95. package/dist/market_adapter/utils/chain.js +9 -17
  96. package/dist/market_adapter/utils/chain.js.map +1 -1
  97. package/dist/market_adapter/utils/data_discovery.js +8 -10
  98. package/dist/market_adapter/utils/data_discovery.js.map +1 -1
  99. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -1
  100. package/dist/market_adapter/utils/dynamic_grid_snapshot.js +11 -14
  101. package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -1
  102. package/dist/market_adapter/utils/file_lock.js +14 -19
  103. package/dist/market_adapter/utils/file_lock.js.map +1 -1
  104. package/dist/market_adapter/utils/native_history.js +8 -14
  105. package/dist/market_adapter/utils/native_history.js.map +1 -1
  106. package/dist/market_adapter/utils/paths.js +3 -6
  107. package/dist/market_adapter/utils/paths.js.map +1 -1
  108. package/dist/modules/account_bots.d.ts +1 -1
  109. package/dist/modules/account_bots.d.ts.map +1 -1
  110. package/dist/modules/account_bots.js +90 -97
  111. package/dist/modules/account_bots.js.map +1 -1
  112. package/dist/modules/account_orders.d.ts +0 -9
  113. package/dist/modules/account_orders.d.ts.map +1 -1
  114. package/dist/modules/account_orders.js +26 -121
  115. package/dist/modules/account_orders.js.map +1 -1
  116. package/dist/modules/authority_resolver.js +12 -18
  117. package/dist/modules/authority_resolver.js.map +1 -1
  118. package/dist/modules/bitshares-native/chain_client.js +16 -21
  119. package/dist/modules/bitshares-native/chain_client.js.map +1 -1
  120. package/dist/modules/bitshares-native/crypto/ecc.browser.js +12 -72
  121. package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -1
  122. package/dist/modules/bitshares-native/crypto/ecc.js +13 -40
  123. package/dist/modules/bitshares-native/crypto/ecc.js.map +1 -1
  124. package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts.map +1 -1
  125. package/dist/modules/bitshares-native/crypto/ecc_selector.js +5 -6
  126. package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -1
  127. package/dist/modules/bitshares-native/index.d.ts +8 -8
  128. package/dist/modules/bitshares-native/index.d.ts.map +1 -1
  129. package/dist/modules/bitshares-native/index.js +11 -68
  130. package/dist/modules/bitshares-native/index.js.map +1 -1
  131. package/dist/modules/bitshares-native/lru_cache.js +3 -6
  132. package/dist/modules/bitshares-native/lru_cache.js.map +1 -1
  133. package/dist/modules/bitshares-native/resolvers.js +9 -11
  134. package/dist/modules/bitshares-native/resolvers.js.map +1 -1
  135. package/dist/modules/bitshares-native/serial/chain_constants.js +3 -28
  136. package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -1
  137. package/dist/modules/bitshares-native/serial/index.d.ts +4 -4
  138. package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -1
  139. package/dist/modules/bitshares-native/serial/index.js +5 -46
  140. package/dist/modules/bitshares-native/serial/index.js.map +1 -1
  141. package/dist/modules/bitshares-native/serial/operations.d.ts +98 -98
  142. package/dist/modules/bitshares-native/serial/operations.d.ts.map +1 -1
  143. package/dist/modules/bitshares-native/serial/operations.js +372 -473
  144. package/dist/modules/bitshares-native/serial/operations.js.map +1 -1
  145. package/dist/modules/bitshares-native/serial/serializer.js +3 -8
  146. package/dist/modules/bitshares-native/serial/serializer.js.map +1 -1
  147. package/dist/modules/bitshares-native/serial/types.js +9 -74
  148. package/dist/modules/bitshares-native/serial/types.js.map +1 -1
  149. package/dist/modules/bitshares-native/signing_client.d.ts.map +1 -1
  150. package/dist/modules/bitshares-native/signing_client.js +11 -48
  151. package/dist/modules/bitshares-native/signing_client.js.map +1 -1
  152. package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -1
  153. package/dist/modules/bitshares-native/subscriptions.js +24 -27
  154. package/dist/modules/bitshares-native/subscriptions.js.map +1 -1
  155. package/dist/modules/bitshares-native/transport.d.ts.map +1 -1
  156. package/dist/modules/bitshares-native/transport.js +14 -26
  157. package/dist/modules/bitshares-native/transport.js.map +1 -1
  158. package/dist/modules/bitshares-native/tx/builder.js +29 -72
  159. package/dist/modules/bitshares-native/tx/builder.js.map +1 -1
  160. package/dist/modules/bitshares-native/tx/tx_cache.js +12 -21
  161. package/dist/modules/bitshares-native/tx/tx_cache.js.map +1 -1
  162. package/dist/modules/bitshares_client.d.ts +21 -0
  163. package/dist/modules/bitshares_client.d.ts.map +1 -1
  164. package/dist/modules/bitshares_client.js +32 -86
  165. package/dist/modules/bitshares_client.js.map +1 -1
  166. package/dist/modules/bot_settings.d.ts.map +1 -1
  167. package/dist/modules/bot_settings.js +30 -49
  168. package/dist/modules/bot_settings.js.map +1 -1
  169. package/dist/modules/bots_file_lock.d.ts.map +1 -1
  170. package/dist/modules/bots_file_lock.js +5 -13
  171. package/dist/modules/bots_file_lock.js.map +1 -1
  172. package/dist/modules/broadcast_failure.js +1 -3
  173. package/dist/modules/broadcast_failure.js.map +1 -1
  174. package/dist/modules/chain_keys.d.ts +4 -9
  175. package/dist/modules/chain_keys.d.ts.map +1 -1
  176. package/dist/modules/chain_keys.js +77 -182
  177. package/dist/modules/chain_keys.js.map +1 -1
  178. package/dist/modules/chain_orders.d.ts +2 -2
  179. package/dist/modules/chain_orders.d.ts.map +1 -1
  180. package/dist/modules/chain_orders.js +81 -144
  181. package/dist/modules/chain_orders.js.map +1 -1
  182. package/dist/modules/config.d.ts.map +1 -1
  183. package/dist/modules/config.js +23 -28
  184. package/dist/modules/config.js.map +1 -1
  185. package/dist/modules/constants.d.ts +4 -14
  186. package/dist/modules/constants.d.ts.map +1 -1
  187. package/dist/modules/constants.js +46 -78
  188. package/dist/modules/constants.js.map +1 -1
  189. package/dist/modules/cr_planner.js +15 -26
  190. package/dist/modules/cr_planner.js.map +1 -1
  191. package/dist/modules/credential_policy.d.ts +3 -6
  192. package/dist/modules/credential_policy.d.ts.map +1 -1
  193. package/dist/modules/credential_policy.js +62 -153
  194. package/dist/modules/credential_policy.js.map +1 -1
  195. package/dist/modules/credential_runtime.d.ts +1 -1
  196. package/dist/modules/credential_runtime.d.ts.map +1 -1
  197. package/dist/modules/credential_runtime.js +34 -41
  198. package/dist/modules/credential_runtime.js.map +1 -1
  199. package/dist/modules/credential_session_cache.d.ts +1 -1
  200. package/dist/modules/credential_session_cache.d.ts.map +1 -1
  201. package/dist/modules/credential_session_cache.js +5 -42
  202. package/dist/modules/credential_session_cache.js.map +1 -1
  203. package/dist/modules/credit_runtime.d.ts.map +1 -1
  204. package/dist/modules/credit_runtime.js +126 -162
  205. package/dist/modules/credit_runtime.js.map +1 -1
  206. package/dist/modules/crypto/browser_provider.d.ts +1 -1
  207. package/dist/modules/crypto/browser_provider.d.ts.map +1 -1
  208. package/dist/modules/crypto/browser_provider.js +7 -11
  209. package/dist/modules/crypto/browser_provider.js.map +1 -1
  210. package/dist/modules/crypto/index.d.ts +6 -6
  211. package/dist/modules/crypto/index.d.ts.map +1 -1
  212. package/dist/modules/crypto/index.js +12 -30
  213. package/dist/modules/crypto/index.js.map +1 -1
  214. package/dist/modules/crypto/node_provider.d.ts +1 -1
  215. package/dist/modules/crypto/node_provider.d.ts.map +1 -1
  216. package/dist/modules/crypto/node_provider.js +3 -5
  217. package/dist/modules/crypto/node_provider.js.map +1 -1
  218. package/dist/modules/crypto/provider.js +1 -2
  219. package/dist/modules/crypto/pure_ripemd160.js +1 -3
  220. package/dist/modules/crypto/pure_ripemd160.js.map +1 -1
  221. package/dist/modules/crypto/pure_scrypt.js +1 -4
  222. package/dist/modules/crypto/pure_scrypt.js.map +1 -1
  223. package/dist/modules/crypto/pure_secp256k1.d.ts +1 -1
  224. package/dist/modules/crypto/pure_secp256k1.d.ts.map +1 -1
  225. package/dist/modules/crypto/pure_secp256k1.js +1 -16
  226. package/dist/modules/crypto/pure_secp256k1.js.map +1 -1
  227. package/dist/modules/crypto/sync.d.ts.map +1 -1
  228. package/dist/modules/crypto/sync.js +16 -17
  229. package/dist/modules/crypto/sync.js.map +1 -1
  230. package/dist/modules/daemon_node_health.js +14 -16
  231. package/dist/modules/daemon_node_health.js.map +1 -1
  232. package/dist/modules/dexbot_class.d.ts +19 -14
  233. package/dist/modules/dexbot_class.d.ts.map +1 -1
  234. package/dist/modules/dexbot_class.js +127 -164
  235. package/dist/modules/dexbot_class.js.map +1 -1
  236. package/dist/modules/dexbot_cow_runtime.d.ts +28 -27
  237. package/dist/modules/dexbot_cow_runtime.d.ts.map +1 -1
  238. package/dist/modules/dexbot_cow_runtime.js +55 -45
  239. package/dist/modules/dexbot_cow_runtime.js.map +1 -1
  240. package/dist/modules/dexbot_credential_client.d.ts +6 -2
  241. package/dist/modules/dexbot_credential_client.d.ts.map +1 -1
  242. package/dist/modules/dexbot_credential_client.js +21 -31
  243. package/dist/modules/dexbot_credential_client.js.map +1 -1
  244. package/dist/modules/dexbot_fill_runtime.d.ts +23 -23
  245. package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -1
  246. package/dist/modules/dexbot_fill_runtime.js +119 -77
  247. package/dist/modules/dexbot_fill_runtime.js.map +1 -1
  248. package/dist/modules/dexbot_maintenance_runtime.d.ts +46 -38
  249. package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
  250. package/dist/modules/dexbot_maintenance_runtime.js +81 -81
  251. package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
  252. package/dist/modules/dexbot_startup_runtime.d.ts +3 -3
  253. package/dist/modules/dexbot_startup_runtime.d.ts.map +1 -1
  254. package/dist/modules/dexbot_startup_runtime.js +43 -81
  255. package/dist/modules/dexbot_startup_runtime.js.map +1 -1
  256. package/dist/modules/dexbot_state_recovery.d.ts +11 -11
  257. package/dist/modules/dexbot_state_recovery.js +32 -78
  258. package/dist/modules/dexbot_state_recovery.js.map +1 -1
  259. package/dist/modules/env.js +3 -7
  260. package/dist/modules/env.js.map +1 -1
  261. package/dist/modules/fund_registry.d.ts.map +1 -1
  262. package/dist/modules/fund_registry.js +12 -24
  263. package/dist/modules/fund_registry.js.map +1 -1
  264. package/dist/modules/general_settings.js +10 -16
  265. package/dist/modules/general_settings.js.map +1 -1
  266. package/dist/modules/graceful_shutdown.d.ts.map +1 -1
  267. package/dist/modules/graceful_shutdown.js +12 -19
  268. package/dist/modules/graceful_shutdown.js.map +1 -1
  269. package/dist/modules/key_store.d.ts.map +1 -1
  270. package/dist/modules/key_store.js +27 -65
  271. package/dist/modules/key_store.js.map +1 -1
  272. package/dist/modules/launcher/bot_supervisor.d.ts +1 -1
  273. package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -1
  274. package/dist/modules/launcher/bot_supervisor.js +89 -118
  275. package/dist/modules/launcher/bot_supervisor.js.map +1 -1
  276. package/dist/modules/launcher/child_env.js +1 -5
  277. package/dist/modules/launcher/child_env.js.map +1 -1
  278. package/dist/modules/launcher/credential_bootstrap.js +22 -31
  279. package/dist/modules/launcher/credential_bootstrap.js.map +1 -1
  280. package/dist/modules/launcher/credential_daemon.js +37 -75
  281. package/dist/modules/launcher/credential_daemon.js.map +1 -1
  282. package/dist/modules/launcher/credential_secret.js +2 -37
  283. package/dist/modules/launcher/credential_secret.js.map +1 -1
  284. package/dist/modules/launcher/foreign_cred_daemon.js +25 -31
  285. package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -1
  286. package/dist/modules/launcher/headless_password.js +10 -12
  287. package/dist/modules/launcher/headless_password.js.map +1 -1
  288. package/dist/modules/launcher/launch_modes.js +3 -9
  289. package/dist/modules/launcher/launch_modes.js.map +1 -1
  290. package/dist/modules/launcher/market_adapter_runtime.d.ts +1 -1
  291. package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -1
  292. package/dist/modules/launcher/market_adapter_runtime.js +25 -35
  293. package/dist/modules/launcher/market_adapter_runtime.js.map +1 -1
  294. package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -1
  295. package/dist/modules/launcher/market_adapter_watchdog.js +42 -45
  296. package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -1
  297. package/dist/modules/launcher/monolithic_runtime.d.ts +3 -2
  298. package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
  299. package/dist/modules/launcher/monolithic_runtime.js +97 -138
  300. package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
  301. package/dist/modules/launcher/runtime_entry.d.ts +1 -11
  302. package/dist/modules/launcher/runtime_entry.d.ts.map +1 -1
  303. package/dist/modules/launcher/runtime_entry.js +12 -15
  304. package/dist/modules/launcher/runtime_entry.js.map +1 -1
  305. package/dist/modules/launcher/status_reporting.d.ts +1 -1
  306. package/dist/modules/launcher/status_reporting.d.ts.map +1 -1
  307. package/dist/modules/launcher/status_reporting.js +15 -36
  308. package/dist/modules/launcher/status_reporting.js.map +1 -1
  309. package/dist/modules/launcher/supervisor_control.js +4 -9
  310. package/dist/modules/launcher/supervisor_control.js.map +1 -1
  311. package/dist/modules/logger.d.ts +1 -1
  312. package/dist/modules/logger.d.ts.map +1 -1
  313. package/dist/modules/logger.js +3 -38
  314. package/dist/modules/logger.js.map +1 -1
  315. package/dist/modules/market_adapter_whitelist.js +9 -18
  316. package/dist/modules/market_adapter_whitelist.js.map +1 -1
  317. package/dist/modules/node_failure_ledger.js +1 -3
  318. package/dist/modules/node_failure_ledger.js.map +1 -1
  319. package/dist/modules/node_health_cache.d.ts.map +1 -1
  320. package/dist/modules/node_health_cache.js +15 -25
  321. package/dist/modules/node_health_cache.js.map +1 -1
  322. package/dist/modules/node_manager.d.ts +1 -1
  323. package/dist/modules/node_manager.d.ts.map +1 -1
  324. package/dist/modules/node_manager.js +44 -43
  325. package/dist/modules/node_manager.js.map +1 -1
  326. package/dist/modules/order/accounting.d.ts.map +1 -1
  327. package/dist/modules/order/accounting.js +102 -118
  328. package/dist/modules/order/accounting.js.map +1 -1
  329. package/dist/modules/order/async_lock.d.ts +3 -15
  330. package/dist/modules/order/async_lock.d.ts.map +1 -1
  331. package/dist/modules/order/async_lock.js +6 -26
  332. package/dist/modules/order/async_lock.js.map +1 -1
  333. package/dist/modules/order/export.js +34 -75
  334. package/dist/modules/order/export.js.map +1 -1
  335. package/dist/modules/order/format.d.ts +1 -3
  336. package/dist/modules/order/format.d.ts.map +1 -1
  337. package/dist/modules/order/format.js +4 -24
  338. package/dist/modules/order/format.js.map +1 -1
  339. package/dist/modules/order/grid.d.ts +8 -8
  340. package/dist/modules/order/grid.d.ts.map +1 -1
  341. package/dist/modules/order/grid.js +254 -266
  342. package/dist/modules/order/grid.js.map +1 -1
  343. package/dist/modules/order/grid_reconcile.d.ts.map +1 -1
  344. package/dist/modules/order/grid_reconcile.js +77 -94
  345. package/dist/modules/order/grid_reconcile.js.map +1 -1
  346. package/dist/modules/order/grid_reconcile_internal.d.ts.map +1 -1
  347. package/dist/modules/order/grid_reconcile_internal.js +117 -149
  348. package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
  349. package/dist/modules/order/index.d.ts.map +1 -1
  350. package/dist/modules/order/index.js +11 -45
  351. package/dist/modules/order/index.js.map +1 -1
  352. package/dist/modules/order/logger.d.ts +0 -8
  353. package/dist/modules/order/logger.d.ts.map +1 -1
  354. package/dist/modules/order/logger.js +28 -141
  355. package/dist/modules/order/logger.js.map +1 -1
  356. package/dist/modules/order/logger_state.d.ts.map +1 -1
  357. package/dist/modules/order/logger_state.js +3 -4
  358. package/dist/modules/order/logger_state.js.map +1 -1
  359. package/dist/modules/order/manager.d.ts +10 -79
  360. package/dist/modules/order/manager.d.ts.map +1 -1
  361. package/dist/modules/order/manager.js +131 -247
  362. package/dist/modules/order/manager.js.map +1 -1
  363. package/dist/modules/order/processed_fill_store.js +2 -7
  364. package/dist/modules/order/processed_fill_store.js.map +1 -1
  365. package/dist/modules/order/strategy.js +23 -25
  366. package/dist/modules/order/strategy.js.map +1 -1
  367. package/dist/modules/order/sync_engine.d.ts +27 -0
  368. package/dist/modules/order/sync_engine.d.ts.map +1 -1
  369. package/dist/modules/order/sync_engine.js +232 -181
  370. package/dist/modules/order/sync_engine.js.map +1 -1
  371. package/dist/modules/order/utils/math.d.ts +1 -25
  372. package/dist/modules/order/utils/math.d.ts.map +1 -1
  373. package/dist/modules/order/utils/math.js +49 -172
  374. package/dist/modules/order/utils/math.js.map +1 -1
  375. package/dist/modules/order/utils/order.d.ts +46 -2
  376. package/dist/modules/order/utils/order.d.ts.map +1 -1
  377. package/dist/modules/order/utils/order.js +165 -143
  378. package/dist/modules/order/utils/order.js.map +1 -1
  379. package/dist/modules/order/utils/system.d.ts +3 -1
  380. package/dist/modules/order/utils/system.d.ts.map +1 -1
  381. package/dist/modules/order/utils/system.js +152 -211
  382. package/dist/modules/order/utils/system.js.map +1 -1
  383. package/dist/modules/order/utils/timeout.js +1 -4
  384. package/dist/modules/order/utils/timeout.js.map +1 -1
  385. package/dist/modules/order/utils/validate.js +91 -142
  386. package/dist/modules/order/utils/validate.js.map +1 -1
  387. package/dist/modules/order/utils/withPoolRef.js +21 -61
  388. package/dist/modules/order/utils/withPoolRef.js.map +1 -1
  389. package/dist/modules/order/working_grid.js +6 -9
  390. package/dist/modules/order/working_grid.js.map +1 -1
  391. package/dist/modules/path_api.d.ts.map +1 -1
  392. package/dist/modules/path_api.js +8 -11
  393. package/dist/modules/path_api.js.map +1 -1
  394. package/dist/modules/paths.d.ts.map +1 -1
  395. package/dist/modules/paths.js +61 -67
  396. package/dist/modules/paths.js.map +1 -1
  397. package/dist/modules/process_discovery.d.ts.map +1 -1
  398. package/dist/modules/process_discovery.js +14 -23
  399. package/dist/modules/process_discovery.js.map +1 -1
  400. package/dist/modules/runtime.js +7 -11
  401. package/dist/modules/runtime.js.map +1 -1
  402. package/dist/modules/runtime_settings.d.ts.map +1 -1
  403. package/dist/modules/runtime_settings.js +14 -16
  404. package/dist/modules/runtime_settings.js.map +1 -1
  405. package/dist/modules/settings_merge.js +1 -3
  406. package/dist/modules/settings_merge.js.map +1 -1
  407. package/dist/modules/socket_json_client.js +3 -5
  408. package/dist/modules/socket_json_client.js.map +1 -1
  409. package/dist/modules/storage/browser_adapter.js +1 -4
  410. package/dist/modules/storage/browser_adapter.js.map +1 -1
  411. package/dist/modules/storage/index.d.ts +3 -2
  412. package/dist/modules/storage/index.d.ts.map +1 -1
  413. package/dist/modules/storage/index.js +5 -8
  414. package/dist/modules/storage/index.js.map +1 -1
  415. package/dist/modules/storage/node_adapter.d.ts +3 -4
  416. package/dist/modules/storage/node_adapter.d.ts.map +1 -1
  417. package/dist/modules/storage/node_adapter.js +12 -16
  418. package/dist/modules/storage/node_adapter.js.map +1 -1
  419. package/dist/modules/storage/types.js +1 -2
  420. package/dist/modules/types.d.ts +0 -6
  421. package/dist/modules/types.d.ts.map +1 -1
  422. package/dist/modules/types.js +1 -2
  423. package/dist/modules/types.js.map +1 -1
  424. package/dist/modules/utils/base58check.js +8 -15
  425. package/dist/modules/utils/base58check.js.map +1 -1
  426. package/dist/modules/utils/build_dir.js +3 -7
  427. package/dist/modules/utils/build_dir.js.map +1 -1
  428. package/dist/modules/utils/errors.js +1 -5
  429. package/dist/modules/utils/errors.js.map +1 -1
  430. package/dist/modules/utils/math_utils.d.ts +1 -1
  431. package/dist/modules/utils/math_utils.d.ts.map +1 -1
  432. package/dist/modules/utils/math_utils.js +2 -7
  433. package/dist/modules/utils/math_utils.js.map +1 -1
  434. package/dist/modules/validate_profiles.d.ts.map +1 -1
  435. package/dist/modules/validate_profiles.js +18 -25
  436. package/dist/modules/validate_profiles.js.map +1 -1
  437. package/dist/pm2.d.ts +4 -70
  438. package/dist/pm2.d.ts.map +1 -1
  439. package/dist/pm2.js +106 -132
  440. package/dist/pm2.js.map +1 -1
  441. package/dist/scripts/analyze-git.js +13 -17
  442. package/dist/scripts/analyze-git.js.map +1 -1
  443. package/dist/scripts/analyze-orders.d.ts.map +1 -1
  444. package/dist/scripts/analyze-orders.js +48 -63
  445. package/dist/scripts/analyze-orders.js.map +1 -1
  446. package/dist/scripts/diagnose-kibana-candles.d.ts.map +1 -1
  447. package/dist/scripts/diagnose-kibana-candles.js +2 -1
  448. package/dist/scripts/diagnose-kibana-candles.js.map +1 -1
  449. package/dist/scripts/diagnose-pool-history.d.ts.map +1 -1
  450. package/dist/scripts/diagnose-pool-history.js +2 -1
  451. package/dist/scripts/diagnose-pool-history.js.map +1 -1
  452. package/dist/scripts/divergence-calc.d.ts.map +1 -1
  453. package/dist/scripts/divergence-calc.js +2 -2
  454. package/dist/scripts/divergence-calc.js.map +1 -1
  455. package/dist/scripts/fix-err-message.js +17 -22
  456. package/dist/scripts/fix-err-message.js.map +1 -1
  457. package/dist/scripts/generate_lp_chart.d.ts.map +1 -1
  458. package/dist/scripts/generate_lp_chart.js +7 -15
  459. package/dist/scripts/generate_lp_chart.js.map +1 -1
  460. package/dist/scripts/generate_mainnet_corpus_report.d.ts.map +1 -1
  461. package/dist/scripts/generate_mainnet_corpus_report.js +3 -2
  462. package/dist/scripts/generate_mainnet_corpus_report.js.map +1 -1
  463. package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +1 -1
  464. package/dist/scripts/generate_market_adapter_whitelist.js +18 -24
  465. package/dist/scripts/generate_market_adapter_whitelist.js.map +1 -1
  466. package/dist/scripts/native_release_gates.js +15 -19
  467. package/dist/scripts/native_release_gates.js.map +1 -1
  468. package/dist/scripts/print_grid.d.ts.map +1 -1
  469. package/dist/scripts/print_grid.js +2 -2
  470. package/dist/scripts/print_grid.js.map +1 -1
  471. package/dist/scripts/run-tests.js +12 -17
  472. package/dist/scripts/run-tests.js.map +1 -1
  473. package/dist/scripts/runner.d.ts.map +1 -1
  474. package/dist/scripts/runner.js +18 -20
  475. package/dist/scripts/runner.js.map +1 -1
  476. package/dist/scripts/sync-version.js +2 -2
  477. package/dist/scripts/sync-version.js.map +1 -1
  478. package/dist/scripts/test-credit-renewal.d.ts.map +1 -1
  479. package/dist/scripts/test-credit-renewal.js +4 -3
  480. package/dist/scripts/test-credit-renewal.js.map +1 -1
  481. package/dist/scripts/update.js +93 -95
  482. package/dist/scripts/update.js.map +1 -1
  483. package/dist/scripts/validate_bots.d.ts.map +1 -1
  484. package/dist/scripts/validate_bots.js +2 -2
  485. package/dist/scripts/validate_bots.js.map +1 -1
  486. package/dist/scripts/verify-browser-bundle.js +12 -17
  487. package/dist/scripts/verify-browser-bundle.js.map +1 -1
  488. package/dist/unlock.d.ts +0 -30
  489. package/dist/unlock.d.ts.map +1 -1
  490. package/dist/unlock.js +258 -222
  491. package/dist/unlock.js.map +1 -1
  492. package/package.json +5 -8
  493. package/scripts/README.md +1 -1
  494. package/scripts/create-bot-symlinks.sh +2 -2
  495. package/dist/modules/utils/fs_utils.d.ts +0 -18
  496. package/dist/modules/utils/fs_utils.d.ts.map +0 -1
  497. package/dist/modules/utils/fs_utils.js +0 -32
  498. package/dist/modules/utils/fs_utils.js.map +0 -1
  499. package/dist/scripts/migrate_bot_keys.d.ts +0 -3
  500. package/dist/scripts/migrate_bot_keys.d.ts.map +0 -1
  501. package/dist/scripts/migrate_bot_keys.js +0 -225
  502. package/dist/scripts/migrate_bot_keys.js.map +0 -1
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * modules/order/grid.ts - Grid Engine
4
3
  *
@@ -94,67 +93,12 @@
94
93
  *
95
94
  * ===============================================================================
96
95
  */
97
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
98
- if (k2 === undefined) k2 = k;
99
- var desc = Object.getOwnPropertyDescriptor(m, k);
100
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
101
- desc = { enumerable: true, get: function() { return m[k]; } };
102
- }
103
- Object.defineProperty(o, k2, desc);
104
- }) : (function(o, m, k, k2) {
105
- if (k2 === undefined) k2 = k;
106
- o[k2] = m[k];
107
- }));
108
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
109
- Object.defineProperty(o, "default", { enumerable: true, value: v });
110
- }) : function(o, v) {
111
- o["default"] = v;
112
- });
113
- var __importStar = (this && this.__importStar) || (function () {
114
- var ownKeys = function(o) {
115
- ownKeys = Object.getOwnPropertyNames || function (o) {
116
- var ar = [];
117
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
118
- return ar;
119
- };
120
- return ownKeys(o);
121
- };
122
- return function (mod) {
123
- if (mod && mod.__esModule) return mod;
124
- var result = {};
125
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
126
- __setModuleDefault(result, mod);
127
- return result;
128
- };
129
- })();
130
- Object.defineProperty(exports, "__esModule", { value: true });
131
- exports.calculateGapSlots = calculateGapSlots;
132
- exports.isGridBloated = isGridBloated;
133
- exports.isGridBloatGraceActive = isGridBloatGraceActive;
134
- exports.clearGridBloatFlag = clearGridBloatFlag;
135
- exports.getSizingContext = getSizingContext;
136
- exports._getSizingContext = _getSizingContext;
137
- exports.createOrderGrid = createOrderGrid;
138
- exports.loadGrid = loadGrid;
139
- exports.initializeGrid = initializeGrid;
140
- exports.recalculateGrid = recalculateGrid;
141
- exports.checkAndUpdateGridIfNeeded = checkAndUpdateGridIfNeeded;
142
- exports._recalculateGridOrderSizesFromBlockchain = _recalculateGridOrderSizesFromBlockchain;
143
- exports.updateGridFromBlockchainSnapshot = updateGridFromBlockchainSnapshot;
144
- exports.compareGrids = compareGrids;
145
- exports.monitorDivergence = monitorDivergence;
146
- exports.calculateCurrentSpread = calculateCurrentSpread;
147
- exports.checkSpreadCondition = checkSpreadCondition;
148
- exports.checkGridHealth = checkGridHealth;
149
- exports.checkWindowDust = checkWindowDust;
150
- exports.hasAnyDust = hasAnyDust;
151
- exports.getDustOrders = getDustOrders;
152
- exports.determineOrderSideByFunds = determineOrderSideByFunds;
153
- exports.prepareSpreadCorrectionOrders = prepareSpreadCorrectionOrders;
154
- const constants_1 = require("../constants");
155
- const { GRID_COMPARISON } = constants_1.GRID_LIMITS;
156
- const Format = __importStar(require("./format"));
157
- const asymmetric_bounds_1 = require("../../market_adapter/core/asymmetric_bounds");
96
+ import { createRequire } from 'node:module';
97
+ const require = createRequire(import.meta.url);
98
+ import { ORDER_TYPES, ORDER_STATES, COW_ACTIONS, DEFAULT_CONFIG, GRID_LIMITS, TIMING, PIPELINE_TIMING, MARKET_ADAPTER, INCREMENT_BOUNDS } from '../constants.js';
99
+ const { GRID_COMPARISON } = GRID_LIMITS;
100
+ import * as Format from './format.js';
101
+ import { resolveMaxAsymmetryFactor, applyAsymmetricBounds, } from '../../market_adapter/core/asymmetric_bounds.js';
158
102
  // FIX: Extract magic numbers to named constants for maintainability
159
103
  const GRID_CONSTANTS = {
160
104
  RMS_PERCENTAGE_SCALE: 100, // Convert RMS percentage threshold from percent to decimal
@@ -167,16 +111,16 @@ function _snapshotFundState(manager) {
167
111
  sellLocked: Number(manager.accountTotals?.sellLocked || 0),
168
112
  };
169
113
  }
170
- const math_1 = require("./utils/math");
171
- const order_1 = require("./utils/order");
172
- const system_1 = require("./utils/system");
173
- const withPoolRef_1 = require("./utils/withPoolRef");
174
- const market_adapter_whitelist_1 = require("../market_adapter_whitelist");
175
- const errors_1 = require("../utils/errors");
176
- function calculateGapSlots(incrementPercent, targetSpreadPercent, gridLimitsOverride) {
177
- return (0, math_1.calculateGapSlots)(incrementPercent, targetSpreadPercent, gridLimitsOverride ?? constants_1.GRID_LIMITS);
114
+ import { floatToBlockchainInt, getPrecisionByOrderType, getPrecisionsForManager, calculateOrderCreationFees, calculateOrderSizes, calculateRotationOrderSizes, calculateAvailableFundsValue, calculateGridSideDivergenceMetric, getPrecisionSlack, getMinAbsoluteOrderSize, getSingleDustThreshold, getGridBestPrices, calculateSpreadFromOrders, allocateFundsByWeights, calculateGapSlots as _mathGapSlots, findPriceCollision, getBtsSide, getSellStartIdx, resolveGapBand, countGapBandSpread, adjustBudgetForBtsFees, } from './utils/math.js';
115
+ import { filterOrdersByType, checkSizesBeforeMinimum, checkSizeThreshold, resolveConfiguredPriceBound, shouldFlagOutOfSpread, isOrderHealthy, isPhantomOrder, isSlotAvailable, isOrderOnChain, isOrderPlaced, hasOnChainId, isEmptyGridSlot, parseSlotIndex, calculateIdealBoundary, assignGridRoles, resolveOnChainRetypeType } from './utils/order.js';
116
+ import { loadAmaCenterPrice, loadAmaCenterSnapshot, withBlockchainRetry } from './utils/system.js';
117
+ import { derivePriceWithPoolRef } from './utils/withPoolRef.js';
118
+ import { getWhitelistFlags } from '../market_adapter_whitelist.js';
119
+ import { getErrorMessage } from '../utils/errors.js';
120
+ export function calculateGapSlots(incrementPercent, targetSpreadPercent, gridLimitsOverride) {
121
+ return _mathGapSlots(incrementPercent, targetSpreadPercent, gridLimitsOverride ?? GRID_LIMITS);
178
122
  }
179
- function isGridBloated(manager, orders) {
123
+ export function isGridBloated(manager, orders) {
180
124
  const gridSize = Array.isArray(orders) ? orders.length : orders.size;
181
125
  if (!gridSize || !manager?.config)
182
126
  return { bloated: false };
@@ -186,11 +130,11 @@ function isGridBloated(manager, orders) {
186
130
  return { bloated: false };
187
131
  const targetSpreadPct = config.targetSpreadPercent || incPct * 2;
188
132
  const orderList = Array.isArray(orders) ? orders : Array.from(orders.values());
189
- const numBuyActive = orderList.filter((o) => o.type === constants_1.ORDER_TYPES.BUY &&
190
- (o.state === constants_1.ORDER_STATES.ACTIVE || o.state === constants_1.ORDER_STATES.PARTIAL) &&
133
+ const numBuyActive = orderList.filter((o) => o.type === ORDER_TYPES.BUY &&
134
+ (o.state === ORDER_STATES.ACTIVE || o.state === ORDER_STATES.PARTIAL) &&
191
135
  o.orderId).length;
192
- const numSellActive = orderList.filter((o) => o.type === constants_1.ORDER_TYPES.SELL &&
193
- (o.state === constants_1.ORDER_STATES.ACTIVE || o.state === constants_1.ORDER_STATES.PARTIAL) &&
136
+ const numSellActive = orderList.filter((o) => o.type === ORDER_TYPES.SELL &&
137
+ (o.state === ORDER_STATES.ACTIVE || o.state === ORDER_STATES.PARTIAL) &&
194
138
  o.orderId).length;
195
139
  const placedCount = numBuyActive + numSellActive;
196
140
  if (!placedCount)
@@ -221,7 +165,7 @@ function isGridBloated(manager, orders) {
221
165
  }
222
166
  }
223
167
  const railEstimate = Math.max(expectedTotal, placedCount);
224
- const buffer = (config.gridLimits?.MIN_SPREAD_ORDERS ?? constants_1.GRID_LIMITS.MIN_SPREAD_ORDERS);
168
+ const buffer = (config.gridLimits?.MIN_SPREAD_ORDERS ?? GRID_LIMITS.MIN_SPREAD_ORDERS);
225
169
  const maxAllowed = railEstimate + gapSlots + buffer;
226
170
  return {
227
171
  bloated: gridSize > maxAllowed,
@@ -241,8 +185,8 @@ function isGridBloated(manager, orders) {
241
185
  * @param {Object} manager - OrderManager instance.
242
186
  * @returns {{active: boolean, elapsed: number, graceMs: number}}
243
187
  */
244
- function isGridBloatGraceActive(manager) {
245
- const graceMs = Number(constants_1.TIMING?.GRID_BLOAT_RESYNC_GRACE_MS) || constants_1.TIMING.GRID_BLOAT_RESYNC_GRACE_MS;
188
+ export function isGridBloatGraceActive(manager) {
189
+ const graceMs = Number(TIMING?.GRID_BLOAT_RESYNC_GRACE_MS) || TIMING.GRID_BLOAT_RESYNC_GRACE_MS;
246
190
  if (!manager._gridBloatDetectedAt) {
247
191
  return { active: false, elapsed: 0, graceMs };
248
192
  }
@@ -254,7 +198,7 @@ function isGridBloatGraceActive(manager) {
254
198
  * returned to normal. Shared so both call sites use the same key.
255
199
  * @param {Object} manager - OrderManager instance.
256
200
  */
257
- function clearGridBloatFlag(manager) {
201
+ export function clearGridBloatFlag(manager) {
258
202
  delete manager._gridBloatDetectedAt;
259
203
  }
260
204
  /**
@@ -265,7 +209,7 @@ function clearGridBloatFlag(manager) {
265
209
  * @param {'buy'|'sell'} side
266
210
  * @returns {Promise<import('./types').SizingContext|null>}
267
211
  */
268
- async function getSizingContext(manager, side) {
212
+ export async function getSizingContext(manager, side) {
269
213
  return await _getSizingContext(manager, side);
270
214
  }
271
215
  /**
@@ -277,7 +221,7 @@ async function getSizingContext(manager, side) {
277
221
  * @returns {Promise<import('./types').SizingContext|null>}
278
222
  * @private
279
223
  */
280
- async function _getSizingContext(manager, side, { skipRecalc = false } = {}) {
224
+ export async function _getSizingContext(manager, side, { skipRecalc = false } = {}) {
281
225
  if (!manager || !manager.assets)
282
226
  return null;
283
227
  // 1. Ensure fund state is fresh before sizing
@@ -286,7 +230,7 @@ async function _getSizingContext(manager, side, { skipRecalc = false } = {}) {
286
230
  }
287
231
  const snap = manager.getChainFundsSnapshot ? manager.getChainFundsSnapshot() : {};
288
232
  const isBuy = side === 'buy';
289
- const type = isBuy ? constants_1.ORDER_TYPES.BUY : constants_1.ORDER_TYPES.SELL;
233
+ const type = isBuy ? ORDER_TYPES.BUY : ORDER_TYPES.SELL;
290
234
  // 2. Determine base budget: Always use ALLOCATED funds (respects botFunds %)
291
235
  // This ensures the bot only "thinks" about the capital it is allowed to use.
292
236
  let budget = isBuy ? (snap.allocatedBuy || 0) : (snap.allocatedSell || 0);
@@ -297,15 +241,15 @@ async function _getSizingContext(manager, side, { skipRecalc = false } = {}) {
297
241
  const targetBuy = Math.max(0, manager.config.activeOrders?.buy ?? 1);
298
242
  const targetSell = Math.max(0, manager.config.activeOrders?.sell ?? 1);
299
243
  const totalTarget = targetBuy + targetSell;
300
- const btsOrderType = (0, math_1.getBtsSide)(manager.config?.assetA, manager.config?.assetB);
301
- const isBtsSide = isBuy ? (btsOrderType === constants_1.ORDER_TYPES.BUY) : (btsOrderType === constants_1.ORDER_TYPES.SELL);
302
- const formulaBudget = (0, math_1.calculateOrderCreationFees)(manager.config.assetA, manager.config.assetB, totalTarget, manager.config?.feeParams?.BTS_RESERVATION_MULTIPLIER);
303
- budget = (0, math_1.adjustBudgetForBtsFees)(budget, isBtsSide, formulaBudget, manager.config.min_BTS_value || 0, Format.toFiniteNumber(manager.funds?.btsBalance?.free, 0), Format.toFiniteNumber(isBuy ? (snap.allocatedBuy || 0) : (snap.allocatedSell || 0)), Format.toFiniteNumber(snap.allocatedBuy || 0)
244
+ const btsOrderType = getBtsSide(manager.config?.assetA, manager.config?.assetB);
245
+ const isBtsSide = isBuy ? (btsOrderType === ORDER_TYPES.BUY) : (btsOrderType === ORDER_TYPES.SELL);
246
+ const formulaBudget = calculateOrderCreationFees(manager.config.assetA, manager.config.assetB, totalTarget, manager.config?.feeParams?.BTS_RESERVATION_MULTIPLIER);
247
+ budget = adjustBudgetForBtsFees(budget, isBtsSide, formulaBudget, manager.config.min_BTS_value || 0, Format.toFiniteNumber(manager.funds?.btsBalance?.free, 0), Format.toFiniteNumber(isBuy ? (snap.allocatedBuy || 0) : (snap.allocatedSell || 0)), Format.toFiniteNumber(snap.allocatedBuy || 0)
304
248
  + Format.toFiniteNumber(snap.allocatedSell || 0));
305
249
  }
306
250
  return {
307
251
  budget,
308
- precision: (0, math_1.getPrecisionByOrderType)(manager.assets, type),
252
+ precision: getPrecisionByOrderType(manager.assets, type),
309
253
  config: manager.config
310
254
  };
311
255
  }
@@ -358,7 +302,7 @@ async function _getSizingContext(manager, side, { skipRecalc = false } = {}) {
358
302
  * @param {import('./types').GridConfig} config - Grid configuration
359
303
  * @returns {import('./types').GridCreationResult}
360
304
  */
361
- function createOrderGrid(config) {
305
+ export function createOrderGrid(config) {
362
306
  const { startPrice, minPrice, maxPrice, incrementPercent } = config;
363
307
  // FIX: Add comprehensive input validation to prevent silent grid creation failures
364
308
  if (!Number.isFinite(startPrice)) {
@@ -388,7 +332,7 @@ function createOrderGrid(config) {
388
332
  // Fall back to the canonical INCREMENT_BOUNDS when the config omits
389
333
  // incrementBounds. Without this, a non-positive incrementPercent (e.g. 0)
390
334
  // silently passes validation and the geometric loop below spins forever.
391
- const incrementBounds = config.incrementBounds || constants_1.INCREMENT_BOUNDS;
335
+ const incrementBounds = config.incrementBounds || INCREMENT_BOUNDS;
392
336
  const minPercent = incrementBounds.MIN_PERCENT;
393
337
  const maxPercent = incrementBounds.MAX_PERCENT;
394
338
  if (incrementPercent <= 0 || incrementPercent < minPercent || incrementPercent > maxPercent) {
@@ -439,7 +383,7 @@ function createOrderGrid(config) {
439
383
  // Determine the boundary and assign roles (BUY/SPREAD/SELL) to each slot.
440
384
  //
441
385
  // STRATEGY: Center the spread gap around startPrice
442
- const boundaryIdx = (0, order_1.calculateIdealBoundary)(priceLevels.map((p) => ({ price: p })), startPrice, gapSlots);
386
+ const boundaryIdx = calculateIdealBoundary(priceLevels.map((p) => ({ price: p })), startPrice, gapSlots);
443
387
  // ================================================================================
444
388
  // STEP 4: CREATE ORDER OBJECTS
445
389
  // ================================================================================
@@ -448,12 +392,12 @@ function createOrderGrid(config) {
448
392
  id: `slot-${i}`,
449
393
  price,
450
394
  type: null, // assigned below
451
- state: constants_1.ORDER_STATES.VIRTUAL,
395
+ state: ORDER_STATES.VIRTUAL,
452
396
  size: 0
453
397
  }));
454
- const updatedOrders = (0, order_1.assignGridRoles)(orders, boundaryIdx, gapSlots, constants_1.ORDER_TYPES, constants_1.ORDER_STATES);
455
- const buyCount = updatedOrders.filter((o) => o.type === constants_1.ORDER_TYPES.BUY).length;
456
- const sellCount = updatedOrders.filter((o) => o.type === constants_1.ORDER_TYPES.SELL).length;
398
+ const updatedOrders = assignGridRoles(orders, boundaryIdx, gapSlots, ORDER_TYPES, ORDER_STATES);
399
+ const buyCount = updatedOrders.filter((o) => o.type === ORDER_TYPES.BUY).length;
400
+ const sellCount = updatedOrders.filter((o) => o.type === ORDER_TYPES.SELL).length;
457
401
  if (buyCount === 0 || sellCount === 0) {
458
402
  throw new Error(`Grid generation produced an imbalanced rail (buy=${buyCount}, sell=${sellCount}) for ` +
459
403
  `startPrice=${startPrice}, bounds=[${minPrice}, ${maxPrice}], incrementPercent=${incrementPercent}, ` +
@@ -503,15 +447,15 @@ function _clearOrderCachesLogic(manager) {
503
447
  * @param {number|null} [boundaryIdx=null] - The master boundary index.
504
448
  * @returns {Promise<void>}
505
449
  */
506
- async function loadGrid(manager, grid, boundaryIdx = null) {
450
+ export async function loadGrid(manager, grid, boundaryIdx = null) {
507
451
  if (!Array.isArray(grid))
508
452
  return;
509
453
  return await manager._gridLock.acquire(async () => {
510
454
  try {
511
- await (0, system_1.withBlockchainRetry)(() => manager._initializeAssets(), 'initializeAssets', { logger: manager.logger });
455
+ await withBlockchainRetry(() => manager._initializeAssets(), 'initializeAssets', { logger: manager.logger });
512
456
  }
513
457
  catch (e) {
514
- manager.logger?.log?.(`Asset initialization failed during grid load: ${(0, errors_1.getErrorMessage)(e)}`, 'warn');
458
+ manager.logger?.log?.(`Asset initialization failed during grid load: ${getErrorMessage(e)}`, 'warn');
515
459
  }
516
460
  // RC-2: Use logic helper
517
461
  _clearOrderCachesLogic(manager);
@@ -540,14 +484,14 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
540
484
  const gapSlots = calculateGapSlots(manager.config?.incrementPercent, manager.config?.targetSpreadPercent, manager.config?.gridLimits);
541
485
  manager._gapSlots = gapSlots;
542
486
  const buyEndIdx = boundaryIdx;
543
- const sellStartIdx = (0, math_1.getSellStartIdx)(boundaryIdx, gapSlots);
487
+ const sellStartIdx = getSellStartIdx(boundaryIdx, gapSlots);
544
488
  let reassignCount = 0;
545
489
  grid = grid.map((slot, i) => {
546
490
  const correctType = (i <= buyEndIdx)
547
- ? constants_1.ORDER_TYPES.BUY
491
+ ? ORDER_TYPES.BUY
548
492
  : (i >= sellStartIdx)
549
- ? constants_1.ORDER_TYPES.SELL
550
- : constants_1.ORDER_TYPES.SPREAD;
493
+ ? ORDER_TYPES.SELL
494
+ : ORDER_TYPES.SPREAD;
551
495
  // DEFENSIVE BACKSTOP: a VIRTUAL slot with no orderId and
552
496
  // zero size is side-neutral — it is a reusable placeholder
553
497
  // that may be activated on either rail. Storing a stale
@@ -562,10 +506,10 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
562
506
  // boundary-shift and strategy re-plan paths use
563
507
  // assignGridRoles (order.ts) with assignOnChain, where
564
508
  // geometry-based typing wins.
565
- if ((0, order_1.isEmptyGridSlot)(slot, slot, { allowNullType: true })) {
566
- if (slot.type !== constants_1.ORDER_TYPES.SPREAD)
509
+ if (isEmptyGridSlot(slot, slot, { allowNullType: true })) {
510
+ if (slot.type !== ORDER_TYPES.SPREAD)
567
511
  reassignCount++;
568
- return { ...slot, type: constants_1.ORDER_TYPES.SPREAD };
512
+ return { ...slot, type: ORDER_TYPES.SPREAD };
569
513
  }
570
514
  if (slot.type !== correctType) {
571
515
  let newType = correctType;
@@ -583,8 +527,8 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
583
527
  // to a number by initializeGrid), which makes every
584
528
  // comparison false and wrongly resolves below-center
585
529
  // slots to SELL.
586
- if (newType === constants_1.ORDER_TYPES.SPREAD && (0, order_1.isOrderOnChain)(slot)) {
587
- newType = (0, order_1.resolveOnChainRetypeType)(slot, i, buyEndIdx, constants_1.ORDER_TYPES);
530
+ if (newType === ORDER_TYPES.SPREAD && isOrderOnChain(slot)) {
531
+ newType = resolveOnChainRetypeType(slot, i, buyEndIdx, ORDER_TYPES);
588
532
  }
589
533
  reassignCount++;
590
534
  return { ...slot, type: newType };
@@ -612,7 +556,7 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
612
556
  manager._gridBloatDetectedAt = Date.now();
613
557
  if (typeof manager.requestStructuralGridResync === 'function') {
614
558
  manager.requestStructuralGridResync('grid-bloat-detected', { reason: `Grid size ${d.gridSize} exceeds maximum ${d.maxAllowed}` }).catch((err) => {
615
- manager.logger?.log?.(`[GRID-BLOAT] Structural resync request failed: ${(0, errors_1.getErrorMessage)(err)}`, 'error');
559
+ manager.logger?.log?.(`[GRID-BLOAT] Structural resync request failed: ${getErrorMessage(err)}`, 'error');
616
560
  });
617
561
  }
618
562
  }
@@ -623,9 +567,9 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
623
567
  // RC-2: Use applyOrderUpdate (PRIVATE/UNLOCKED)
624
568
  for (const order of grid) {
625
569
  let currentOrder = order;
626
- if ((0, order_1.isPhantomOrder)(order)) {
570
+ if (isPhantomOrder(order)) {
627
571
  manager.logger?.log?.(`Sanitizing corrupted order ${order.id}: ACTIVE/PARTIAL without orderId -> VIRTUAL`, 'warn');
628
- currentOrder = { ...order, state: constants_1.ORDER_STATES.VIRTUAL };
572
+ currentOrder = { ...order, state: ORDER_STATES.VIRTUAL };
629
573
  }
630
574
  await manager._applyOrderUpdate(currentOrder, 'grid-load', { skipAccounting: true });
631
575
  }
@@ -638,8 +582,8 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
638
582
  // at creation) so the count is order-independent, matching the
639
583
  // accountant (accounting.ts). Fall back to array position only
640
584
  // for ids that are not grid slot ids.
641
- const spreadCount = (0, math_1.countGapBandSpread)(manager, grid, (o, i) => {
642
- const idx = (0, order_1.parseSlotIndex)(o?.id);
585
+ const spreadCount = countGapBandSpread(manager, grid, (o, i) => {
586
+ const idx = parseSlotIndex(o?.id);
643
587
  return idx === null ? i : idx;
644
588
  });
645
589
  manager.initialSpreadCount = spreadCount;
@@ -652,20 +596,29 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
652
596
  manager.logger?.log?.(`Loaded ${manager.orders.size} orders from persisted grid.`, 'info');
653
597
  });
654
598
  }
599
+ function resolveMinScaleSlots(primary, secondary) {
600
+ const p = Number(primary);
601
+ if (Number.isFinite(p))
602
+ return Math.max(0, Math.floor(p));
603
+ const s = Number(secondary);
604
+ if (Number.isFinite(s))
605
+ return Math.max(0, Math.floor(s));
606
+ return MARKET_ADAPTER.ASYMMETRIC_BOUNDS_MIN_SCALE_SLOTS;
607
+ }
655
608
  /**
656
- * Initialize the order grid with blockchain-aware sizing.
657
- * @param {import('./types').OrderManager} manager - The manager instance.
658
- * @returns {Promise<void>}
659
- * @throws {Error} If initialization fails or account totals are missing.
660
- */
661
- async function initializeGrid(manager) {
609
+ * Initialize and orchestrate the order grid.
610
+ *
611
+ * @return {Promise<void>}
612
+ * @throws {Error} If initialization fails or account totals are missing.
613
+ */
614
+ export async function initializeGrid(manager) {
662
615
  if (!manager)
663
616
  throw new Error('initializeGrid requires a manager instance');
664
617
  try {
665
- await (0, system_1.withBlockchainRetry)(() => manager._initializeAssets(), 'initializeAssets', { logger: manager.logger });
618
+ await withBlockchainRetry(() => manager._initializeAssets(), 'initializeAssets', { logger: manager.logger });
666
619
  }
667
620
  catch (e) {
668
- manager.logger?.log?.(`Asset initialization failed during grid init: ${(0, errors_1.getErrorMessage)(e)}`, 'warn');
621
+ manager.logger?.log?.(`Asset initialization failed during grid init: ${getErrorMessage(e)}`, 'warn');
669
622
  }
670
623
  // FIX: Add explicit state validation to prevent cryptic errors later
671
624
  if (!manager.assets || !manager.assets.assetA || !manager.assets.assetB) {
@@ -680,7 +633,7 @@ async function initializeGrid(manager) {
680
633
  if (typeof mpRaw !== 'number' || isNaN(mpRaw)) {
681
634
  try {
682
635
  const { BitShares } = require('../bitshares_client');
683
- const derived = await (0, withPoolRef_1.derivePriceWithPoolRef)(BitShares, manager.config.assetA, manager.config.assetB, manager.config.priceMode || 'auto', manager.config.poolRef);
636
+ const derived = await derivePriceWithPoolRef(BitShares, manager.config.assetA, manager.config.assetB, manager.config.priceMode || 'auto', manager.config.poolRef);
684
637
  if (derived) {
685
638
  manager.logger?.log?.(`[DIAGNOSTIC] initializeGrid: Derived new startPrice=${derived.toFixed(8)} (mode=${manager.config.priceMode || 'auto'})`, 'info');
686
639
  manager.config.startPrice = Number(derived);
@@ -690,7 +643,7 @@ async function initializeGrid(manager) {
690
643
  }
691
644
  }
692
645
  catch (err) {
693
- manager.logger?.log?.(`Failed to derive market price: ${(0, errors_1.getErrorMessage)(err)}`, 'warn');
646
+ manager.logger?.log?.(`Failed to derive market price: ${getErrorMessage(err)}`, 'warn');
694
647
  throw err; // Re-throw to prevent "pool" string reaching numeric math
695
648
  }
696
649
  }
@@ -706,7 +659,7 @@ async function initializeGrid(manager) {
706
659
  let gp = mp;
707
660
  let gpSource = 'startPrice';
708
661
  let amaSnapshot = null;
709
- const whitelistFlags = (0, market_adapter_whitelist_1.getWhitelistFlags)(manager.config.botKey);
662
+ const whitelistFlags = getWhitelistFlags(manager.config.botKey);
710
663
  const isGridRangeScalingWhitelisted = whitelistFlags.asymmetricBounds === true;
711
664
  let gridPriceOffsetPct = 0;
712
665
  const gpRaw = manager.config.gridPrice;
@@ -719,7 +672,7 @@ async function initializeGrid(manager) {
719
672
  else if (gpMode === 'pool' || gpMode === 'book') {
720
673
  try {
721
674
  const { BitShares } = require('../bitshares_client');
722
- const derived = await (0, withPoolRef_1.derivePriceWithPoolRef)(BitShares, manager.config.assetA, manager.config.assetB, gpMode, manager.config.poolRef);
675
+ const derived = await derivePriceWithPoolRef(BitShares, manager.config.assetA, manager.config.assetB, gpMode, manager.config.poolRef);
723
676
  if (derived) {
724
677
  gp = Number(derived);
725
678
  gpSource = gpMode;
@@ -730,12 +683,12 @@ async function initializeGrid(manager) {
730
683
  }
731
684
  }
732
685
  catch (err) {
733
- manager.logger?.log?.(`initializeGrid: ${gpMode} gridPrice derivation failed: ${(0, errors_1.getErrorMessage)(err)}`, 'warn');
686
+ manager.logger?.log?.(`initializeGrid: ${gpMode} gridPrice derivation failed: ${getErrorMessage(err)}`, 'warn');
734
687
  }
735
688
  }
736
689
  else if (/^ama(?:[1-4])?$/.test(gpMode || '')) {
737
- amaSnapshot = (0, system_1.loadAmaCenterSnapshot)(manager.config.botKey);
738
- const amaCenter = amaSnapshot?.gridCenterPrice ?? (0, system_1.loadAmaCenterPrice)(manager.config.botKey);
690
+ amaSnapshot = loadAmaCenterSnapshot(manager.config.botKey);
691
+ const amaCenter = amaSnapshot?.gridCenterPrice ?? loadAmaCenterPrice(manager.config.botKey);
739
692
  if (Number.isFinite(amaCenter) && amaCenter > 0) {
740
693
  gp = amaCenter;
741
694
  gpSource = 'ama';
@@ -750,14 +703,16 @@ async function initializeGrid(manager) {
750
703
  manager.logger?.log?.(`initializeGrid: AMA center unavailable for gridPrice, falling back to startPrice`, 'warn');
751
704
  }
752
705
  }
753
- const minP = (0, order_1.resolveConfiguredPriceBound)(manager.config.minPrice, constants_1.DEFAULT_CONFIG.minPrice, gp, 'min');
754
- const maxP = (0, order_1.resolveConfiguredPriceBound)(manager.config.maxPrice, constants_1.DEFAULT_CONFIG.maxPrice, gp, 'max');
706
+ const minP = resolveConfiguredPriceBound(manager.config.minPrice, DEFAULT_CONFIG.minPrice, gp, 'min');
707
+ const maxP = resolveConfiguredPriceBound(manager.config.maxPrice, DEFAULT_CONFIG.maxPrice, gp, 'max');
755
708
  // Asymmetric bound adjustment: widen the bound in the AMA trend direction
756
709
  // and tighten the opposite side, giving the grid more room when the center
757
710
  // trails price. Uses slope data from the dynamicgrid.json snapshot.
758
711
  let resolvedMinP = minP;
759
712
  let resolvedMaxP = maxP;
760
713
  let rangeScalingFactor = null;
714
+ let appliedTrend = null;
715
+ let minScaleSlots = null;
761
716
  if (gpSource === 'ama' && Number.isFinite(minP) && Number.isFinite(maxP)
762
717
  && isGridRangeScalingWhitelisted) {
763
718
  const dw = amaSnapshot?.dynamicWeights;
@@ -768,8 +723,8 @@ async function initializeGrid(manager) {
768
723
  ? amaSnapshot.asymmetricBounds
769
724
  : null;
770
725
  if (dw) {
771
- const maxAsymmetryFactor = (0, asymmetric_bounds_1.resolveMaxAsymmetryFactor)(manager.config.asymmetricBounds?.maxAsymmetryFactor, dw?.maxAsymmetryFactor, constants_1.MARKET_ADAPTER.ASYMMETRIC_BOUNDS_MAX_ASYMMETRY_FACTOR);
772
- const adjustment = (0, asymmetric_bounds_1.applyAsymmetricBounds)({
726
+ const maxAsymmetryFactor = resolveMaxAsymmetryFactor(manager.config.asymmetricBounds?.maxAsymmetryFactor, dw?.maxAsymmetryFactor, MARKET_ADAPTER.ASYMMETRIC_BOUNDS_MAX_ASYMMETRY_FACTOR);
727
+ const adjustment = applyAsymmetricBounds({
773
728
  centerPrice: gp,
774
729
  minPrice: minP,
775
730
  maxPrice: maxP,
@@ -782,6 +737,8 @@ async function initializeGrid(manager) {
782
737
  resolvedMinP = adjustment.resolvedMinPrice;
783
738
  resolvedMaxP = adjustment.resolvedMaxPrice;
784
739
  rangeScalingFactor = Number(adjustment.appliedAsymmetryFactor);
740
+ appliedTrend = (dw?.trend === 'UP' || dw?.trend === 'DOWN') ? dw.trend : null;
741
+ minScaleSlots = resolveMinScaleSlots(manager.config.asymmetricBounds?.minScaleSlots, dw?.minScaleSlots);
785
742
  manager.logger?.log?.(`[BOUND-ASYMMETRY] trend=${dw.trend} slopeOffset=${dw.slopeOffset.toFixed(4)} `
786
743
  + `raw=${((adjustment.rawAsymmetryFactor ?? 0) * 100).toFixed(1)}% `
787
744
  + `cap=${((maxAsymmetryFactor ?? 0) * 100).toFixed(0)}% `
@@ -803,6 +760,8 @@ async function initializeGrid(manager) {
803
760
  resolvedMaxP = gp * ((maxP / gp) * (1 + asymmetry));
804
761
  }
805
762
  rangeScalingFactor = asymmetry;
763
+ appliedTrend = rootTrend;
764
+ minScaleSlots = resolveMinScaleSlots(manager.config.asymmetricBounds?.minScaleSlots, rootBounds.minScaleSlots);
806
765
  manager.logger?.log?.(`[BOUND-ASYMMETRY] trend=${rootTrend} `
807
766
  + `asymmetry=${(asymmetry * 100).toFixed(1)}% `
808
767
  + `(root-level) min ${(minP ?? 0).toFixed(8)}→${(resolvedMinP ?? 0).toFixed(8)} `
@@ -831,6 +790,35 @@ async function initializeGrid(manager) {
831
790
  gridStartPrice = clamped;
832
791
  }
833
792
  }
793
+ // Narrowing-side slot guard: range scaling tightens one bound toward the
794
+ // center. Without a floor this can collapse that side into a near-center
795
+ // sliver holding few or zero active orders. Guarantee at least
796
+ // minScaleSlots price levels remain between the grid center and the
797
+ // tightened bound (in multiples of incrementPercent). The widened side
798
+ // still extends freely.
799
+ if (appliedTrend && Number.isFinite(gridStartPrice) && gridStartPrice > 0) {
800
+ const inc = Number(manager.config.incrementPercent);
801
+ const mss = Number.isFinite(minScaleSlots) ? Math.floor(Number(minScaleSlots)) : 0;
802
+ if (Number.isFinite(inc) && inc > 0 && mss > 0) {
803
+ const stepMult = 1 + (inc / 100);
804
+ if (appliedTrend === 'DOWN' && resolvedMaxP != null) {
805
+ const keepAbove = gridStartPrice * Math.pow(stepMult, mss);
806
+ if (resolvedMaxP < keepAbove) {
807
+ manager.logger?.log?.(`[BOUND-ASYMMETRY] narrowing-side guard: max ${resolvedMaxP.toFixed(8)} collapses ` +
808
+ `${mss} levels; holding at ${keepAbove.toFixed(8)}`, 'info');
809
+ resolvedMaxP = keepAbove;
810
+ }
811
+ }
812
+ else if (appliedTrend === 'UP' && resolvedMinP != null) {
813
+ const belowMin = gridStartPrice * Math.pow(1 - (inc / 100), mss);
814
+ if (resolvedMinP > belowMin) {
815
+ manager.logger?.log?.(`[BOUND-ASYMMETRY] narrowing-side guard would pull min ${resolvedMinP.toFixed(8)} ` +
816
+ `short of ${mss} levels; holding at ${belowMin.toFixed(8)}`, 'info');
817
+ resolvedMinP = belowMin;
818
+ }
819
+ }
820
+ }
821
+ }
834
822
  manager.config.minPrice = resolvedMinP;
835
823
  manager.config.maxPrice = resolvedMaxP;
836
824
  manager._lastGridPricingContext = {
@@ -845,14 +833,14 @@ async function initializeGrid(manager) {
845
833
  // Ensure percentage-based funds are resolved before sizing
846
834
  try {
847
835
  if (manager.accountId && !manager.accountTotals) {
848
- await manager.waitForAccountTotals(constants_1.TIMING.ACCOUNT_TOTALS_TIMEOUT_MS);
836
+ await manager.waitForAccountTotals(TIMING.ACCOUNT_TOTALS_TIMEOUT_MS);
849
837
  }
850
838
  }
851
839
  catch (e) {
852
- manager.logger?.log?.(`Failed to load account totals: ${(0, errors_1.getErrorMessage)(e)}`, 'warn');
840
+ manager.logger?.log?.(`Failed to load account totals: ${getErrorMessage(e)}`, 'warn');
853
841
  // FIX: Add error handling - cannot proceed with grid initialization without account totals
854
842
  // Continuing would create grid with 0 fund allocation, rendering it non-functional
855
- throw new Error(`Cannot initialize grid without account totals: ${(0, errors_1.getErrorMessage)(e)}`);
843
+ throw new Error(`Cannot initialize grid without account totals: ${getErrorMessage(e)}`);
856
844
  }
857
845
  const { orders, boundaryIdx, initialSpreadCount, gapSlots } = createOrderGrid({
858
846
  ...manager.config,
@@ -871,13 +859,13 @@ async function initializeGrid(manager) {
871
859
  manager.notifyBoundaryUpdate(boundaryIdx);
872
860
  }
873
861
  catch (err) {
874
- manager.logger?.log?.(`Error notifying boundary update: ${(0, errors_1.getErrorMessage)(err)}`, 'warn');
862
+ manager.logger?.log?.(`Error notifying boundary update: ${getErrorMessage(err)}`, 'warn');
875
863
  }
876
864
  }
877
865
  }
878
- const minSellSize = (0, math_1.getMinAbsoluteOrderSize)(constants_1.ORDER_TYPES.SELL, manager.assets);
879
- const minBuySize = (0, math_1.getMinAbsoluteOrderSize)(constants_1.ORDER_TYPES.BUY, manager.assets);
880
- const { A: precA, B: precB } = (0, math_1.getPrecisionsForManager)(manager.assets);
866
+ const minSellSize = getMinAbsoluteOrderSize(ORDER_TYPES.SELL, manager.assets);
867
+ const minBuySize = getMinAbsoluteOrderSize(ORDER_TYPES.BUY, manager.assets);
868
+ const { A: precA, B: precB } = getPrecisionsForManager(manager.assets);
881
869
  // Use centralized sizing context for both sides.
882
870
  // Resolve funds once upfront so both contexts share the same snapshot,
883
871
  // avoiding a redundant recalculateFunds inside the second _getSizingContext call.
@@ -886,17 +874,17 @@ async function initializeGrid(manager) {
886
874
  const buyCtx = await _getSizingContext(manager, 'buy', { skipRecalc: true });
887
875
  if (!sellCtx || !buyCtx)
888
876
  throw new Error('Failed to retrieve sizing context for grid initialization');
889
- let sizedOrders = (0, math_1.calculateOrderSizes)(orders, manager.config, sellCtx.budget, buyCtx.budget, minSellSize, minBuySize, precA, precB);
877
+ let sizedOrders = calculateOrderSizes(orders, manager.config, sellCtx.budget, buyCtx.budget, minSellSize, minBuySize, precA, precB);
890
878
  // Verification of sizes
891
- const sells = (0, order_1.filterOrdersByType)(sizedOrders, constants_1.ORDER_TYPES.SELL).map((o) => Number(o.size || 0));
892
- const buys = (0, order_1.filterOrdersByType)(sizedOrders, constants_1.ORDER_TYPES.BUY).map((o) => Number(o.size || 0));
893
- if ((0, order_1.checkSizesBeforeMinimum)(sells, minSellSize, precA) || (0, order_1.checkSizesBeforeMinimum)(buys, minBuySize, precB)) {
879
+ const sells = filterOrdersByType(sizedOrders, ORDER_TYPES.SELL).map((o) => Number(o.size || 0));
880
+ const buys = filterOrdersByType(sizedOrders, ORDER_TYPES.BUY).map((o) => Number(o.size || 0));
881
+ if (checkSizesBeforeMinimum(sells, minSellSize, precA) || checkSizesBeforeMinimum(buys, minBuySize, precB)) {
894
882
  throw new Error('Calculated orders fall below minimum allowable size.');
895
883
  }
896
884
  // Check for warning if orders are near minimal size (regression fix)
897
- const warningSellSize = minSellSize > 0 ? (0, math_1.getMinAbsoluteOrderSize)(constants_1.ORDER_TYPES.SELL, manager.assets, 100) : 0;
898
- const warningBuySize = minBuySize > 0 ? (0, math_1.getMinAbsoluteOrderSize)(constants_1.ORDER_TYPES.BUY, manager.assets, 100) : 0;
899
- if ((0, order_1.checkSizeThreshold)(sells, warningSellSize, precA, false) || (0, order_1.checkSizeThreshold)(buys, warningBuySize, precB, false)) {
885
+ const warningSellSize = minSellSize > 0 ? getMinAbsoluteOrderSize(ORDER_TYPES.SELL, manager.assets, 100) : 0;
886
+ const warningBuySize = minBuySize > 0 ? getMinAbsoluteOrderSize(ORDER_TYPES.BUY, manager.assets, 100) : 0;
887
+ if (checkSizeThreshold(sells, warningSellSize, precA, false) || checkSizeThreshold(buys, warningBuySize, precB, false)) {
900
888
  manager.logger?.log?.("WARNING: Order grid contains orders near minimum size. To ensure the bot runs properly, consider increasing the funds of your bot.", "warn");
901
889
  }
902
890
  // RC-2: Wrap atomic changes in grid lock
@@ -941,13 +929,13 @@ async function initializeGrid(manager) {
941
929
  * @param {string} opts.privateKey - Private key.
942
930
  * @returns {Promise<void>}
943
931
  */
944
- async function recalculateGrid(manager, opts) {
932
+ export async function recalculateGrid(manager, opts) {
945
933
  const { readOpenOrdersFn, chainOrders, account, privateKey } = opts;
946
934
  // Suppress invariant warnings during full resync
947
935
  manager.startBootstrap();
948
936
  // Total timeout across all steps — prevents indefinite hang even if
949
937
  // an individual withBlockchainRetry step pins the event loop.
950
- const totalTimeoutMs = constants_1.PIPELINE_TIMING.TIMEOUT_MS * 2; // 10 min
938
+ const totalTimeoutMs = PIPELINE_TIMING.TIMEOUT_MS * 2; // 10 min
951
939
  let _resyncAborted = false;
952
940
  const work = (async () => {
953
941
  try {
@@ -956,24 +944,24 @@ async function recalculateGrid(manager, opts) {
956
944
  return;
957
945
  // #1: Initialize assets with timeout + retry + node failover
958
946
  try {
959
- await (0, system_1.withBlockchainRetry)(() => manager._initializeAssets(), 'initializeAssets', { logger: manager.logger });
947
+ await withBlockchainRetry(() => manager._initializeAssets(), 'initializeAssets', { logger: manager.logger });
960
948
  }
961
949
  catch (e) {
962
- manager.logger?.log?.(`Asset initialization failed during resync: ${(0, errors_1.getErrorMessage)(e)}`, 'warn');
950
+ manager.logger?.log?.(`Asset initialization failed during resync: ${getErrorMessage(e)}`, 'warn');
963
951
  }
964
952
  if (_resyncAborted)
965
953
  return;
966
954
  // #2: Fetch account totals with timeout + retry + node failover
967
- await (0, system_1.withBlockchainRetry)(() => manager.fetchAccountTotals(), 'fetchAccountTotals', { logger: manager.logger });
955
+ await withBlockchainRetry(() => manager.fetchAccountTotals(), 'fetchAccountTotals', { logger: manager.logger });
968
956
  if (_resyncAborted)
969
957
  return;
970
958
  // #3: Read open orders with timeout + retry + node failover
971
- const chainOpenOrders = await (0, system_1.withBlockchainRetry)(() => readOpenOrdersFn(), 'readOpenOrders', { logger: manager.logger });
959
+ const chainOpenOrders = await withBlockchainRetry(() => readOpenOrdersFn(), 'readOpenOrders', { logger: manager.logger });
972
960
  if (_resyncAborted)
973
961
  return;
974
962
  if (!Array.isArray(chainOpenOrders))
975
963
  return;
976
- await (0, system_1.withBlockchainRetry)(() => manager.syncFromOpenOrders(chainOpenOrders, { skipAccounting: true }), 'syncFromOpenOrders', { logger: manager.logger });
964
+ await withBlockchainRetry(() => manager.syncFromOpenOrders(chainOpenOrders, { skipAccounting: true }), 'syncFromOpenOrders', { logger: manager.logger });
977
965
  if (_resyncAborted)
978
966
  return;
979
967
  // resetFunds under _fundLock + snapshot; persistGrid outside lock to
@@ -1013,8 +1001,8 @@ async function recalculateGrid(manager, opts) {
1013
1001
  await reconcileGridOrders({ manager, config: manager.config, account, privateKey, chainOrders, chainOpenOrders });
1014
1002
  }
1015
1003
  catch (err) {
1016
- manager.logger?.log?.(`Error during startup order reconciliation: ${(0, errors_1.getErrorMessage)(err)}`, 'error');
1017
- throw new Error(`Grid recalculation failed during order reconciliation: ${(0, errors_1.getErrorMessage)(err)}`);
1004
+ manager.logger?.log?.(`Error during startup order reconciliation: ${getErrorMessage(err)}`, 'error');
1005
+ throw new Error(`Grid recalculation failed during order reconciliation: ${getErrorMessage(err)}`);
1018
1006
  }
1019
1007
  if (_resyncAborted)
1020
1008
  return;
@@ -1045,20 +1033,20 @@ async function recalculateGrid(manager, opts) {
1045
1033
  * @param {import('./types').OrderManager} manager - Manager instance with order state
1046
1034
  * @returns {import('./types').SideUpdateFlags}
1047
1035
  */
1048
- function checkAndUpdateGridIfNeeded(manager) {
1036
+ export function checkAndUpdateGridIfNeeded(manager) {
1049
1037
  const threshold = manager.config?.gridLimits?.GRID_REGENERATION_PERCENTAGE;
1050
1038
  const chainSnap = manager.getChainFundsSnapshot();
1051
1039
  const gridBuy = Number(manager.funds?.total?.grid?.buy || 0);
1052
1040
  const gridSell = Number(manager.funds?.total?.grid?.sell || 0);
1053
1041
  const result = { buyUpdated: false, sellUpdated: false };
1054
1042
  const sides = [
1055
- { name: 'buy', grid: gridBuy, orderType: constants_1.ORDER_TYPES.BUY },
1056
- { name: 'sell', grid: gridSell, orderType: constants_1.ORDER_TYPES.SELL }
1043
+ { name: 'buy', grid: gridBuy, orderType: ORDER_TYPES.BUY },
1044
+ { name: 'sell', grid: gridSell, orderType: ORDER_TYPES.SELL }
1057
1045
  ];
1058
1046
  for (const s of sides) {
1059
1047
  if (s.grid <= 0)
1060
1048
  continue;
1061
- const availableFunds = (0, math_1.calculateAvailableFundsValue)(s.name, manager.accountTotals, manager.funds, manager.config.assetA, manager.config.assetB, manager.config.activeOrders, manager.config.min_BTS_value, manager.config.feeParams ?? null);
1049
+ const availableFunds = calculateAvailableFundsValue(s.name, manager.accountTotals, manager.funds, manager.config.assetA, manager.config.assetB, manager.config.activeOrders, manager.config.min_BTS_value, manager.config.feeParams ?? null);
1062
1050
  // Denominator: side's allocated capital (or chain total fallback).
1063
1051
  const allocated = s.name === 'buy' ? chainSnap.allocatedBuy : chainSnap.allocatedSell;
1064
1052
  const denominator = (allocated > 0) ? allocated : (s.grid + availableFunds);
@@ -1128,16 +1116,16 @@ function checkAndUpdateGridIfNeeded(manager) {
1128
1116
  * @param {import('./types').OrderManager} manager - OrderManager instance
1129
1117
  * @param {string} orderType - ORDER_TYPES.BUY or ORDER_TYPES.SELL
1130
1118
  * @param {Object} [options] - Options object
1131
- * @param {import('./working_grid')} [options.workingGrid] - Working grid for COW pattern
1119
+ * @param {import('./working_grid.js')} [options.workingGrid] - Working grid for COW pattern
1132
1120
  * @returns {Promise<{actions: Array, changed: boolean}|undefined>} - COW result or undefined
1133
1121
  * @private
1134
1122
  */
1135
- async function _recalculateGridOrderSizesFromBlockchain(manager, orderType, options = {}) {
1123
+ export async function _recalculateGridOrderSizesFromBlockchain(manager, orderType, options = {}) {
1136
1124
  if (!manager.assets)
1137
1125
  return options?.workingGrid ? { actions: [], changed: false } : undefined;
1138
1126
  const workingGrid = options?.workingGrid || null;
1139
1127
  const collectActions = !!workingGrid;
1140
- const isBuy = orderType === constants_1.ORDER_TYPES.BUY;
1128
+ const isBuy = orderType === ORDER_TYPES.BUY;
1141
1129
  const sideName = isBuy ? 'buy' : 'sell';
1142
1130
  // Use centralized sizing context (respects botFunds % allocation)
1143
1131
  const ctx = await _getSizingContext(manager, sideName);
@@ -1173,7 +1161,7 @@ async function _recalculateGridOrderSizesFromBlockchain(manager, orderType, opti
1173
1161
  if (allSideSlots.length === 0)
1174
1162
  return collectActions ? { actions: [], changed: false } : undefined;
1175
1163
  // Calculate geometric sizes for the ENTIRE rail
1176
- const newSizes = (0, math_1.calculateRotationOrderSizes)(ctx.budget, 0, allSideSlots.length, orderType, manager.config, 0, ctx.precision);
1164
+ const newSizes = calculateRotationOrderSizes(ctx.budget, 0, allSideSlots.length, orderType, manager.config, 0, ctx.precision);
1177
1165
  const actions = [];
1178
1166
  let changed = false;
1179
1167
  const freeKey = isBuy ? 'buyFree' : 'sellFree';
@@ -1192,7 +1180,7 @@ async function _recalculateGridOrderSizesFromBlockchain(manager, orderType, opti
1192
1180
  // NOTE: BTS update fees are paid from BTS balance (separate from asset balance),
1193
1181
  // so they don't affect this asset-side size cap. Fee budgets are tracked in
1194
1182
  // funds.btsFeesOwed and reserved separately via btsFeesReservation.
1195
- const isCommitted = (0, order_1.isOrderOnChain)(slot);
1183
+ const isCommitted = isOrderOnChain(slot);
1196
1184
  if (isCommitted) {
1197
1185
  const currentSize = Number(slot.size || 0);
1198
1186
  const delta = newSize - currentSize;
@@ -1212,8 +1200,8 @@ async function _recalculateGridOrderSizesFromBlockchain(manager, orderType, opti
1212
1200
  }
1213
1201
  }
1214
1202
  // Use integer comparison to avoid redundant updates from float noise
1215
- const currentSizeInt = (0, math_1.floatToBlockchainInt)(slot.size || 0, ctx.precision);
1216
- const newSizeInt = (0, math_1.floatToBlockchainInt)(newSize, ctx.precision);
1203
+ const currentSizeInt = floatToBlockchainInt(slot.size || 0, ctx.precision);
1204
+ const newSizeInt = floatToBlockchainInt(newSize, ctx.precision);
1217
1205
  if (slot.size === undefined || currentSizeInt !== newSizeInt) {
1218
1206
  changed = true;
1219
1207
  if (collectActions) {
@@ -1221,9 +1209,9 @@ async function _recalculateGridOrderSizesFromBlockchain(manager, orderType, opti
1221
1209
  ...slot,
1222
1210
  size: newSize
1223
1211
  });
1224
- if (isCommitted && (0, order_1.hasOnChainId)(slot)) {
1212
+ if (isCommitted && hasOnChainId(slot)) {
1225
1213
  actions.push({
1226
- type: constants_1.COW_ACTIONS.UPDATE,
1214
+ type: COW_ACTIONS.UPDATE,
1227
1215
  id: slot.id,
1228
1216
  orderId: slot.orderId,
1229
1217
  newGridId: slot.id,
@@ -1269,9 +1257,9 @@ async function _recalculateGridOrderSizesFromBlockchain(manager, orderType, opti
1269
1257
  * @param {string} orderType - 'buy', 'sell', or 'both' - which sides to update
1270
1258
  * @param {boolean} [fromBlockchainTimer=false] - If true, skip refetch of account totals (already current)
1271
1259
  * @param {number|null} [overrideBoundaryIdx=null] - Optional override for boundary index
1272
- * @returns {Promise<{actions: Array, workingGrid: import('./working_grid'), workingIndexes: Object, workingBoundary: number, hasWorkingChanges: boolean, aborted: boolean}|null>}
1260
+ * @returns {Promise<{actions: Array, workingGrid: import('./working_grid.js'), workingIndexes: Object, workingBoundary: number, hasWorkingChanges: boolean, aborted: boolean}|null>}
1273
1261
  */
1274
- async function updateGridFromBlockchainSnapshot(manager, orderType = 'both', fromBlockchainTimer = false, overrideBoundaryIdx = null) {
1262
+ export async function updateGridFromBlockchainSnapshot(manager, orderType = 'both', fromBlockchainTimer = false, overrideBoundaryIdx = null) {
1275
1263
  if (!fromBlockchainTimer && manager.config?.accountId) {
1276
1264
  await manager.fetchAccountTotals(manager.config.accountId);
1277
1265
  }
@@ -1297,7 +1285,7 @@ async function updateGridFromBlockchainSnapshot(manager, orderType = 'both', fro
1297
1285
  const allSlots = Array.from(workingGrid.values())
1298
1286
  .filter((s) => s.price != null)
1299
1287
  .sort((a, b) => a.price - b.price);
1300
- const updatedSlots = (0, order_1.assignGridRoles)(allSlots, newBoundary, gapSlots, constants_1.ORDER_TYPES, constants_1.ORDER_STATES, { assignOnChain: true });
1288
+ const updatedSlots = assignGridRoles(allSlots, newBoundary, gapSlots, ORDER_TYPES, ORDER_STATES, { assignOnChain: true });
1301
1289
  for (const slot of updatedSlots) {
1302
1290
  workingGrid.set(slot.id, slot);
1303
1291
  }
@@ -1306,13 +1294,13 @@ async function updateGridFromBlockchainSnapshot(manager, orderType = 'both', fro
1306
1294
  // Calculate size updates for each side (via existing sizing function in COW mode).
1307
1295
  // _recalculateGridOrderSizesFromBlockchain reads types from the working grid when
1308
1296
  // one is passed, so boundary-crossing slots are now correctly classified.
1309
- if (orderType === constants_1.ORDER_TYPES.BUY || orderType === 'both') {
1310
- const buyResult = await _recalculateGridOrderSizesFromBlockchain(manager, constants_1.ORDER_TYPES.BUY, { workingGrid });
1297
+ if (orderType === ORDER_TYPES.BUY || orderType === 'both') {
1298
+ const buyResult = await _recalculateGridOrderSizesFromBlockchain(manager, ORDER_TYPES.BUY, { workingGrid });
1311
1299
  allActions.push(...buyResult.actions);
1312
1300
  hasWorkingChanges = hasWorkingChanges || buyResult.changed;
1313
1301
  }
1314
- if (orderType === constants_1.ORDER_TYPES.SELL || orderType === 'both') {
1315
- const sellResult = await _recalculateGridOrderSizesFromBlockchain(manager, constants_1.ORDER_TYPES.SELL, { workingGrid });
1302
+ if (orderType === ORDER_TYPES.SELL || orderType === 'both') {
1303
+ const sellResult = await _recalculateGridOrderSizesFromBlockchain(manager, ORDER_TYPES.SELL, { workingGrid });
1316
1304
  allActions.push(...sellResult.actions);
1317
1305
  hasWorkingChanges = hasWorkingChanges || sellResult.changed;
1318
1306
  }
@@ -1358,7 +1346,7 @@ async function updateGridFromBlockchainSnapshot(manager, orderType = 'both', fro
1358
1346
  * @param {import('./types').OrderManager|null} [manager=null] - Manager instance (for grid lock access)
1359
1347
  * @returns {Promise<import('./types').GridComparisonResult>}
1360
1348
  */
1361
- async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1349
+ export async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1362
1350
  if (!Array.isArray(calculatedGrid) || !Array.isArray(persistedGrid)) {
1363
1351
  return { buy: { metric: 0, updated: false }, sell: { metric: 0, updated: false } };
1364
1352
  }
@@ -1381,14 +1369,14 @@ async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1381
1369
  // they are instead handled by the available-funds ratio check or follow-up correction.
1382
1370
  // Must be sorted ASC for calculateRotationOrderSizes to match geometric weight distribution
1383
1371
  const filterForRms = (orders, type) => {
1384
- const result = Array.isArray(orders) ? orders.filter((o) => o && o.type === type && o.state === constants_1.ORDER_STATES.ACTIVE) : [];
1372
+ const result = Array.isArray(orders) ? orders.filter((o) => o && o.type === type && o.state === ORDER_STATES.ACTIVE) : [];
1385
1373
  return result
1386
1374
  .sort((a, b) => (a.price ?? 0) - (b.price ?? 0));
1387
1375
  };
1388
- const calculatedBuys = filterForRms(calculatedSnap, constants_1.ORDER_TYPES.BUY);
1389
- const calculatedSells = filterForRms(calculatedSnap, constants_1.ORDER_TYPES.SELL);
1390
- const persistedBuys = filterForRms(persistedSnap, constants_1.ORDER_TYPES.BUY);
1391
- const persistedSells = filterForRms(persistedSnap, constants_1.ORDER_TYPES.SELL);
1376
+ const calculatedBuys = filterForRms(calculatedSnap, ORDER_TYPES.BUY);
1377
+ const calculatedSells = filterForRms(calculatedSnap, ORDER_TYPES.SELL);
1378
+ const persistedBuys = filterForRms(persistedSnap, ORDER_TYPES.BUY);
1379
+ const persistedSells = filterForRms(persistedSnap, ORDER_TYPES.SELL);
1392
1380
  // Calculate ideal sizes for each order based on current available budget.
1393
1381
  // The sizing context (which includes recalculateFunds) is resolved once per side up front
1394
1382
  // so both buy and sell metrics share a single fund snapshot. This avoids the previous
@@ -1411,7 +1399,7 @@ async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1411
1399
  return activeOrders;
1412
1400
  // Calculate geometric ideals for the ENTIRE side (all slots)
1413
1401
  try {
1414
- const allIdealSizes = (0, math_1.calculateRotationOrderSizes)(ctx.budget, 0, sideSlots.length, type, manager.config, 0, ctx.precision);
1402
+ const allIdealSizes = calculateRotationOrderSizes(ctx.budget, 0, sideSlots.length, type, manager.config, 0, ctx.precision);
1415
1403
  // Map Ideal sizes to IDs for quick lookup
1416
1404
  const idealMap = new Map();
1417
1405
  sideSlots.forEach((slot, i) => idealMap.set(slot.id, allIdealSizes[i]));
@@ -1433,11 +1421,11 @@ async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1433
1421
  const sellCtx = needsSell
1434
1422
  ? await _getSizingContext(manager, 'sell', { skipRecalc: true })
1435
1423
  : null;
1436
- const buyIdeals = computeSideIdeals(calculatedBuys, constants_1.ORDER_TYPES.BUY, buyCtx);
1437
- const sellIdeals = computeSideIdeals(calculatedSells, constants_1.ORDER_TYPES.SELL, sellCtx);
1424
+ const buyIdeals = computeSideIdeals(calculatedBuys, ORDER_TYPES.BUY, buyCtx);
1425
+ const sellIdeals = computeSideIdeals(calculatedSells, ORDER_TYPES.SELL, sellCtx);
1438
1426
  // Calculate RMS divergence metric for each side
1439
- const buyMetric = (0, math_1.calculateGridSideDivergenceMetric)(buyIdeals, persistedBuys, 'buy');
1440
- const sellMetric = (0, math_1.calculateGridSideDivergenceMetric)(sellIdeals, persistedSells, 'sell');
1427
+ const buyMetric = calculateGridSideDivergenceMetric(buyIdeals, persistedBuys, 'buy');
1428
+ const sellMetric = calculateGridSideDivergenceMetric(sellIdeals, persistedSells, 'sell');
1441
1429
  // Check if metrics exceed threshold and flag sides for regeneration
1442
1430
  // Set RMS_PERCENTAGE to 0 to disable RMS divergence checks
1443
1431
  let buyUpdated = false, sellUpdated = false;
@@ -1447,14 +1435,14 @@ async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1447
1435
  // RC-3: Use Set for automatic duplicate prevention
1448
1436
  if (!(manager._gridSidesUpdated instanceof Set))
1449
1437
  manager._gridSidesUpdated = new Set();
1450
- manager._gridSidesUpdated.add(constants_1.ORDER_TYPES.BUY);
1438
+ manager._gridSidesUpdated.add(ORDER_TYPES.BUY);
1451
1439
  buyUpdated = true;
1452
1440
  }
1453
1441
  if (sellMetric > limit) {
1454
1442
  // RC-3: Use Set for automatic duplicate prevention
1455
1443
  if (!(manager._gridSidesUpdated instanceof Set))
1456
1444
  manager._gridSidesUpdated = new Set();
1457
- manager._gridSidesUpdated.add(constants_1.ORDER_TYPES.SELL);
1445
+ manager._gridSidesUpdated.add(ORDER_TYPES.SELL);
1458
1446
  sellUpdated = true;
1459
1447
  }
1460
1448
  }
@@ -1473,7 +1461,7 @@ async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1473
1461
  * @param {Array<import('./types').GridOrderSlot>} persistedGrid - Current/persisted grid
1474
1462
  * @returns {Promise<import('./types').DivergenceResult>}
1475
1463
  */
1476
- async function monitorDivergence(manager, calculatedGrid, persistedGrid) {
1464
+ export async function monitorDivergence(manager, calculatedGrid, persistedGrid) {
1477
1465
  // 1. Check ratio-based divergence (available funds vs allocated)
1478
1466
  const ratioResult = checkAndUpdateGridIfNeeded(manager);
1479
1467
  if (ratioResult.buyUpdated || ratioResult.sellUpdated) {
@@ -1505,12 +1493,12 @@ async function monitorDivergence(manager, calculatedGrid, persistedGrid) {
1505
1493
  */
1506
1494
  function _getOnChainOrders(manager) {
1507
1495
  const onChainBuys = [
1508
- ...manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.BUY, constants_1.ORDER_STATES.ACTIVE),
1509
- ...manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.BUY, constants_1.ORDER_STATES.PARTIAL)
1496
+ ...manager.getOrdersByTypeAndState(ORDER_TYPES.BUY, ORDER_STATES.ACTIVE),
1497
+ ...manager.getOrdersByTypeAndState(ORDER_TYPES.BUY, ORDER_STATES.PARTIAL)
1510
1498
  ].filter((o) => o?.orderId && Number(o?.size || 0) > 0);
1511
1499
  const onChainSells = [
1512
- ...manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.SELL, constants_1.ORDER_STATES.ACTIVE),
1513
- ...manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.SELL, constants_1.ORDER_STATES.PARTIAL)
1500
+ ...manager.getOrdersByTypeAndState(ORDER_TYPES.SELL, ORDER_STATES.ACTIVE),
1501
+ ...manager.getOrdersByTypeAndState(ORDER_TYPES.SELL, ORDER_STATES.PARTIAL)
1514
1502
  ].filter((o) => o?.orderId && Number(o?.size || 0) > 0);
1515
1503
  return { onChainBuys, onChainSells };
1516
1504
  }
@@ -1519,9 +1507,9 @@ function _getOnChainOrders(manager) {
1519
1507
  * @param {import('./types').OrderManager} manager - The manager instance.
1520
1508
  * @returns {number} The calculated spread percentage.
1521
1509
  */
1522
- function calculateCurrentSpread(manager) {
1510
+ export function calculateCurrentSpread(manager) {
1523
1511
  const { onChainBuys, onChainSells } = _getOnChainOrders(manager);
1524
- return (0, math_1.calculateSpreadFromOrders)(onChainBuys, onChainSells);
1512
+ return calculateSpreadFromOrders(onChainBuys, onChainSells);
1525
1513
  }
1526
1514
  /**
1527
1515
  * Proactive spread correction check.
@@ -1546,7 +1534,7 @@ function calculateCurrentSpread(manager) {
1546
1534
  * @param {Function|null} [updateOrdersOnChainBatch=null] - Optional batch update function
1547
1535
  * @returns {Promise<import('./types').SpreadCheckResult>}
1548
1536
  */
1549
- async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatch = null) {
1537
+ export async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatch = null) {
1550
1538
  // CRITICAL: Acquire corrections lock to serialize spread correction operations
1551
1539
  // This prevents concurrent fill processing from modifying funds while we're making decisions
1552
1540
  let correction = null;
@@ -1560,7 +1548,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1560
1548
  // Mid between best bid and best ask is the most current price the bot has.
1561
1549
  // Falls back to config.startPrice when either side is empty (e.g. at startup).
1562
1550
  const { onChainBuys, onChainSells } = _getOnChainOrders(manager);
1563
- const { bestBuy, bestSell } = (0, math_1.getGridBestPrices)(onChainBuys, onChainSells);
1551
+ const { bestBuy, bestSell } = getGridBestPrices(onChainBuys, onChainSells);
1564
1552
  const lastPrice = (bestBuy !== null && bestSell !== null)
1565
1553
  ? (bestBuy + bestSell) / 2
1566
1554
  : Number(manager.config.startPrice) || 0;
@@ -1578,18 +1566,18 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1578
1566
  const currentSpread = calculateCurrentSpread(manager);
1579
1567
  // Nominal spread is the configured target spread percentage.
1580
1568
  // Keep this fixed: doubled-side flags are fill/replacement mechanics only.
1581
- const nominalSpread = manager.config.targetSpreadPercent ?? constants_1.DEFAULT_CONFIG.targetSpreadPercent;
1569
+ const nominalSpread = manager.config.targetSpreadPercent ?? DEFAULT_CONFIG.targetSpreadPercent;
1582
1570
  // Fixed tolerance: 0.5 steps = half increment (tighter spread check).
1583
1571
  const toleranceSteps = 0.5;
1584
- const buyCount = manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.BUY, constants_1.ORDER_STATES.ACTIVE)
1585
- .concat(manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.BUY, constants_1.ORDER_STATES.PARTIAL))
1572
+ const buyCount = manager.getOrdersByTypeAndState(ORDER_TYPES.BUY, ORDER_STATES.ACTIVE)
1573
+ .concat(manager.getOrdersByTypeAndState(ORDER_TYPES.BUY, ORDER_STATES.PARTIAL))
1586
1574
  .filter((o) => o?.orderId && Number(o?.size || 0) > 0)
1587
1575
  .length;
1588
- const sellCount = manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.SELL, constants_1.ORDER_STATES.ACTIVE)
1589
- .concat(manager.getOrdersByTypeAndState(constants_1.ORDER_TYPES.SELL, constants_1.ORDER_STATES.PARTIAL))
1576
+ const sellCount = manager.getOrdersByTypeAndState(ORDER_TYPES.SELL, ORDER_STATES.ACTIVE)
1577
+ .concat(manager.getOrdersByTypeAndState(ORDER_TYPES.SELL, ORDER_STATES.PARTIAL))
1590
1578
  .filter((o) => o?.orderId && Number(o?.size || 0) > 0)
1591
1579
  .length;
1592
- manager.outOfSpread = (0, order_1.shouldFlagOutOfSpread)(currentSpread, nominalSpread, toleranceSteps, buyCount, sellCount, manager.config.incrementPercent);
1580
+ manager.outOfSpread = shouldFlagOutOfSpread(currentSpread, nominalSpread, toleranceSteps, buyCount, sellCount, manager.config.incrementPercent);
1593
1581
  if (manager.outOfSpread === 0)
1594
1582
  return false;
1595
1583
  // Check whether the empty side is caused by boundary-at-rail-edge.
@@ -1605,7 +1593,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1605
1593
  const gapSlots = manager._gapSlots ?? calculateGapSlots(manager.config.incrementPercent, manager.config.targetSpreadPercent, manager.config.gridLimits);
1606
1594
  const railLen = allSlots.length;
1607
1595
  const buyEndIdx = manager.boundaryIdx;
1608
- const sellStartIdx = (0, math_1.getSellStartIdx)(manager.boundaryIdx, gapSlots);
1596
+ const sellStartIdx = getSellStartIdx(manager.boundaryIdx, gapSlots);
1609
1597
  const buySideCount = Math.max(0, Math.min(railLen, buyEndIdx + 1));
1610
1598
  const sellSideCount = Math.max(0, railLen - sellStartIdx);
1611
1599
  // Structural resync: both sides have room but one is empty.
@@ -1619,7 +1607,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1619
1607
  `Requesting structural grid resync to re-center.`, 'warn');
1620
1608
  if (typeof manager.requestStructuralGridResync === 'function') {
1621
1609
  manager.requestStructuralGridResync('boundary-at-rail-edge', { reason: `Boundary ${manager.boundaryIdx} leaves ${buySideCount} buy / ${sellSideCount} sell slots` }).catch((err) => {
1622
- manager.logger?.log?.(`[SPREAD] Structural resync request failed: ${(0, errors_1.getErrorMessage)(err)}`, 'error');
1610
+ manager.logger?.log?.(`[SPREAD] Structural resync request failed: ${getErrorMessage(err)}`, 'error');
1623
1611
  });
1624
1612
  }
1625
1613
  }
@@ -1639,7 +1627,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1639
1627
  // STARVATION FALLBACK: If the selected side has no correctable slots (e.g.
1640
1628
  // all SPREAD slots already filled or misaligned), try the opposite side.
1641
1629
  if ((placeCount + updateCount) === 0) {
1642
- const oppositeSide = decision.side === constants_1.ORDER_TYPES.BUY ? constants_1.ORDER_TYPES.SELL : constants_1.ORDER_TYPES.BUY;
1630
+ const oppositeSide = decision.side === ORDER_TYPES.BUY ? ORDER_TYPES.SELL : ORDER_TYPES.BUY;
1643
1631
  manager.logger?.log?.(`[SPREAD] Side ${decision.side} produced zero candidates; ` +
1644
1632
  `trying opposite side ${oppositeSide}.`, 'debug');
1645
1633
  const oppositeCorrection = await prepareSpreadCorrectionOrders(manager, oppositeSide, manager.outOfSpread);
@@ -1657,7 +1645,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1657
1645
  shouldApplyCorrection = await manager._gridLock.acquire(executeSpreadCheck);
1658
1646
  }
1659
1647
  catch (err) {
1660
- manager.logger?.log?.(`Error checking spread condition: ${(0, errors_1.getErrorMessage)(err)}`, 'error');
1648
+ manager.logger?.log?.(`Error checking spread condition: ${getErrorMessage(err)}`, 'error');
1661
1649
  // Track failure in recovery state for external monitoring.
1662
1650
  // Do NOT throw — the startup runtime path lacks a try/catch and
1663
1651
  // a throw would crash startup. The error is symptom of a deeper
@@ -1688,7 +1676,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1688
1676
  // Refresh lastPrice from current grid state — the grid may
1689
1677
  // have changed since function entry (TOCTOU).
1690
1678
  const freshOnChain = _getOnChainOrders(manager);
1691
- const freshBest = (0, math_1.getGridBestPrices)(freshOnChain.onChainBuys, freshOnChain.onChainSells);
1679
+ const freshBest = getGridBestPrices(freshOnChain.onChainBuys, freshOnChain.onChainSells);
1692
1680
  const freshPrice = (freshBest.bestBuy !== null && freshBest.bestSell !== null)
1693
1681
  ? (freshBest.bestBuy + freshBest.bestSell) / 2
1694
1682
  : Number(manager.config.startPrice) || 0;
@@ -1722,7 +1710,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1722
1710
  return { ordersPlaced: placed + updated, partialsMoved: updated };
1723
1711
  }
1724
1712
  catch (err) {
1725
- manager.logger?.log?.(`Error applying spread correction on-chain: ${(0, errors_1.getErrorMessage)(err)}`, 'warn');
1713
+ manager.logger?.log?.(`Error applying spread correction on-chain: ${getErrorMessage(err)}`, 'warn');
1726
1714
  return { ordersPlaced: 0, partialsMoved: 0 };
1727
1715
  }
1728
1716
  }
@@ -1741,7 +1729,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1741
1729
  * @param {Function|null} [updateOrdersOnChainBatch=null] - Optional batch update function.
1742
1730
  * @returns {Promise<import('./types').DustCheckResult>}
1743
1731
  */
1744
- async function checkGridHealth(manager, _updateOrdersOnChainBatch = null) {
1732
+ export async function checkGridHealth(manager, _updateOrdersOnChainBatch = null) {
1745
1733
  if (!manager)
1746
1734
  return { buyDust: false, sellDust: false, buyDustOrders: [], sellDustOrders: [] };
1747
1735
  // Skip health checks during bootstrap to prevent spamming warnings
@@ -1767,25 +1755,25 @@ async function checkGridHealth(manager, _updateOrdersOnChainBatch = null) {
1767
1755
  * the sibling active order already covers that price level.
1768
1756
  *
1769
1757
  * Returns boolean flags plus the actual dust order objects so callers can act
1770
- * on individual orders (e.g. DUST_CANCEL_DELAY_SEC auto-cancel).
1758
+ * on individual orders (dust is cancelled immediately on detection).
1771
1759
  *
1772
1760
  * @param {import('./types').OrderManager} manager
1773
1761
  * @returns {Promise<import('./types').DustCheckResult>}
1774
1762
  */
1775
- async function checkWindowDust(manager) {
1763
+ export async function checkWindowDust(manager) {
1776
1764
  if (!manager)
1777
1765
  return { buyDust: false, sellDust: false, buyDustOrders: [], sellDustOrders: [] };
1778
1766
  const allOrders = Array.from(manager.orders.values());
1779
1767
  const isLiveOrder = (order) => order &&
1780
1768
  order.orderId &&
1781
1769
  order.price != null &&
1782
- (order.state === constants_1.ORDER_STATES.ACTIVE || order.state === constants_1.ORDER_STATES.PARTIAL);
1770
+ (order.state === ORDER_STATES.ACTIVE || order.state === ORDER_STATES.PARTIAL);
1783
1771
  // Identify top-of-window orders (closest to market per side).
1784
1772
  const topBuyOrder = allOrders
1785
- .filter((o) => o.type === constants_1.ORDER_TYPES.BUY && isLiveOrder(o))
1773
+ .filter((o) => o.type === ORDER_TYPES.BUY && isLiveOrder(o))
1786
1774
  .sort((a, b) => b.price - a.price)[0];
1787
1775
  const topSellOrder = allOrders
1788
- .filter((o) => o.type === constants_1.ORDER_TYPES.SELL && isLiveOrder(o))
1776
+ .filter((o) => o.type === ORDER_TYPES.SELL && isLiveOrder(o))
1789
1777
  .sort((a, b) => a.price - b.price)[0];
1790
1778
  // Check if an order has a duplicate price level — an active sibling at the
1791
1779
  // same price within tolerance. If so, cancelling won't create a grid gap.
@@ -1793,17 +1781,17 @@ async function checkWindowDust(manager) {
1793
1781
  // sibling, neither qualifies and the gap is left to the rebalancer.
1794
1782
  // Uses the LARGER size of the two orders for tolerance calculation to prevent
1795
1783
  // a tiny dust order from inflating the tolerance window.
1796
- const hasDuplicatePriceLevel = (order, assets) => (0, math_1.findPriceCollision)(allOrders, order.id, order.price, order.size, order.type, assets, (o) => o.type === order.type && o.state === constants_1.ORDER_STATES.ACTIVE && !!o.orderId && o.price != null) != null;
1784
+ const hasDuplicatePriceLevel = (order, assets) => findPriceCollision(allOrders, order.id, order.price, order.size, order.type, assets, (o) => o.type === order.type && o.state === ORDER_STATES.ACTIVE && !!o.orderId && o.price != null) != null;
1797
1785
  const assets = manager.assets;
1798
- const allPartials = allOrders.filter((o) => isLiveOrder(o) && o.state === constants_1.ORDER_STATES.PARTIAL);
1786
+ const allPartials = allOrders.filter((o) => isLiveOrder(o) && o.state === ORDER_STATES.PARTIAL);
1799
1787
  const isTopBuy = (o) => topBuyOrder && o.id === topBuyOrder.id;
1800
1788
  const isTopSell = (o) => topSellOrder && o.id === topSellOrder.id;
1801
1789
  // Safety filter: top-of-window partials always qualify; interior partials
1802
1790
  // only qualify if they have a duplicate price level (no gap risk).
1803
- const eligibleBuyPartials = allPartials.filter((o) => o.type === constants_1.ORDER_TYPES.BUY && (isTopBuy(o) || hasDuplicatePriceLevel(o, assets)));
1804
- const eligibleSellPartials = allPartials.filter((o) => o.type === constants_1.ORDER_TYPES.SELL && (isTopSell(o) || hasDuplicatePriceLevel(o, assets)));
1805
- const buyDustOrders = await _getDustOrders(manager, eligibleBuyPartials, constants_1.ORDER_TYPES.BUY);
1806
- const sellDustOrders = await _getDustOrders(manager, eligibleSellPartials, constants_1.ORDER_TYPES.SELL);
1791
+ const eligibleBuyPartials = allPartials.filter((o) => o.type === ORDER_TYPES.BUY && (isTopBuy(o) || hasDuplicatePriceLevel(o, assets)));
1792
+ const eligibleSellPartials = allPartials.filter((o) => o.type === ORDER_TYPES.SELL && (isTopSell(o) || hasDuplicatePriceLevel(o, assets)));
1793
+ const buyDustOrders = await _getDustOrders(manager, eligibleBuyPartials, ORDER_TYPES.BUY);
1794
+ const sellDustOrders = await _getDustOrders(manager, eligibleSellPartials, ORDER_TYPES.SELL);
1807
1795
  return {
1808
1796
  buyDust: buyDustOrders.length > 0,
1809
1797
  sellDust: sellDustOrders.length > 0,
@@ -1824,7 +1812,7 @@ async function checkWindowDust(manager) {
1824
1812
  async function _getDustOrders(manager, partials, type) {
1825
1813
  if (!partials || partials.length === 0)
1826
1814
  return [];
1827
- const side = type === constants_1.ORDER_TYPES.BUY ? 'buy' : 'sell';
1815
+ const side = type === ORDER_TYPES.BUY ? 'buy' : 'sell';
1828
1816
  const ctx = await _getSizingContext(manager, side);
1829
1817
  const dustThresholdPercent = manager.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE;
1830
1818
  const sideSlots = Array.from(manager.orders.values())
@@ -1833,7 +1821,7 @@ async function _getDustOrders(manager, partials, type) {
1833
1821
  if (sideSlots.length === 0)
1834
1822
  return [];
1835
1823
  const idealSizes = ctx && ctx.budget > 0
1836
- ? (0, math_1.allocateFundsByWeights)(ctx.budget, sideSlots.length, manager.config.weightDistribution[side], manager.config.incrementPercent / 100, type === constants_1.ORDER_TYPES.BUY, 0, ctx.precision)
1824
+ ? allocateFundsByWeights(ctx.budget, sideSlots.length, manager.config.weightDistribution[side], manager.config.incrementPercent / 100, type === ORDER_TYPES.BUY, 0, ctx.precision)
1837
1825
  : [];
1838
1826
  // When no budget is available, idealSizes becomes [] so every
1839
1827
  // partial's threshold collapses to 0 — no order qualifies as dust.
@@ -1844,7 +1832,7 @@ async function _getDustOrders(manager, partials, type) {
1844
1832
  if (idx === -1)
1845
1833
  return false;
1846
1834
  const threshold = idealSizes.length > idx && idealSizes[idx] > 0
1847
- ? (0, math_1.getSingleDustThreshold)(idealSizes[idx], dustThresholdPercent)
1835
+ ? getSingleDustThreshold(idealSizes[idx], dustThresholdPercent)
1848
1836
  : 0;
1849
1837
  return p.size < threshold;
1850
1838
  });
@@ -1867,8 +1855,8 @@ async function _hasAnyDust(manager, partials, type) {
1867
1855
  * @param {'buy'|'sell'} side
1868
1856
  * @returns {Promise<boolean>}
1869
1857
  */
1870
- async function hasAnyDust(manager, partials, side) {
1871
- const type = side === 'buy' ? constants_1.ORDER_TYPES.BUY : side === 'sell' ? constants_1.ORDER_TYPES.SELL : null;
1858
+ export async function hasAnyDust(manager, partials, side) {
1859
+ const type = side === 'buy' ? ORDER_TYPES.BUY : side === 'sell' ? ORDER_TYPES.SELL : null;
1872
1860
  if (!type)
1873
1861
  return false;
1874
1862
  return await _hasAnyDust(manager, partials, type);
@@ -1881,8 +1869,8 @@ async function hasAnyDust(manager, partials, side) {
1881
1869
  * @param {'buy'|'sell'} side
1882
1870
  * @returns {Promise<Array<import('./types').GridOrderSlot>>}
1883
1871
  */
1884
- async function getDustOrders(manager, partials, side) {
1885
- const type = side === 'buy' ? constants_1.ORDER_TYPES.BUY : side === 'sell' ? constants_1.ORDER_TYPES.SELL : null;
1872
+ export async function getDustOrders(manager, partials, side) {
1873
+ const type = side === 'buy' ? ORDER_TYPES.BUY : side === 'sell' ? ORDER_TYPES.SELL : null;
1886
1874
  if (!type)
1887
1875
  return [];
1888
1876
  return await _getDustOrders(manager, partials, type);
@@ -1894,7 +1882,7 @@ async function getDustOrders(manager, partials, side) {
1894
1882
  * normalize sell-side funds into buy-side units for a fair cross-asset comparison.
1895
1883
  * @returns {{ side: import('./types').OrderType|null, reason: string }} The side to correct on, or null if insufficient funds.
1896
1884
  */
1897
- function determineOrderSideByFunds(manager, currentMarketPrice) {
1885
+ export function determineOrderSideByFunds(manager, currentMarketPrice) {
1898
1886
  const buyAvailable = Math.min(Number(manager.funds?.available?.buy || 0), Number(manager.accountTotals?.buyFree || 0));
1899
1887
  const sellAvailable = Math.min(Number(manager.funds?.available?.sell || 0), Number(manager.accountTotals?.sellFree || 0));
1900
1888
  // Need at least some funds on a side to justify correction
@@ -1916,13 +1904,13 @@ function determineOrderSideByFunds(manager, currentMarketPrice) {
1916
1904
  const sellInBuyUnits = (Number.isFinite(marketPrice) && marketPrice > 0)
1917
1905
  ? sellAvailable * marketPrice
1918
1906
  : sellAvailable;
1919
- side = buyAvailable >= sellInBuyUnits ? constants_1.ORDER_TYPES.BUY : constants_1.ORDER_TYPES.SELL;
1907
+ side = buyAvailable >= sellInBuyUnits ? ORDER_TYPES.BUY : ORDER_TYPES.SELL;
1920
1908
  }
1921
1909
  else if (buyViable) {
1922
- side = constants_1.ORDER_TYPES.BUY;
1910
+ side = ORDER_TYPES.BUY;
1923
1911
  }
1924
1912
  else if (sellViable) {
1925
- side = constants_1.ORDER_TYPES.SELL;
1913
+ side = ORDER_TYPES.SELL;
1926
1914
  }
1927
1915
  if (!side) {
1928
1916
  const committedBuy = Math.max(0, Number(manager.funds?.committed?.chain?.buy || 0));
@@ -1933,17 +1921,17 @@ function determineOrderSideByFunds(manager, currentMarketPrice) {
1933
1921
  if (hasValidPrice) {
1934
1922
  const buyComparable = committedBuy;
1935
1923
  const sellComparable = committedSell * marketPrice;
1936
- side = buyComparable >= sellComparable ? constants_1.ORDER_TYPES.BUY : constants_1.ORDER_TYPES.SELL;
1924
+ side = buyComparable >= sellComparable ? ORDER_TYPES.BUY : ORDER_TYPES.SELL;
1937
1925
  }
1938
1926
  else if (committedBuy > buyMinUnit && committedSell <= sellMinUnit) {
1939
- side = constants_1.ORDER_TYPES.BUY;
1927
+ side = ORDER_TYPES.BUY;
1940
1928
  }
1941
1929
  else if (committedSell > sellMinUnit && committedBuy <= buyMinUnit) {
1942
- side = constants_1.ORDER_TYPES.SELL;
1930
+ side = ORDER_TYPES.SELL;
1943
1931
  }
1944
1932
  else {
1945
1933
  // Deterministic fallback when both sides hold inventory but market valuation is unavailable.
1946
- side = constants_1.ORDER_TYPES.BUY;
1934
+ side = ORDER_TYPES.BUY;
1947
1935
  }
1948
1936
  manager.logger?.log?.(`Spread correction using redistribution fallback on ${side} ` +
1949
1937
  `(free buy=${Format.formatAmount8(buyAvailable)}, free sell=${Format.formatAmount8(sellAvailable)}, ` +
@@ -1970,7 +1958,7 @@ function determineOrderSideByFunds(manager, currentMarketPrice) {
1970
1958
  // the band, so this cap only binds when the opposite rail is smaller than the
1971
1959
  // band — i.e. an empty opposite rail (cap 0) blocks promotion entirely.
1972
1960
  function _collectPromotableBoundarySlots(allSlotsByPrice, railType, buyEndIdx, sellStartIdx, quota) {
1973
- const isBuy = railType === constants_1.ORDER_TYPES.BUY;
1961
+ const isBuy = railType === ORDER_TYPES.BUY;
1974
1962
  const maxIdx = allSlotsByPrice.length - 1;
1975
1963
  const maxPromotable = isBuy
1976
1964
  ? Math.max(0, maxIdx + 1 - sellStartIdx)
@@ -1980,7 +1968,7 @@ function _collectPromotableBoundarySlots(allSlotsByPrice, railType, buyEndIdx, s
1980
1968
  const step = isBuy ? 1 : -1;
1981
1969
  for (let idx = isBuy ? buyEndIdx + 1 : sellStartIdx - 1; promoted.length < promotionQuota && (isBuy ? idx < sellStartIdx : idx > buyEndIdx); idx += step) {
1982
1970
  const slot = allSlotsByPrice[idx];
1983
- if (!slot || !(0, order_1.isSlotAvailable)(slot))
1971
+ if (!slot || !isSlotAvailable(slot))
1984
1972
  break;
1985
1973
  promoted.push(slot);
1986
1974
  }
@@ -1993,15 +1981,15 @@ function _collectPromotableBoundarySlots(allSlotsByPrice, railType, buyEndIdx, s
1993
1981
  * @returns {Promise<import('./types').SpreadCorrectionResult>}
1994
1982
  * @throws {Error} If preferredSide is invalid.
1995
1983
  */
1996
- async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread = 0) {
1984
+ export async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread = 0) {
1997
1985
  // FIX: Validate preferredSide parameter to prevent silent logic errors
1998
- if (preferredSide !== constants_1.ORDER_TYPES.BUY && preferredSide !== constants_1.ORDER_TYPES.SELL) {
1999
- throw new Error(`Invalid preferredSide: ${preferredSide}. Must be '${constants_1.ORDER_TYPES.BUY}' or '${constants_1.ORDER_TYPES.SELL}'.`);
1986
+ if (preferredSide !== ORDER_TYPES.BUY && preferredSide !== ORDER_TYPES.SELL) {
1987
+ throw new Error(`Invalid preferredSide: ${preferredSide}. Must be '${ORDER_TYPES.BUY}' or '${ORDER_TYPES.SELL}'.`);
2000
1988
  }
2001
1989
  const ordersToPlace = [];
2002
1990
  const ordersToUpdate = [];
2003
1991
  const railType = preferredSide;
2004
- const sideName = railType === constants_1.ORDER_TYPES.BUY ? 'buy' : 'sell';
1992
+ const sideName = railType === ORDER_TYPES.BUY ? 'buy' : 'sell';
2005
1993
  const configuredMissingSlots = Number(outOfSpread || 0);
2006
1994
  const missingSlots = configuredMissingSlots > 0
2007
1995
  ? Math.floor(configuredMissingSlots)
@@ -2030,7 +2018,7 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2030
2018
  // spread correction cycle will re-classify with the updated committed value.
2031
2019
  // This prevents TOCTOU-style inconsistency where slot types are chosen
2032
2020
  // against a boundary that was never atomically committed to manager.orders.
2033
- const resolved = (0, math_1.resolveGapBand)(manager);
2021
+ const resolved = resolveGapBand(manager);
2034
2022
  const gapSlots = resolved.gapSlots;
2035
2023
  const boundaryKnown = resolved.boundaryIdx !== null && resolved.sellStartIdx !== null;
2036
2024
  // NOTE: `?? 0` keeps the legacy classification fallback (boundary not
@@ -2039,22 +2027,22 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2039
2027
  // `boundaryKnown` below: deriving a new boundary from a fabricated 0 would
2040
2028
  // silently commit a boundary that was never real.
2041
2029
  const buyEndIdx = resolved.boundaryIdx ?? 0;
2042
- const sellStartIdx = resolved.sellStartIdx ?? (0, math_1.getSellStartIdx)(buyEndIdx, gapSlots);
2030
+ const sellStartIdx = resolved.sellStartIdx ?? getSellStartIdx(buyEndIdx, gapSlots);
2043
2031
  const getSlotCorrectType = (slot) => {
2044
2032
  const idx = slotIndexMap.get(slot.id);
2045
2033
  if (idx === undefined)
2046
2034
  return slot.type;
2047
2035
  if (idx <= buyEndIdx)
2048
- return constants_1.ORDER_TYPES.BUY;
2036
+ return ORDER_TYPES.BUY;
2049
2037
  if (idx >= sellStartIdx)
2050
- return constants_1.ORDER_TYPES.SELL;
2051
- return constants_1.ORDER_TYPES.SPREAD;
2038
+ return ORDER_TYPES.SELL;
2039
+ return ORDER_TYPES.SPREAD;
2052
2040
  };
2053
2041
  let edgePartial = null;
2054
2042
  const partials = allOrders
2055
2043
  .filter((o) => getSlotCorrectType(o) === railType
2056
- && o.state === constants_1.ORDER_STATES.PARTIAL)
2057
- .sort((a, b) => railType === constants_1.ORDER_TYPES.BUY ? b.price - a.price : a.price - b.price);
2044
+ && o.state === ORDER_STATES.PARTIAL)
2045
+ .sort((a, b) => railType === ORDER_TYPES.BUY ? b.price - a.price : a.price - b.price);
2058
2046
  if (partials.length > 0) {
2059
2047
  edgePartial = partials[0];
2060
2048
  manager.logger?.log?.(`[SPREAD-CORRECTION] Identified partial order at ${edgePartial.price} for update`, 'debug');
@@ -2064,10 +2052,10 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2064
2052
  // in the BUY or SELL zone is excluded — it would otherwise be placed on the
2065
2053
  // correction side at a price the grid already considers the opposite side.
2066
2054
  const typedSpreadCandidates = allOrders
2067
- .filter((o) => o.type === constants_1.ORDER_TYPES.SPREAD
2068
- && (0, order_1.isSlotAvailable)(o)
2055
+ .filter((o) => o.type === ORDER_TYPES.SPREAD
2056
+ && isSlotAvailable(o)
2069
2057
  && getSlotCorrectType(o) === railType)
2070
- .sort((a, b) => railType === constants_1.ORDER_TYPES.BUY ? a.price - b.price : b.price - a.price)
2058
+ .sort((a, b) => railType === ORDER_TYPES.BUY ? a.price - b.price : b.price - a.price)
2071
2059
  .slice(0, missingSlots);
2072
2060
  // Secondary candidates: orphaned virtual slots that have lost their
2073
2061
  // order (e.g. stale-cleaned after a race condition during a crash).
@@ -2082,12 +2070,12 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2082
2070
  // NOT re-activated on the stale side — doing so would compound inventory
2083
2071
  // at prices where the bot already traded.
2084
2072
  const orphanedVirtualCandidates = allOrders
2085
- .filter((o) => (o.type === railType || o.type === constants_1.ORDER_TYPES.SPREAD)
2086
- && o.state === constants_1.ORDER_STATES.VIRTUAL
2073
+ .filter((o) => (o.type === railType || o.type === ORDER_TYPES.SPREAD)
2074
+ && o.state === ORDER_STATES.VIRTUAL
2087
2075
  && !o.orderId
2088
2076
  && Number(o.size || 0) === 0
2089
2077
  && getSlotCorrectType(o) === railType)
2090
- .sort((a, b) => railType === constants_1.ORDER_TYPES.BUY ? b.price - a.price : a.price - b.price)
2078
+ .sort((a, b) => railType === ORDER_TYPES.BUY ? b.price - a.price : a.price - b.price)
2091
2079
  .slice(0, missingSlots);
2092
2080
  // If the funded rail is full, the spread itself may be stale: the
2093
2081
  // nearest empty slots are still in the gap band. Promote contiguous
@@ -2141,8 +2129,8 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2141
2129
  return false;
2142
2130
  // Resolve candidate size: if zero/missing, use minimum so tolerance
2143
2131
  // doesn't collapse to zero (calculatePriceTolerance returns null for size <= 0).
2144
- const cs = (c.size && c.size > 0) ? c.size : (0, math_1.getMinAbsoluteOrderSize)(railType, manager.assets);
2145
- return !(0, math_1.findPriceCollision)(allOrders, c.id, c.price, cs, railType, manager.assets, (o) => (0, order_1.isOrderPlaced)(o) && o.price != null);
2132
+ const cs = (c.size && c.size > 0) ? c.size : getMinAbsoluteOrderSize(railType, manager.assets);
2133
+ return !findPriceCollision(allOrders, c.id, c.price, cs, railType, manager.assets, (o) => isOrderPlaced(o) && o.price != null);
2146
2134
  });
2147
2135
  const filteredCount = preFilter - spreadCandidates.length;
2148
2136
  if (filteredCount > 0) {
@@ -2168,14 +2156,14 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2168
2156
  if (!ctx || ctx.budget <= 0 || syntheticSideSlots.length === 0) {
2169
2157
  return { ordersToPlace: [], ordersToUpdate: [] };
2170
2158
  }
2171
- const precisionEpsilon = (0, math_1.getPrecisionSlack)(ctx.precision, 1);
2172
- const idealSizes = (0, math_1.allocateFundsByWeights)(ctx.budget, syntheticSideSlots.length, manager.config.weightDistribution[sideName], manager.config.incrementPercent / 100, railType === constants_1.ORDER_TYPES.BUY, 0, ctx.precision);
2159
+ const precisionEpsilon = getPrecisionSlack(ctx.precision, 1);
2160
+ const idealSizes = allocateFundsByWeights(ctx.budget, syntheticSideSlots.length, manager.config.weightDistribution[sideName], manager.config.incrementPercent / 100, railType === ORDER_TYPES.BUY, 0, ctx.precision);
2173
2161
  const idealById = new Map();
2174
2162
  syntheticSideSlots.forEach((slot, idx) => {
2175
2163
  idealById.set(slot.id, Number(idealSizes[idx] || 0));
2176
2164
  });
2177
2165
  const availableFund = Math.max(0, Math.min(Number(manager.funds?.available?.[sideName] || 0), Number(sideName === 'buy' ? manager.accountTotals?.buyFree : manager.accountTotals?.sellFree) || 0));
2178
- const minAbsoluteSize = (0, math_1.getMinAbsoluteOrderSize)(railType, manager.assets);
2166
+ const minAbsoluteSize = getMinAbsoluteOrderSize(railType, manager.assets);
2179
2167
  const prioritizedTargets = [];
2180
2168
  if (edgePartial && edgePartial.id) {
2181
2169
  const ideal = Number(idealById.get(edgePartial.id) || 0);
@@ -2211,9 +2199,9 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2211
2199
  if (totalNeeded > availableFund + precisionEpsilon) {
2212
2200
  let shortfall = totalNeeded - availableFund;
2213
2201
  const donors = sideSlots
2214
- .filter((o) => (0, order_1.hasOnChainId)(o) && (o.state === constants_1.ORDER_STATES.ACTIVE || o.state === constants_1.ORDER_STATES.PARTIAL))
2202
+ .filter((o) => hasOnChainId(o) && (o.state === ORDER_STATES.ACTIVE || o.state === ORDER_STATES.PARTIAL))
2215
2203
  .filter((o) => !edgePartial || o.id !== edgePartial.id)
2216
- .sort((a, b) => railType === constants_1.ORDER_TYPES.BUY ? a.price - b.price : b.price - a.price);
2204
+ .sort((a, b) => railType === ORDER_TYPES.BUY ? a.price - b.price : b.price - a.price);
2217
2205
  for (const donor of donors) {
2218
2206
  if (shortfall <= precisionEpsilon)
2219
2207
  break;
@@ -2227,7 +2215,7 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2227
2215
  const donorNext = donorCurrent - reduction;
2228
2216
  if (donorNext <= precisionEpsilon)
2229
2217
  continue;
2230
- if (!(0, order_1.isOrderHealthy)(donorNext, railType, manager.assets, donorIdeal || donorNext))
2218
+ if (!isOrderHealthy(donorNext, railType, manager.assets, donorIdeal || donorNext))
2231
2219
  continue;
2232
2220
  redistributionUpdates.push({ partialOrder: { ...donor }, newSize: donorNext });
2233
2221
  recoveredBudget += reduction;
@@ -2244,7 +2232,7 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2244
2232
  if (target.kind === 'partial-topup') {
2245
2233
  const topUp = Math.min(target.needed, remainingBudget);
2246
2234
  const newSize = target.current + topUp;
2247
- if (newSize > target.current + precisionEpsilon && (0, order_1.isOrderHealthy)(newSize, railType, manager.assets, target.ideal)) {
2235
+ if (newSize > target.current + precisionEpsilon && isOrderHealthy(newSize, railType, manager.assets, target.ideal)) {
2248
2236
  ordersToUpdate.push({ partialOrder: { ...target.order }, newSize });
2249
2237
  remainingBudget -= topUp;
2250
2238
  }
@@ -2253,13 +2241,13 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2253
2241
  const createSize = Math.min(target.ideal, remainingBudget);
2254
2242
  if (createSize <= precisionEpsilon)
2255
2243
  continue;
2256
- if (!(0, order_1.isOrderHealthy)(createSize, railType, manager.assets, target.ideal))
2244
+ if (!isOrderHealthy(createSize, railType, manager.assets, target.ideal))
2257
2245
  continue;
2258
2246
  ordersToPlace.push({
2259
2247
  ...target.order,
2260
2248
  type: railType,
2261
2249
  size: createSize,
2262
- state: constants_1.ORDER_STATES.VIRTUAL
2250
+ state: ORDER_STATES.VIRTUAL
2263
2251
  });
2264
2252
  remainingBudget -= createSize;
2265
2253
  }
@@ -2276,14 +2264,14 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread
2276
2264
  const idx = slotIndexMap.get(id);
2277
2265
  if (idx === undefined)
2278
2266
  continue;
2279
- const dist = railType === constants_1.ORDER_TYPES.BUY
2267
+ const dist = railType === ORDER_TYPES.BUY
2280
2268
  ? idx - buyEndIdx
2281
2269
  : sellStartIdx - idx;
2282
2270
  if (dist > maxDist)
2283
2271
  maxDist = dist;
2284
2272
  }
2285
2273
  if (maxDist > 0) {
2286
- boundaryIdx = railType === constants_1.ORDER_TYPES.BUY
2274
+ boundaryIdx = railType === ORDER_TYPES.BUY
2287
2275
  ? buyEndIdx + maxDist
2288
2276
  : buyEndIdx - maxDist;
2289
2277
  const maxIdx = allSlotsByPrice.length - 1;