dexbot 1.3.3 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (736) hide show
  1. package/dist/analysis/chart_utils.d.ts +11 -9
  2. package/dist/analysis/chart_utils.d.ts.map +1 -1
  3. package/dist/analysis/chart_utils.js +21 -16
  4. package/dist/analysis/chart_utils.js.map +1 -1
  5. package/dist/analysis/math_utils.d.ts +4 -13
  6. package/dist/analysis/math_utils.d.ts.map +1 -1
  7. package/dist/analysis/math_utils.js +16 -18
  8. package/dist/analysis/math_utils.js.map +1 -1
  9. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +3 -7
  10. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -1
  11. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +38 -34
  12. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -1
  13. package/dist/analysis/trend_detection/hurst_analyzer.d.ts +1 -4
  14. package/dist/analysis/trend_detection/hurst_analyzer.d.ts.map +1 -1
  15. package/dist/analysis/trend_detection/hurst_analyzer.js +10 -7
  16. package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -1
  17. package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts +6 -6
  18. package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts.map +1 -1
  19. package/dist/analysis/trend_detection/kalman_trend_analyzer.js +23 -15
  20. package/dist/analysis/trend_detection/kalman_trend_analyzer.js.map +1 -1
  21. package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts +12 -13
  22. package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts.map +1 -1
  23. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js +16 -16
  24. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js.map +1 -1
  25. package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts +1 -4
  26. package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts.map +1 -1
  27. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js +10 -7
  28. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js.map +1 -1
  29. package/dist/bot.d.ts.map +1 -1
  30. package/dist/bot.js +6 -13
  31. package/dist/bot.js.map +1 -1
  32. package/dist/credential-daemon.d.ts.map +1 -1
  33. package/dist/credential-daemon.js +21 -22
  34. package/dist/credential-daemon.js.map +1 -1
  35. package/dist/dexbot.d.ts.map +1 -1
  36. package/dist/dexbot.js +16 -15
  37. package/dist/dexbot.js.map +1 -1
  38. package/dist/market_adapter/ama_signal_runner.d.ts +1 -1
  39. package/dist/market_adapter/ama_signal_runner.d.ts.map +1 -1
  40. package/dist/market_adapter/ama_signal_runner.js +8 -20
  41. package/dist/market_adapter/ama_signal_runner.js.map +1 -1
  42. package/dist/market_adapter/candle_utils.d.ts +2 -10
  43. package/dist/market_adapter/candle_utils.d.ts.map +1 -1
  44. package/dist/market_adapter/candle_utils.js +7 -8
  45. package/dist/market_adapter/candle_utils.js.map +1 -1
  46. package/dist/market_adapter/core/asymmetric_bounds.d.ts +12 -7
  47. package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -1
  48. package/dist/market_adapter/core/asymmetric_bounds.js +4 -5
  49. package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -1
  50. package/dist/market_adapter/core/config_normalizers.d.ts +4 -9
  51. package/dist/market_adapter/core/config_normalizers.d.ts.map +1 -1
  52. package/dist/market_adapter/core/config_normalizers.js +9 -9
  53. package/dist/market_adapter/core/config_normalizers.js.map +1 -1
  54. package/dist/market_adapter/core/kibana_candles.d.ts +16 -20
  55. package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -1
  56. package/dist/market_adapter/core/kibana_candles.js +16 -15
  57. package/dist/market_adapter/core/kibana_candles.js.map +1 -1
  58. package/dist/market_adapter/core/kibana_client.d.ts +8 -11
  59. package/dist/market_adapter/core/kibana_client.d.ts.map +1 -1
  60. package/dist/market_adapter/core/kibana_client.js +13 -11
  61. package/dist/market_adapter/core/kibana_client.js.map +1 -1
  62. package/dist/market_adapter/core/kibana_market_candles.d.ts +5 -12
  63. package/dist/market_adapter/core/kibana_market_candles.d.ts.map +1 -1
  64. package/dist/market_adapter/core/kibana_market_candles.js +12 -21
  65. package/dist/market_adapter/core/kibana_market_candles.js.map +1 -1
  66. package/dist/market_adapter/core/market_adapter_service.d.ts +75 -53
  67. package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -1
  68. package/dist/market_adapter/core/market_adapter_service.js +102 -98
  69. package/dist/market_adapter/core/market_adapter_service.js.map +1 -1
  70. package/dist/market_adapter/core/strategies/ama.d.ts +21 -1
  71. package/dist/market_adapter/core/strategies/ama.d.ts.map +1 -1
  72. package/dist/market_adapter/core/strategies/ama.js +10 -10
  73. package/dist/market_adapter/core/strategies/ama.js.map +1 -1
  74. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts +7 -11
  75. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts.map +1 -1
  76. package/dist/market_adapter/core/strategies/ama_slope_model.js +23 -30
  77. package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -1
  78. package/dist/market_adapter/core/strategies/atr/calculator.d.ts +5 -4
  79. package/dist/market_adapter/core/strategies/atr/calculator.d.ts.map +1 -1
  80. package/dist/market_adapter/core/strategies/atr/calculator.js +5 -3
  81. package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -1
  82. package/dist/market_adapter/core/strategies/collateral_manager.d.ts +4 -7
  83. package/dist/market_adapter/core/strategies/collateral_manager.d.ts.map +1 -1
  84. package/dist/market_adapter/core/strategies/collateral_manager.js +5 -4
  85. package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -1
  86. package/dist/market_adapter/core/strategies/regime_gate.d.ts +11 -19
  87. package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -1
  88. package/dist/market_adapter/core/strategies/regime_gate.js +22 -22
  89. package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -1
  90. package/dist/market_adapter/index.d.ts +24 -2
  91. package/dist/market_adapter/index.d.ts.map +1 -1
  92. package/dist/market_adapter/index.js +82 -56
  93. package/dist/market_adapter/index.js.map +1 -1
  94. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +26 -37
  95. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -1
  96. package/dist/market_adapter/inputs/fetch_lp_data.d.ts +4 -12
  97. package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
  98. package/dist/market_adapter/inputs/fetch_lp_data.js +100 -66
  99. package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
  100. package/dist/market_adapter/inputs/kibana_source.d.ts +4 -9
  101. package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -1
  102. package/dist/market_adapter/inputs/kibana_source.js +17 -18
  103. package/dist/market_adapter/inputs/kibana_source.js.map +1 -1
  104. package/dist/market_adapter/interval_utils.d.ts +1 -4
  105. package/dist/market_adapter/interval_utils.d.ts.map +1 -1
  106. package/dist/market_adapter/interval_utils.js +2 -3
  107. package/dist/market_adapter/interval_utils.js.map +1 -1
  108. package/dist/market_adapter/log_format.d.ts +1 -9
  109. package/dist/market_adapter/log_format.d.ts.map +1 -1
  110. package/dist/market_adapter/log_format.js +7 -8
  111. package/dist/market_adapter/log_format.js.map +1 -1
  112. package/dist/market_adapter/lp_chart_core.d.ts +1 -4
  113. package/dist/market_adapter/lp_chart_core.d.ts.map +1 -1
  114. package/dist/market_adapter/lp_chart_core.js +22 -20
  115. package/dist/market_adapter/lp_chart_core.js.map +1 -1
  116. package/dist/market_adapter/lp_chart_runner.d.ts +13 -24
  117. package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -1
  118. package/dist/market_adapter/lp_chart_runner.js +58 -56
  119. package/dist/market_adapter/lp_chart_runner.js.map +1 -1
  120. package/dist/market_adapter/lp_chart_strategy_loader.d.ts +4 -17
  121. package/dist/market_adapter/lp_chart_strategy_loader.d.ts.map +1 -1
  122. package/dist/market_adapter/lp_chart_strategy_loader.js +36 -36
  123. package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -1
  124. package/dist/market_adapter/market_adapter.d.ts +51 -72
  125. package/dist/market_adapter/market_adapter.d.ts.map +1 -1
  126. package/dist/market_adapter/market_adapter.js +227 -192
  127. package/dist/market_adapter/market_adapter.js.map +1 -1
  128. package/dist/market_adapter/merge_lp_data.js +17 -16
  129. package/dist/market_adapter/merge_lp_data.js.map +1 -1
  130. package/dist/market_adapter/test_helpers.d.ts +9 -13
  131. package/dist/market_adapter/test_helpers.d.ts.map +1 -1
  132. package/dist/market_adapter/test_helpers.js +14 -14
  133. package/dist/market_adapter/test_helpers.js.map +1 -1
  134. package/dist/market_adapter/utils/adapter_client.d.ts +6 -14
  135. package/dist/market_adapter/utils/adapter_client.d.ts.map +1 -1
  136. package/dist/market_adapter/utils/adapter_client.js +16 -15
  137. package/dist/market_adapter/utils/adapter_client.js.map +1 -1
  138. package/dist/market_adapter/utils/atomic_write.d.ts +2 -5
  139. package/dist/market_adapter/utils/atomic_write.d.ts.map +1 -1
  140. package/dist/market_adapter/utils/atomic_write.js +5 -5
  141. package/dist/market_adapter/utils/atomic_write.js.map +1 -1
  142. package/dist/market_adapter/utils/chain.d.ts +19 -21
  143. package/dist/market_adapter/utils/chain.d.ts.map +1 -1
  144. package/dist/market_adapter/utils/chain.js +15 -16
  145. package/dist/market_adapter/utils/chain.js.map +1 -1
  146. package/dist/market_adapter/utils/data_discovery.d.ts +1 -4
  147. package/dist/market_adapter/utils/data_discovery.d.ts.map +1 -1
  148. package/dist/market_adapter/utils/data_discovery.js +10 -10
  149. package/dist/market_adapter/utils/data_discovery.js.map +1 -1
  150. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts +1 -6
  151. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -1
  152. package/dist/market_adapter/utils/dynamic_grid_snapshot.js +14 -14
  153. package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -1
  154. package/dist/market_adapter/utils/file_lock.d.ts +1 -7
  155. package/dist/market_adapter/utils/file_lock.d.ts.map +1 -1
  156. package/dist/market_adapter/utils/file_lock.js +21 -25
  157. package/dist/market_adapter/utils/file_lock.js.map +1 -1
  158. package/dist/market_adapter/utils/native_history.d.ts +12 -12
  159. package/dist/market_adapter/utils/native_history.d.ts.map +1 -1
  160. package/dist/market_adapter/utils/native_history.js +15 -15
  161. package/dist/market_adapter/utils/native_history.js.map +1 -1
  162. package/dist/market_adapter/utils/paths.d.ts +2 -4
  163. package/dist/market_adapter/utils/paths.d.ts.map +1 -1
  164. package/dist/market_adapter/utils/paths.js +6 -5
  165. package/dist/market_adapter/utils/paths.js.map +1 -1
  166. package/dist/modules/account_bots.d.ts +7 -8
  167. package/dist/modules/account_bots.d.ts.map +1 -1
  168. package/dist/modules/account_bots.js +92 -114
  169. package/dist/modules/account_bots.js.map +1 -1
  170. package/dist/modules/account_orders.d.ts +5 -9
  171. package/dist/modules/account_orders.d.ts.map +1 -1
  172. package/dist/modules/account_orders.js +69 -32
  173. package/dist/modules/account_orders.js.map +1 -1
  174. package/dist/modules/authority_resolver.d.ts +32 -1
  175. package/dist/modules/authority_resolver.d.ts.map +1 -1
  176. package/dist/modules/authority_resolver.js +18 -12
  177. package/dist/modules/authority_resolver.js.map +1 -1
  178. package/dist/modules/bitshares-native/chain_client.d.ts +3 -8
  179. package/dist/modules/bitshares-native/chain_client.d.ts.map +1 -1
  180. package/dist/modules/bitshares-native/chain_client.js +21 -16
  181. package/dist/modules/bitshares-native/chain_client.js.map +1 -1
  182. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts +21 -29
  183. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -1
  184. package/dist/modules/bitshares-native/crypto/ecc.browser.js +72 -38
  185. package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -1
  186. package/dist/modules/bitshares-native/crypto/ecc.d.ts +9 -36
  187. package/dist/modules/bitshares-native/crypto/ecc.d.ts.map +1 -1
  188. package/dist/modules/bitshares-native/crypto/ecc.js +40 -83
  189. package/dist/modules/bitshares-native/crypto/ecc.js.map +1 -1
  190. package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts +14 -1
  191. package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts.map +1 -1
  192. package/dist/modules/bitshares-native/crypto/ecc_selector.js +5 -3
  193. package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -1
  194. package/dist/modules/bitshares-native/index.d.ts +10 -2
  195. package/dist/modules/bitshares-native/index.d.ts.map +1 -1
  196. package/dist/modules/bitshares-native/index.js +68 -31
  197. package/dist/modules/bitshares-native/index.js.map +1 -1
  198. package/dist/modules/bitshares-native/lru_cache.d.ts +1 -4
  199. package/dist/modules/bitshares-native/lru_cache.d.ts.map +1 -1
  200. package/dist/modules/bitshares-native/lru_cache.js +6 -3
  201. package/dist/modules/bitshares-native/lru_cache.js.map +1 -1
  202. package/dist/modules/bitshares-native/resolvers.d.ts +3 -6
  203. package/dist/modules/bitshares-native/resolvers.d.ts.map +1 -1
  204. package/dist/modules/bitshares-native/resolvers.js +11 -9
  205. package/dist/modules/bitshares-native/resolvers.js.map +1 -1
  206. package/dist/modules/bitshares-native/serial/chain_constants.d.ts +53 -55
  207. package/dist/modules/bitshares-native/serial/chain_constants.d.ts.map +1 -1
  208. package/dist/modules/bitshares-native/serial/chain_constants.js +28 -27
  209. package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -1
  210. package/dist/modules/bitshares-native/serial/index.d.ts +5 -9
  211. package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -1
  212. package/dist/modules/bitshares-native/serial/index.js +46 -12
  213. package/dist/modules/bitshares-native/serial/index.js.map +1 -1
  214. package/dist/modules/bitshares-native/serial/operations.d.ts +102 -100
  215. package/dist/modules/bitshares-native/serial/operations.d.ts.map +1 -1
  216. package/dist/modules/bitshares-native/serial/operations.js +473 -471
  217. package/dist/modules/bitshares-native/serial/operations.js.map +1 -1
  218. package/dist/modules/bitshares-native/serial/serializer.d.ts +2 -7
  219. package/dist/modules/bitshares-native/serial/serializer.d.ts.map +1 -1
  220. package/dist/modules/bitshares-native/serial/serializer.js +8 -3
  221. package/dist/modules/bitshares-native/serial/serializer.js.map +1 -1
  222. package/dist/modules/bitshares-native/serial/types.d.ts +26 -41
  223. package/dist/modules/bitshares-native/serial/types.d.ts.map +1 -1
  224. package/dist/modules/bitshares-native/serial/types.js +76 -42
  225. package/dist/modules/bitshares-native/serial/types.js.map +1 -1
  226. package/dist/modules/bitshares-native/signing_client.d.ts +1 -5
  227. package/dist/modules/bitshares-native/signing_client.d.ts.map +1 -1
  228. package/dist/modules/bitshares-native/signing_client.js +49 -11
  229. package/dist/modules/bitshares-native/signing_client.js.map +1 -1
  230. package/dist/modules/bitshares-native/subscriptions.d.ts +1 -4
  231. package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -1
  232. package/dist/modules/bitshares-native/subscriptions.js +47 -84
  233. package/dist/modules/bitshares-native/subscriptions.js.map +1 -1
  234. package/dist/modules/bitshares-native/transport.d.ts +1 -8
  235. package/dist/modules/bitshares-native/transport.d.ts.map +1 -1
  236. package/dist/modules/bitshares-native/transport.js +22 -15
  237. package/dist/modules/bitshares-native/transport.js.map +1 -1
  238. package/dist/modules/bitshares-native/tx/builder.d.ts +3 -8
  239. package/dist/modules/bitshares-native/tx/builder.d.ts.map +1 -1
  240. package/dist/modules/bitshares-native/tx/builder.js +61 -23
  241. package/dist/modules/bitshares-native/tx/builder.js.map +1 -1
  242. package/dist/modules/bitshares-native/tx/tx_cache.d.ts +1 -8
  243. package/dist/modules/bitshares-native/tx/tx_cache.d.ts.map +1 -1
  244. package/dist/modules/bitshares-native/tx/tx_cache.js +21 -17
  245. package/dist/modules/bitshares-native/tx/tx_cache.js.map +1 -1
  246. package/dist/modules/bitshares_client.d.ts +12 -23
  247. package/dist/modules/bitshares_client.d.ts.map +1 -1
  248. package/dist/modules/bitshares_client.js +109 -56
  249. package/dist/modules/bitshares_client.js.map +1 -1
  250. package/dist/modules/bot_settings.d.ts +1 -13
  251. package/dist/modules/bot_settings.d.ts.map +1 -1
  252. package/dist/modules/bot_settings.js +34 -34
  253. package/dist/modules/bot_settings.js.map +1 -1
  254. package/dist/modules/bots_file_lock.d.ts +3 -9
  255. package/dist/modules/bots_file_lock.d.ts.map +1 -1
  256. package/dist/modules/bots_file_lock.js +8 -9
  257. package/dist/modules/bots_file_lock.js.map +1 -1
  258. package/dist/modules/chain_keys.d.ts +7 -39
  259. package/dist/modules/chain_keys.d.ts.map +1 -1
  260. package/dist/modules/chain_keys.js +126 -90
  261. package/dist/modules/chain_keys.js.map +1 -1
  262. package/dist/modules/chain_orders.d.ts +46 -52
  263. package/dist/modules/chain_orders.d.ts.map +1 -1
  264. package/dist/modules/chain_orders.js +152 -104
  265. package/dist/modules/chain_orders.js.map +1 -1
  266. package/dist/modules/config.d.ts +50 -57
  267. package/dist/modules/config.d.ts.map +1 -1
  268. package/dist/modules/config.js +28 -24
  269. package/dist/modules/config.js.map +1 -1
  270. package/dist/modules/constants.d.ts +492 -494
  271. package/dist/modules/constants.d.ts.map +1 -1
  272. package/dist/modules/constants.js +69 -39
  273. package/dist/modules/constants.js.map +1 -1
  274. package/dist/modules/cr_planner.d.ts +1 -13
  275. package/dist/modules/cr_planner.d.ts.map +1 -1
  276. package/dist/modules/cr_planner.js +28 -28
  277. package/dist/modules/cr_planner.js.map +1 -1
  278. package/dist/modules/credential_policy.d.ts +18 -33
  279. package/dist/modules/credential_policy.d.ts.map +1 -1
  280. package/dist/modules/credential_policy.js +114 -87
  281. package/dist/modules/credential_policy.js.map +1 -1
  282. package/dist/modules/credential_runtime.d.ts +11 -21
  283. package/dist/modules/credential_runtime.d.ts.map +1 -1
  284. package/dist/modules/credential_runtime.js +40 -40
  285. package/dist/modules/credential_runtime.js.map +1 -1
  286. package/dist/modules/credential_session_cache.d.ts +8 -8
  287. package/dist/modules/credential_session_cache.d.ts.map +1 -1
  288. package/dist/modules/credential_session_cache.js +41 -8
  289. package/dist/modules/credential_session_cache.js.map +1 -1
  290. package/dist/modules/credit_runtime.d.ts +51 -316
  291. package/dist/modules/credit_runtime.d.ts.map +1 -1
  292. package/dist/modules/credit_runtime.js +257 -183
  293. package/dist/modules/credit_runtime.js.map +1 -1
  294. package/dist/modules/crypto/browser_provider.js +6 -6
  295. package/dist/modules/crypto/browser_provider.js.map +1 -1
  296. package/dist/modules/crypto/index.d.ts.map +1 -1
  297. package/dist/modules/crypto/index.js +2 -0
  298. package/dist/modules/crypto/index.js.map +1 -1
  299. package/dist/modules/crypto/sync.js +3 -3
  300. package/dist/modules/crypto/sync.js.map +1 -1
  301. package/dist/modules/dexbot_class.d.ts +262 -81
  302. package/dist/modules/dexbot_class.d.ts.map +1 -1
  303. package/dist/modules/dexbot_class.js +156 -123
  304. package/dist/modules/dexbot_class.js.map +1 -1
  305. package/dist/modules/dexbot_cow_runtime.d.ts +12 -9
  306. package/dist/modules/dexbot_cow_runtime.d.ts.map +1 -1
  307. package/dist/modules/dexbot_cow_runtime.js +144 -63
  308. package/dist/modules/dexbot_cow_runtime.js.map +1 -1
  309. package/dist/modules/dexbot_credential_client.d.ts +5 -11
  310. package/dist/modules/dexbot_credential_client.d.ts.map +1 -1
  311. package/dist/modules/dexbot_credential_client.js +32 -30
  312. package/dist/modules/dexbot_credential_client.js.map +1 -1
  313. package/dist/modules/dexbot_fill_runtime.d.ts +5 -20
  314. package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -1
  315. package/dist/modules/dexbot_fill_runtime.js +55 -116
  316. package/dist/modules/dexbot_fill_runtime.js.map +1 -1
  317. package/dist/modules/dexbot_maintenance_runtime.d.ts +12 -12
  318. package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
  319. package/dist/modules/dexbot_maintenance_runtime.js +55 -45
  320. package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
  321. package/dist/modules/dexbot_startup_runtime.d.ts +2 -6
  322. package/dist/modules/dexbot_startup_runtime.d.ts.map +1 -1
  323. package/dist/modules/dexbot_startup_runtime.js +122 -91
  324. package/dist/modules/dexbot_startup_runtime.js.map +1 -1
  325. package/dist/modules/dexbot_state_recovery.d.ts +11 -24
  326. package/dist/modules/dexbot_state_recovery.d.ts.map +1 -1
  327. package/dist/modules/dexbot_state_recovery.js +62 -28
  328. package/dist/modules/dexbot_state_recovery.js.map +1 -1
  329. package/dist/modules/fund_registry.d.ts +1 -13
  330. package/dist/modules/fund_registry.d.ts.map +1 -1
  331. package/dist/modules/fund_registry.js +23 -21
  332. package/dist/modules/fund_registry.js.map +1 -1
  333. package/dist/modules/general_settings.d.ts +3 -7
  334. package/dist/modules/general_settings.d.ts.map +1 -1
  335. package/dist/modules/general_settings.js +15 -14
  336. package/dist/modules/general_settings.js.map +1 -1
  337. package/dist/modules/graceful_shutdown.d.ts +1 -6
  338. package/dist/modules/graceful_shutdown.d.ts.map +1 -1
  339. package/dist/modules/graceful_shutdown.js +19 -16
  340. package/dist/modules/graceful_shutdown.js.map +1 -1
  341. package/dist/modules/key_store.d.ts.map +1 -1
  342. package/dist/modules/key_store.js +53 -19
  343. package/dist/modules/key_store.js.map +1 -1
  344. package/dist/modules/launcher/bot_supervisor.d.ts +23 -66
  345. package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -1
  346. package/dist/modules/launcher/bot_supervisor.js +115 -107
  347. package/dist/modules/launcher/bot_supervisor.js.map +1 -1
  348. package/dist/modules/launcher/child_env.d.ts +2 -5
  349. package/dist/modules/launcher/child_env.d.ts.map +1 -1
  350. package/dist/modules/launcher/child_env.js +4 -4
  351. package/dist/modules/launcher/child_env.js.map +1 -1
  352. package/dist/modules/launcher/credential_bootstrap.d.ts +4 -8
  353. package/dist/modules/launcher/credential_bootstrap.d.ts.map +1 -1
  354. package/dist/modules/launcher/credential_bootstrap.js +30 -26
  355. package/dist/modules/launcher/credential_bootstrap.js.map +1 -1
  356. package/dist/modules/launcher/credential_daemon.d.ts +8 -15
  357. package/dist/modules/launcher/credential_daemon.d.ts.map +1 -1
  358. package/dist/modules/launcher/credential_daemon.js +72 -41
  359. package/dist/modules/launcher/credential_daemon.js.map +1 -1
  360. package/dist/modules/launcher/credential_secret.d.ts +1 -4
  361. package/dist/modules/launcher/credential_secret.d.ts.map +1 -1
  362. package/dist/modules/launcher/credential_secret.js +36 -4
  363. package/dist/modules/launcher/credential_secret.js.map +1 -1
  364. package/dist/modules/launcher/foreign_cred_daemon.d.ts +32 -1
  365. package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -1
  366. package/dist/modules/launcher/foreign_cred_daemon.js +25 -28
  367. package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -1
  368. package/dist/modules/launcher/headless_password.d.ts +1 -4
  369. package/dist/modules/launcher/headless_password.d.ts.map +1 -1
  370. package/dist/modules/launcher/headless_password.js +11 -11
  371. package/dist/modules/launcher/headless_password.js.map +1 -1
  372. package/dist/modules/launcher/launch_modes.d.ts +15 -14
  373. package/dist/modules/launcher/launch_modes.d.ts.map +1 -1
  374. package/dist/modules/launcher/launch_modes.js +8 -8
  375. package/dist/modules/launcher/launch_modes.js.map +1 -1
  376. package/dist/modules/launcher/market_adapter_runtime.d.ts +10 -19
  377. package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -1
  378. package/dist/modules/launcher/market_adapter_runtime.js +33 -33
  379. package/dist/modules/launcher/market_adapter_runtime.js.map +1 -1
  380. package/dist/modules/launcher/market_adapter_watchdog.d.ts +10 -17
  381. package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -1
  382. package/dist/modules/launcher/market_adapter_watchdog.js +42 -38
  383. package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -1
  384. package/dist/modules/launcher/monolithic_runtime.d.ts +28 -57
  385. package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
  386. package/dist/modules/launcher/monolithic_runtime.js +135 -108
  387. package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
  388. package/dist/modules/launcher/runtime_entry.d.ts +5 -10
  389. package/dist/modules/launcher/runtime_entry.d.ts.map +1 -1
  390. package/dist/modules/launcher/runtime_entry.js +14 -14
  391. package/dist/modules/launcher/runtime_entry.js.map +1 -1
  392. package/dist/modules/launcher/status_reporting.d.ts +17 -37
  393. package/dist/modules/launcher/status_reporting.d.ts.map +1 -1
  394. package/dist/modules/launcher/status_reporting.js +35 -34
  395. package/dist/modules/launcher/status_reporting.js.map +1 -1
  396. package/dist/modules/launcher/supervisor_control.d.ts +1 -4
  397. package/dist/modules/launcher/supervisor_control.d.ts.map +1 -1
  398. package/dist/modules/launcher/supervisor_control.js +9 -4
  399. package/dist/modules/launcher/supervisor_control.js.map +1 -1
  400. package/dist/modules/logger.d.ts +3 -1
  401. package/dist/modules/logger.d.ts.map +1 -1
  402. package/dist/modules/logger.js +38 -28
  403. package/dist/modules/logger.js.map +1 -1
  404. package/dist/modules/market_adapter_whitelist.d.ts +2 -10
  405. package/dist/modules/market_adapter_whitelist.d.ts.map +1 -1
  406. package/dist/modules/market_adapter_whitelist.js +18 -16
  407. package/dist/modules/market_adapter_whitelist.js.map +1 -1
  408. package/dist/modules/node_health_cache.d.ts +2 -12
  409. package/dist/modules/node_health_cache.d.ts.map +1 -1
  410. package/dist/modules/node_health_cache.js +24 -24
  411. package/dist/modules/node_health_cache.js.map +1 -1
  412. package/dist/modules/node_manager.d.ts +1 -1
  413. package/dist/modules/node_manager.d.ts.map +1 -1
  414. package/dist/modules/node_manager.js +44 -38
  415. package/dist/modules/node_manager.js.map +1 -1
  416. package/dist/modules/order/accounting.d.ts +12 -12
  417. package/dist/modules/order/accounting.d.ts.map +1 -1
  418. package/dist/modules/order/accounting.js +111 -76
  419. package/dist/modules/order/accounting.js.map +1 -1
  420. package/dist/modules/order/async_lock.d.ts +1 -2
  421. package/dist/modules/order/async_lock.d.ts.map +1 -1
  422. package/dist/modules/order/async_lock.js +4 -4
  423. package/dist/modules/order/async_lock.js.map +1 -1
  424. package/dist/modules/order/export.d.ts +8 -14
  425. package/dist/modules/order/export.d.ts.map +1 -1
  426. package/dist/modules/order/export.js +77 -42
  427. package/dist/modules/order/export.js.map +1 -1
  428. package/dist/modules/order/format.d.ts +17 -22
  429. package/dist/modules/order/format.d.ts.map +1 -1
  430. package/dist/modules/order/format.js +25 -31
  431. package/dist/modules/order/format.js.map +1 -1
  432. package/dist/modules/order/grid.d.ts +18 -104
  433. package/dist/modules/order/grid.d.ts.map +1 -1
  434. package/dist/modules/order/grid.js +346 -212
  435. package/dist/modules/order/grid.js.map +1 -1
  436. package/dist/modules/order/grid_reconcile.d.ts +8 -8
  437. package/dist/modules/order/grid_reconcile.d.ts.map +1 -1
  438. package/dist/modules/order/grid_reconcile.js +80 -23
  439. package/dist/modules/order/grid_reconcile.js.map +1 -1
  440. package/dist/modules/order/grid_reconcile_internal.d.ts +224 -1
  441. package/dist/modules/order/grid_reconcile_internal.d.ts.map +1 -1
  442. package/dist/modules/order/grid_reconcile_internal.js +159 -73
  443. package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
  444. package/dist/modules/order/index.d.ts +1 -1
  445. package/dist/modules/order/index.d.ts.map +1 -1
  446. package/dist/modules/order/index.js +42 -7
  447. package/dist/modules/order/index.js.map +1 -1
  448. package/dist/modules/order/logger.d.ts +6 -16
  449. package/dist/modules/order/logger.d.ts.map +1 -1
  450. package/dist/modules/order/logger.js +76 -53
  451. package/dist/modules/order/logger.js.map +1 -1
  452. package/dist/modules/order/logger_state.d.ts +4 -4
  453. package/dist/modules/order/logger_state.d.ts.map +1 -1
  454. package/dist/modules/order/logger_state.js +3 -1
  455. package/dist/modules/order/logger_state.js.map +1 -1
  456. package/dist/modules/order/manager.d.ts +160 -37
  457. package/dist/modules/order/manager.d.ts.map +1 -1
  458. package/dist/modules/order/manager.js +166 -128
  459. package/dist/modules/order/manager.js.map +1 -1
  460. package/dist/modules/order/processed_fill_store.d.ts +6 -10
  461. package/dist/modules/order/processed_fill_store.d.ts.map +1 -1
  462. package/dist/modules/order/processed_fill_store.js +10 -9
  463. package/dist/modules/order/processed_fill_store.js.map +1 -1
  464. package/dist/modules/order/strategy.d.ts +3 -3
  465. package/dist/modules/order/strategy.d.ts.map +1 -1
  466. package/dist/modules/order/strategy.js +29 -27
  467. package/dist/modules/order/strategy.js.map +1 -1
  468. package/dist/modules/order/sync_engine.d.ts +9 -19
  469. package/dist/modules/order/sync_engine.d.ts.map +1 -1
  470. package/dist/modules/order/sync_engine.js +176 -126
  471. package/dist/modules/order/sync_engine.js.map +1 -1
  472. package/dist/modules/order/utils/math.d.ts +55 -85
  473. package/dist/modules/order/utils/math.d.ts.map +1 -1
  474. package/dist/modules/order/utils/math.js +155 -88
  475. package/dist/modules/order/utils/math.js.map +1 -1
  476. package/dist/modules/order/utils/order.d.ts +27 -72
  477. package/dist/modules/order/utils/order.d.ts.map +1 -1
  478. package/dist/modules/order/utils/order.js +144 -105
  479. package/dist/modules/order/utils/order.js.map +1 -1
  480. package/dist/modules/order/utils/system.d.ts +103 -45
  481. package/dist/modules/order/utils/system.d.ts.map +1 -1
  482. package/dist/modules/order/utils/system.js +271 -150
  483. package/dist/modules/order/utils/system.js.map +1 -1
  484. package/dist/modules/order/utils/validate.d.ts +35 -47
  485. package/dist/modules/order/utils/validate.d.ts.map +1 -1
  486. package/dist/modules/order/utils/validate.js +233 -116
  487. package/dist/modules/order/utils/validate.js.map +1 -1
  488. package/dist/modules/order/working_grid.d.ts +1 -4
  489. package/dist/modules/order/working_grid.d.ts.map +1 -1
  490. package/dist/modules/order/working_grid.js +9 -7
  491. package/dist/modules/order/working_grid.js.map +1 -1
  492. package/dist/modules/path_api.js +2 -2
  493. package/dist/modules/path_api.js.map +1 -1
  494. package/dist/modules/paths.d.ts +50 -56
  495. package/dist/modules/paths.d.ts.map +1 -1
  496. package/dist/modules/paths.js +66 -57
  497. package/dist/modules/paths.js.map +1 -1
  498. package/dist/modules/process_discovery.d.ts +1 -1
  499. package/dist/modules/process_discovery.d.ts.map +1 -1
  500. package/dist/modules/process_discovery.js +7 -7
  501. package/dist/modules/process_discovery.js.map +1 -1
  502. package/dist/modules/runtime.d.ts +1 -1
  503. package/dist/modules/runtime.d.ts.map +1 -1
  504. package/dist/modules/runtime.js +4 -4
  505. package/dist/modules/runtime.js.map +1 -1
  506. package/dist/modules/runtime_settings.d.ts +1 -0
  507. package/dist/modules/runtime_settings.d.ts.map +1 -1
  508. package/dist/modules/runtime_settings.js +15 -10
  509. package/dist/modules/runtime_settings.js.map +1 -1
  510. package/dist/modules/settings_merge.d.ts +1 -4
  511. package/dist/modules/settings_merge.d.ts.map +1 -1
  512. package/dist/modules/settings_merge.js +2 -1
  513. package/dist/modules/settings_merge.js.map +1 -1
  514. package/dist/modules/storage/browser_adapter.d.ts +7 -3
  515. package/dist/modules/storage/browser_adapter.d.ts.map +1 -1
  516. package/dist/modules/storage/browser_adapter.js +2 -0
  517. package/dist/modules/storage/browser_adapter.js.map +1 -1
  518. package/dist/modules/storage/index.d.ts +2 -2
  519. package/dist/modules/storage/index.d.ts.map +1 -1
  520. package/dist/modules/storage/index.js +2 -5
  521. package/dist/modules/storage/index.js.map +1 -1
  522. package/dist/modules/storage/node_adapter.d.ts +3 -3
  523. package/dist/modules/storage/node_adapter.d.ts.map +1 -1
  524. package/dist/modules/storage/node_adapter.js +9 -7
  525. package/dist/modules/storage/node_adapter.js.map +1 -1
  526. package/dist/modules/storage/types.d.ts +13 -10
  527. package/dist/modules/storage/types.d.ts.map +1 -1
  528. package/dist/modules/types.d.ts +0 -2
  529. package/dist/modules/types.d.ts.map +1 -1
  530. package/dist/modules/utils/base58check.d.ts +1 -9
  531. package/dist/modules/utils/base58check.d.ts.map +1 -1
  532. package/dist/modules/utils/base58check.js +14 -16
  533. package/dist/modules/utils/base58check.js.map +1 -1
  534. package/dist/modules/utils/build_dir.d.ts +2 -5
  535. package/dist/modules/utils/build_dir.d.ts.map +1 -1
  536. package/dist/modules/utils/build_dir.js +6 -3
  537. package/dist/modules/utils/build_dir.js.map +1 -1
  538. package/dist/modules/utils/errors.d.ts +2 -0
  539. package/dist/modules/utils/errors.d.ts.map +1 -0
  540. package/dist/modules/utils/errors.js +12 -0
  541. package/dist/modules/utils/errors.js.map +1 -0
  542. package/dist/modules/utils/fs_utils.d.ts +1 -8
  543. package/dist/modules/utils/fs_utils.d.ts.map +1 -1
  544. package/dist/modules/utils/fs_utils.js +8 -3
  545. package/dist/modules/utils/fs_utils.js.map +1 -1
  546. package/dist/modules/utils/math_utils.d.ts +2 -6
  547. package/dist/modules/utils/math_utils.d.ts.map +1 -1
  548. package/dist/modules/utils/math_utils.js +6 -2
  549. package/dist/modules/utils/math_utils.js.map +1 -1
  550. package/dist/modules/validate_profiles.d.ts +1 -11
  551. package/dist/modules/validate_profiles.d.ts.map +1 -1
  552. package/dist/modules/validate_profiles.js +25 -27
  553. package/dist/modules/validate_profiles.js.map +1 -1
  554. package/dist/pm2.d.ts +7 -6
  555. package/dist/pm2.d.ts.map +1 -1
  556. package/dist/pm2.js +132 -106
  557. package/dist/pm2.js.map +1 -1
  558. package/dist/scripts/analyze-git.d.ts.map +1 -1
  559. package/dist/scripts/analyze-git.js +15 -11
  560. package/dist/scripts/analyze-git.js.map +1 -1
  561. package/dist/scripts/analyze-orders.d.ts +146 -1
  562. package/dist/scripts/analyze-orders.d.ts.map +1 -1
  563. package/dist/scripts/analyze-orders.js +81 -105
  564. package/dist/scripts/analyze-orders.js.map +1 -1
  565. package/dist/scripts/diagnose-pool-history.d.ts.map +1 -1
  566. package/dist/scripts/diagnose-pool-history.js +9 -8
  567. package/dist/scripts/diagnose-pool-history.js.map +1 -1
  568. package/dist/scripts/divergence-calc.d.ts.map +1 -1
  569. package/dist/scripts/divergence-calc.js +11 -8
  570. package/dist/scripts/divergence-calc.js.map +1 -1
  571. package/dist/scripts/fix-err-message.d.ts +3 -0
  572. package/dist/scripts/fix-err-message.d.ts.map +1 -0
  573. package/dist/scripts/fix-err-message.js +198 -0
  574. package/dist/scripts/fix-err-message.js.map +1 -0
  575. package/dist/scripts/generate_lp_chart.d.ts +2 -9
  576. package/dist/scripts/generate_lp_chart.d.ts.map +1 -1
  577. package/dist/scripts/generate_lp_chart.js +14 -10
  578. package/dist/scripts/generate_lp_chart.js.map +1 -1
  579. package/dist/scripts/generate_mainnet_corpus_report.js +4 -4
  580. package/dist/scripts/generate_mainnet_corpus_report.js.map +1 -1
  581. package/dist/scripts/generate_market_adapter_whitelist.d.ts +17 -1
  582. package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +1 -1
  583. package/dist/scripts/generate_market_adapter_whitelist.js +23 -20
  584. package/dist/scripts/generate_market_adapter_whitelist.js.map +1 -1
  585. package/dist/scripts/migrate_bot_keys.d.ts +1 -4
  586. package/dist/scripts/migrate_bot_keys.d.ts.map +1 -1
  587. package/dist/scripts/migrate_bot_keys.js +48 -124
  588. package/dist/scripts/migrate_bot_keys.js.map +1 -1
  589. package/dist/scripts/native_release_gates.d.ts.map +1 -1
  590. package/dist/scripts/native_release_gates.js +18 -14
  591. package/dist/scripts/native_release_gates.js.map +1 -1
  592. package/dist/scripts/print_grid.js +1 -1
  593. package/dist/scripts/print_grid.js.map +1 -1
  594. package/dist/scripts/run-tests.js +1 -0
  595. package/dist/scripts/run-tests.js.map +1 -1
  596. package/dist/scripts/runner.d.ts +1 -11
  597. package/dist/scripts/runner.d.ts.map +1 -1
  598. package/dist/scripts/runner.js +21 -19
  599. package/dist/scripts/runner.js.map +1 -1
  600. package/dist/scripts/test-credit-renewal.d.ts.map +1 -1
  601. package/dist/scripts/test-credit-renewal.js +2 -1
  602. package/dist/scripts/test-credit-renewal.js.map +1 -1
  603. package/dist/scripts/update.d.ts.map +1 -1
  604. package/dist/scripts/update.js +85 -79
  605. package/dist/scripts/update.js.map +1 -1
  606. package/dist/scripts/validate_bots.js +2 -2
  607. package/dist/scripts/validate_bots.js.map +1 -1
  608. package/dist/unlock.d.ts +4 -17
  609. package/dist/unlock.d.ts.map +1 -1
  610. package/dist/unlock.js +141 -108
  611. package/dist/unlock.js.map +1 -1
  612. package/package.json +1 -1
  613. package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts +0 -3
  614. package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts.map +0 -1
  615. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js +0 -149
  616. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js.map +0 -1
  617. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts +0 -3
  618. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts.map +0 -1
  619. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js +0 -387
  620. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js.map +0 -1
  621. package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts +0 -3
  622. package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts.map +0 -1
  623. package/dist/analysis/ama_fitting/calibrate_convergence_er.js +0 -200
  624. package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +0 -1
  625. package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts +0 -3
  626. package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts.map +0 -1
  627. package/dist/analysis/ama_fitting/fetch_lp_candles.js +0 -212
  628. package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +0 -1
  629. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts +0 -31
  630. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts.map +0 -1
  631. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js +0 -249
  632. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js.map +0 -1
  633. package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts +0 -2
  634. package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts.map +0 -1
  635. package/dist/analysis/ama_fitting/optimizer_high_resolution.js +0 -782
  636. package/dist/analysis/ama_fitting/optimizer_high_resolution.js.map +0 -1
  637. package/dist/analysis/analyze_derivatives.d.ts +0 -95
  638. package/dist/analysis/analyze_derivatives.d.ts.map +0 -1
  639. package/dist/analysis/analyze_derivatives.js +0 -295
  640. package/dist/analysis/analyze_derivatives.js.map +0 -1
  641. package/dist/analysis/analyze_dynamic_weight.d.ts +0 -14
  642. package/dist/analysis/analyze_dynamic_weight.d.ts.map +0 -1
  643. package/dist/analysis/analyze_dynamic_weight.js +0 -207
  644. package/dist/analysis/analyze_dynamic_weight.js.map +0 -1
  645. package/dist/analysis/analyze_kalman.d.ts +0 -13
  646. package/dist/analysis/analyze_kalman.d.ts.map +0 -1
  647. package/dist/analysis/analyze_kalman.js +0 -123
  648. package/dist/analysis/analyze_kalman.js.map +0 -1
  649. package/dist/analysis/analyze_regime.d.ts +0 -20
  650. package/dist/analysis/analyze_regime.d.ts.map +0 -1
  651. package/dist/analysis/analyze_regime.js +0 -139
  652. package/dist/analysis/analyze_regime.js.map +0 -1
  653. package/dist/analysis/analyze_regime_windows.d.ts +0 -19
  654. package/dist/analysis/analyze_regime_windows.d.ts.map +0 -1
  655. package/dist/analysis/analyze_regime_windows.js +0 -413
  656. package/dist/analysis/analyze_regime_windows.js.map +0 -1
  657. package/dist/analysis/analyze_risk_profile.d.ts +0 -3
  658. package/dist/analysis/analyze_risk_profile.d.ts.map +0 -1
  659. package/dist/analysis/analyze_risk_profile.js +0 -159
  660. package/dist/analysis/analyze_risk_profile.js.map +0 -1
  661. package/dist/analysis/analyze_trade_heatmap.d.ts +0 -3
  662. package/dist/analysis/analyze_trade_heatmap.d.ts.map +0 -1
  663. package/dist/analysis/analyze_trade_heatmap.js +0 -367
  664. package/dist/analysis/analyze_trade_heatmap.js.map +0 -1
  665. package/dist/analysis/analyze_volatility.d.ts +0 -22
  666. package/dist/analysis/analyze_volatility.d.ts.map +0 -1
  667. package/dist/analysis/analyze_volatility.js +0 -172
  668. package/dist/analysis/analyze_volatility.js.map +0 -1
  669. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts +0 -99
  670. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts.map +0 -1
  671. package/dist/analysis/bot_fitting/backtest_ama_sweep.js +0 -804
  672. package/dist/analysis/bot_fitting/backtest_ama_sweep.js.map +0 -1
  673. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts +0 -2
  674. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts.map +0 -1
  675. package/dist/analysis/bot_fitting/backtest_bot_fitting.js +0 -347
  676. package/dist/analysis/bot_fitting/backtest_bot_fitting.js.map +0 -1
  677. package/dist/analysis/bot_fitting/shared_utils.d.ts +0 -15
  678. package/dist/analysis/bot_fitting/shared_utils.d.ts.map +0 -1
  679. package/dist/analysis/bot_fitting/shared_utils.js +0 -48
  680. package/dist/analysis/bot_fitting/shared_utils.js.map +0 -1
  681. package/dist/analysis/bot_key_utils.d.ts +0 -22
  682. package/dist/analysis/bot_key_utils.d.ts.map +0 -1
  683. package/dist/analysis/bot_key_utils.js +0 -162
  684. package/dist/analysis/bot_key_utils.js.map +0 -1
  685. package/dist/analysis/bot_usage/discover_bot_accounts.d.ts +0 -3
  686. package/dist/analysis/bot_usage/discover_bot_accounts.d.ts.map +0 -1
  687. package/dist/analysis/bot_usage/discover_bot_accounts.js +0 -498
  688. package/dist/analysis/bot_usage/discover_bot_accounts.js.map +0 -1
  689. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +0 -546
  690. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +0 -1
  691. package/dist/analysis/bot_usage/kibana_bot_queries.js +0 -427
  692. package/dist/analysis/bot_usage/kibana_bot_queries.js.map +0 -1
  693. package/dist/analysis/derivative_chart_generator.d.ts +0 -18
  694. package/dist/analysis/derivative_chart_generator.d.ts.map +0 -1
  695. package/dist/analysis/derivative_chart_generator.js +0 -896
  696. package/dist/analysis/derivative_chart_generator.js.map +0 -1
  697. package/dist/analysis/price_sources.d.ts +0 -34
  698. package/dist/analysis/price_sources.d.ts.map +0 -1
  699. package/dist/analysis/price_sources.js +0 -103
  700. package/dist/analysis/price_sources.js.map +0 -1
  701. package/dist/analysis/trade_profitability.d.ts +0 -115
  702. package/dist/analysis/trade_profitability.d.ts.map +0 -1
  703. package/dist/analysis/trade_profitability.js +0 -1247
  704. package/dist/analysis/trade_profitability.js.map +0 -1
  705. package/dist/analysis/tradingview/analyze_tradingview.d.ts +0 -36
  706. package/dist/analysis/tradingview/analyze_tradingview.d.ts.map +0 -1
  707. package/dist/analysis/tradingview/analyze_tradingview.js +0 -172
  708. package/dist/analysis/tradingview/analyze_tradingview.js.map +0 -1
  709. package/dist/analysis/trend_detection/derivative_analyzer.d.ts +0 -250
  710. package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +0 -1
  711. package/dist/analysis/trend_detection/derivative_analyzer.js +0 -903
  712. package/dist/analysis/trend_detection/derivative_analyzer.js.map +0 -1
  713. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts +0 -6
  714. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +0 -1
  715. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +0 -1450
  716. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +0 -1
  717. package/dist/analysis/trend_detection/kalman_chart_generator.d.ts +0 -6
  718. package/dist/analysis/trend_detection/kalman_chart_generator.d.ts.map +0 -1
  719. package/dist/analysis/trend_detection/kalman_chart_generator.js +0 -408
  720. package/dist/analysis/trend_detection/kalman_chart_generator.js.map +0 -1
  721. package/dist/analysis/trend_detection/regime_chart_generator.d.ts +0 -6
  722. package/dist/analysis/trend_detection/regime_chart_generator.d.ts.map +0 -1
  723. package/dist/analysis/trend_detection/regime_chart_generator.js +0 -345
  724. package/dist/analysis/trend_detection/regime_chart_generator.js.map +0 -1
  725. package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts +0 -2
  726. package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts.map +0 -1
  727. package/dist/analysis/trend_detection/tests/test_kalman_trend.js +0 -130
  728. package/dist/analysis/trend_detection/tests/test_kalman_trend.js.map +0 -1
  729. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts +0 -2
  730. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts.map +0 -1
  731. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js +0 -38
  732. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js.map +0 -1
  733. package/dist/analysis/trend_detection/volatility_chart_generator.d.ts +0 -6
  734. package/dist/analysis/trend_detection/volatility_chart_generator.d.ts.map +0 -1
  735. package/dist/analysis/trend_detection/volatility_chart_generator.js +0 -732
  736. package/dist/analysis/trend_detection/volatility_chart_generator.js.map +0 -1
@@ -1,1247 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.analyzePair = analyzePair;
8
- exports.classifyFills = classifyFills;
9
- exports.computeMetrics = computeMetrics;
10
- const node_fs_1 = __importDefault(require("node:fs"));
11
- const kibana_client_1 = __importDefault(require("../market_adapter/core/kibana_client"));
12
- const constants_1 = __importDefault(require("../modules/constants"));
13
- const { kibanaSearch, DEFAULT_CONFIG: BASE_CONFIG } = kibana_client_1.default;
14
- /**
15
- * TRADE PROFITABILITY ANALYZER
16
- *
17
- * Fetches fill_order operations for a BitShares account from Kibana
18
- * within a specified time range, then analyzes profitability using
19
- * FIFO or sequential (LIFO) inventory tracking per asset pair.
20
- *
21
- * Usage:
22
- * tsx analysis/trade_profitability.ts 1.2.3 --start 2025-01-01 --end 2025-06-01
23
- * tsx analysis/trade_profitability.ts 1.2.3 --hours 720
24
- * tsx analysis/trade_profitability.ts 1.2.3 --start 2025-01-01T00:00:00Z --end 2025-06-01T00:00:00Z
25
- * tsx analysis/trade_profitability.ts 1.2.3 --hours 168 --asset 1.3.113
26
- * tsx analysis/trade_profitability.ts 1.2.3 --hours 168 --csv trades.csv
27
- * tsx analysis/trade_profitability.ts 1.2.3 --hours 168 --json results.json
28
- * tsx analysis/trade_profitability.ts "account-name" --lookup
29
- * tsx analysis/trade_profitability.ts 1.2.3 --hours 168 --trades
30
- * tsx analysis/trade_profitability.ts 1.2.3 --hours 168 --match-mode fifo
31
- */
32
- // ─── Constants ────────────────────────────────────────────────────────────────
33
- const OP_FILL_ORDER = 4;
34
- const BTS_ID = '1.3.0';
35
- let BLOCKCHAIN_FEE_PER_FILL = 0.09652; // BTS — flat blockchain operation fee (not market fee); override with --fee-per-order
36
- const ASSETS = {
37
- '1.3.0': { symbol: 'BTS', precision: 5 },
38
- '1.3.118': { symbol: 'GBP', precision: 4 },
39
- '1.3.119': { symbol: 'JPY', precision: 2 },
40
- '1.3.120': { symbol: 'EUR', precision: 4 },
41
- '1.3.1325': { symbol: 'RUBLE', precision: 5 },
42
- '1.3.2512': { symbol: 'EVRAZ', precision: 4 },
43
- '1.3.3291': { symbol: 'TWENTIX', precision: 5 },
44
- '1.3.4099': { symbol: 'XBTSX.STH', precision: 6 },
45
- '1.3.4156': { symbol: 'XBTSX.DOGE', precision: 5 },
46
- '1.3.4157': { symbol: 'XBTSX.BTC', precision: 8 },
47
- '1.3.4159': { symbol: 'XBTSX.LTC', precision: 8 },
48
- '1.3.4176': { symbol: 'XBTSX.DASH', precision: 8 },
49
- '1.3.4274': { symbol: 'XBTSX.BCH', precision: 8 },
50
- '1.3.4760': { symbol: 'XBTSX.ETH', precision: 7 },
51
- '1.3.5537': { symbol: 'IOB.XRP', precision: 4 },
52
- '1.3.5541': { symbol: 'XBTSX.BNB', precision: 7 },
53
- '1.3.5589': { symbol: 'XBTSX.USDT', precision: 6 },
54
- '1.3.5641': { symbol: 'HONEST.CNY', precision: 4 },
55
- '1.3.5649': { symbol: 'HONEST.USD', precision: 4 },
56
- '1.3.5650': { symbol: 'HONEST.BTC', precision: 8 },
57
- '1.3.5659': { symbol: 'HONEST.ETH', precision: 6 },
58
- '1.3.5870': { symbol: 'XBTSX.FIL', precision: 6 },
59
- '1.3.5887': { symbol: 'XBTSX.RUB', precision: 4 },
60
- '1.3.5902': { symbol: 'XBTSX.USDC', precision: 6 },
61
- '1.3.6013': { symbol: 'XBTSX.HIVE', precision: 6 },
62
- '1.3.6124': { symbol: 'XBTSX.AVAX', precision: 6 },
63
- '1.3.6139': { symbol: 'XBTSX.XAUT', precision: 6 },
64
- '1.3.6166': { symbol: 'XBTSX.MATIC', precision: 5 },
65
- '1.3.6241': { symbol: 'XBTSX.ETC', precision: 7 },
66
- '1.3.6268': { symbol: 'BTWTY.EOS', precision: 4 },
67
- '1.3.6301': { symbol: 'HONEST.MONEY', precision: 8 },
68
- '1.3.6304': { symbol: 'HONEST.ADA', precision: 8 },
69
- '1.3.6305': { symbol: 'HONEST.DOT', precision: 8 },
70
- '1.3.6309': { symbol: 'HONEST.ATOM', precision: 8 },
71
- '1.3.6311': { symbol: 'HONEST.ALGO', precision: 8 },
72
- '1.3.6312': { symbol: 'HONEST.FIL', precision: 8 },
73
- '1.3.6313': { symbol: 'HONEST.EOS', precision: 8 },
74
- '1.3.6315': { symbol: 'HONEST.EUR', precision: 4 },
75
- '1.3.6316': { symbol: 'HONEST.GBP', precision: 4 },
76
- '1.3.6317': { symbol: 'HONEST.JPY', precision: 4 },
77
- '1.3.6444': { symbol: 'IOB.XLM', precision: 4 },
78
- '1.3.6573': { symbol: 'XBTSX.DAI', precision: 6 },
79
- '1.3.6620': { symbol: 'XBTSX.A', precision: 6 },
80
- '1.3.6627': { symbol: 'XBTSX.LINK', precision: 6 },
81
- };
82
- const resolvedPrecisions = {};
83
- function assetSymbol(id) {
84
- return ASSETS[id]?.symbol ?? id;
85
- }
86
- function assetPrec(id) {
87
- return ASSETS[id]?.precision ?? resolvedPrecisions[id];
88
- }
89
- function getPrec(id) {
90
- return assetPrec(id);
91
- }
92
- function toReal(amount, assetId) {
93
- const p = getPrec(assetId);
94
- if (p === undefined)
95
- return NaN;
96
- return amount / Math.pow(10, p);
97
- }
98
- // ─── CLI ──────────────────────────────────────────────────────────────────────
99
- function printHelp() {
100
- console.log(`\
101
- Usage: tsx analysis/trade_profitability.ts <accountId> [options]
102
-
103
- Analyzes filled orders for a BitShares account, computing realized PnL
104
- via FIFO or sequential (LIFO) inventory tracking.
105
-
106
- Arguments:
107
- accountId BitShares account ID (1.2.x) or name (with --lookup)
108
-
109
- Options:
110
- --start <iso> Start time (ISO 8601, e.g. 2025-01-01 or 2025-01-01T00:00:00Z)
111
- --end <iso> End time (ISO 8601)
112
- --hours <n> Lookback hours from now (alternative to --start/--end)
113
- --asset <assetId> Filter to one base asset (e.g. 1.3.113 for bitUSD)
114
- --lookup Resolve account name to ID via BitShares node
115
- --node <url> BitShares node URL (default: first healthy from built-in pool)
116
- --csv <file> Export trade list as CSV
117
- --json <file> Export full analysis as JSON
118
- --trades Show per-order PnL detail (hidden by default)
119
- --match-mode <mode> Matching mode: sequential (default, LIFO) or fifo
120
- --fee-per-order <bts> Blockchain fee per limit_order_create op in BTS (default: 0.09652)
121
- --verbose Print extra debug info
122
- --help, -h Show this help
123
-
124
- Examples:
125
- tsx analysis/trade_profitability.ts 1.2.123456 --hours 720
126
- tsx analysis/trade_profitability.ts 1.2.123456 --start 2025-01-01 --end 2025-06-01
127
- tsx analysis/trade_profitability.ts "my-bot-account" --lookup --hours 168
128
- tsx analysis/trade_profitability.ts 1.2.123456 --hours 720 --asset 1.3.113 --csv trades.csv
129
- tsx analysis/trade_profitability.ts 1.2.123456 --hours 720 --match-mode sequential`);
130
- }
131
- function parseArgs() {
132
- const args = process.argv.slice(2);
133
- if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
134
- printHelp();
135
- process.exit(0);
136
- }
137
- const opts = {
138
- accountId: args[0],
139
- hours: null,
140
- start: null,
141
- end: null,
142
- asset: null,
143
- lookup: false,
144
- node: constants_1.default.NODE_MANAGEMENT.DEFAULT_NODES[0],
145
- csv: null,
146
- json: null,
147
- matchMode: 'sequential',
148
- showPnlDetail: false,
149
- verbose: false,
150
- feePerOrder: BLOCKCHAIN_FEE_PER_FILL,
151
- };
152
- for (let i = 1; i < args.length; i++) {
153
- switch (args[i]) {
154
- case '--hours':
155
- opts.hours = parseInt(args[++i], 10);
156
- break;
157
- case '--start':
158
- opts.start = args[++i];
159
- break;
160
- case '--end':
161
- opts.end = args[++i];
162
- break;
163
- case '--asset':
164
- opts.asset = args[++i];
165
- break;
166
- case '--lookup':
167
- opts.lookup = true;
168
- break;
169
- case '--node':
170
- opts.node = args[++i];
171
- break;
172
- case '--csv':
173
- opts.csv = args[++i];
174
- break;
175
- case '--json':
176
- opts.json = args[++i];
177
- break;
178
- case '--trades':
179
- opts.showPnlDetail = true;
180
- break;
181
- case '--fee-per-order':
182
- opts.feePerOrder = parseFloat(args[++i]);
183
- break;
184
- case '--match-mode': {
185
- const m = args[++i];
186
- if (m !== 'sequential' && m !== 'fifo') {
187
- console.error(`Invalid --match-mode: ${m} (expected: sequential | fifo)`);
188
- process.exit(1);
189
- }
190
- opts.matchMode = m;
191
- break;
192
- }
193
- case '--verbose':
194
- opts.verbose = true;
195
- break;
196
- default:
197
- console.error(`Unknown option: ${args[i]}`);
198
- process.exit(1);
199
- }
200
- }
201
- if (!opts.hours && !opts.start) {
202
- opts.hours = 168; // default: 7 days
203
- }
204
- return opts;
205
- }
206
- // ─── Account name resolution ─────────────────────────────────────────────────
207
- async function resolveAccountId(name, nodeUrl) {
208
- const mod = await import('../modules/bitshares-native/index.js');
209
- const { createReadOnlyClient } = mod.default;
210
- const client = createReadOnlyClient({ nodes: [nodeUrl] });
211
- // Suppress transport INFO logs during ephemeral connection:
212
- // bitshares-native transport logger (new Logger('Transport')) writes
213
- // "[timestamp] [INFO] [Transport] ..." — silence by raising log level.
214
- const prevLevel = process.env.LOG_LEVEL;
215
- process.env.LOG_LEVEL = 'warn';
216
- try {
217
- await client.connect();
218
- const accounts = await client.db('lookup_account_names', [[name]]);
219
- if (Array.isArray(accounts) && accounts[0]?.id) {
220
- return accounts[0].id;
221
- }
222
- return null;
223
- }
224
- catch (e) {
225
- console.warn(` [warn] Account resolution failed: ${e.message}`);
226
- return null;
227
- }
228
- finally {
229
- try {
230
- client.disconnect();
231
- }
232
- catch (_) { }
233
- process.env.LOG_LEVEL = prevLevel;
234
- }
235
- }
236
- // ─── On-chain asset precision resolution ────────────────────────────────────
237
- /**
238
- * Collects all unique non-BTS asset IDs from fills, resolves unknown
239
- * precisions from the blockchain, and populates the runtime cache.
240
- */
241
- async function resolveAssetPrecisions(fills, nodeUrl) {
242
- const unknownIds = new Set();
243
- for (const f of fills) {
244
- for (const id of [f.pays.asset_id, f.receives.asset_id, f.fee.asset_id]) {
245
- if (id !== BTS_ID && !(id in ASSETS) && !(id in resolvedPrecisions)) {
246
- unknownIds.add(id);
247
- }
248
- }
249
- }
250
- if (unknownIds.size === 0 || !nodeUrl)
251
- return;
252
- const ids = [...unknownIds];
253
- console.log(` Resolving ${ids.length} unknown asset(s) from blockchain...`);
254
- const mod = await import('../modules/bitshares-native/index.js');
255
- const { createReadOnlyClient } = mod.default;
256
- const client = createReadOnlyClient({ nodes: [nodeUrl] });
257
- try {
258
- await client.connect();
259
- const assets = await client.db('get_assets', [ids]);
260
- if (Array.isArray(assets)) {
261
- for (const asset of assets) {
262
- if (asset?.id && asset.precision != null) {
263
- resolvedPrecisions[asset.id] = asset.precision;
264
- console.log(` ${asset.id} → ${asset.symbol || '?'} (precision ${asset.precision})`);
265
- }
266
- }
267
- }
268
- const missing = ids.filter(id => !(id in resolvedPrecisions));
269
- if (missing.length > 0) {
270
- console.warn(` [warn] ${missing.length} asset(s) not found on chain: ${missing.join(', ')}. Fills referencing them will be skipped.`);
271
- }
272
- }
273
- catch (e) {
274
- console.warn(` [warn] Asset resolution failed: ${e.message}. Fills with unknown assets will be skipped.`);
275
- }
276
- finally {
277
- try {
278
- client.disconnect();
279
- }
280
- catch (_) { }
281
- }
282
- }
283
- // ─── Kibana Query ────────────────────────────────────────────────────────────
284
- function buildFillQuery(accountId, gte, lte, size) {
285
- return {
286
- size,
287
- track_total_hits: false,
288
- _source: [
289
- 'block_data.block_time',
290
- 'block_data.block_num',
291
- 'operation_id_num',
292
- 'operation_history.op_object.pays',
293
- 'operation_history.op_object.receives',
294
- 'operation_history.op_object.fee',
295
- 'operation_history.op_object.order_id',
296
- 'operation_history.op_object.account_id',
297
- 'operation_history.op_object.is_maker',
298
- ],
299
- query: {
300
- bool: {
301
- filter: [
302
- { term: { operation_type: OP_FILL_ORDER } },
303
- { term: { 'operation_history.op_object.account_id.keyword': accountId } },
304
- { range: { 'block_data.block_time': { gte, lte } } },
305
- ],
306
- },
307
- },
308
- sort: [
309
- { 'block_data.block_time': { order: 'asc' } },
310
- { operation_id_num: { order: 'asc' } },
311
- ],
312
- };
313
- }
314
- async function fetchAllFills(config, accountId, gte, lte) {
315
- const pageSize = 10000;
316
- const fills = [];
317
- let searchAfter = null;
318
- const cfg = { ...BASE_CONFIG, timeout: 60000, ...config };
319
- while (true) {
320
- const query = buildFillQuery(accountId, gte, lte, pageSize);
321
- if (searchAfter)
322
- query.search_after = searchAfter;
323
- const result = await kibanaSearch(cfg, query);
324
- const hits = result?.hits?.hits ?? [];
325
- if (!hits.length)
326
- break;
327
- for (const hit of hits) {
328
- const src = hit?._source;
329
- const op = src?.operation_history?.op_object;
330
- if (!op || !op.pays || !op.receives)
331
- continue;
332
- fills.push({
333
- time: src.block_data?.block_time ?? '',
334
- blockNum: src.block_data?.block_num ?? 0,
335
- opNum: Number(src.operation_id_num ?? 0),
336
- orderId: op.order_id ?? '',
337
- accountId: op.account_id ?? '',
338
- pays: { amount: Number(op.pays.amount ?? 0), asset_id: op.pays.asset_id ?? '' },
339
- receives: { amount: Number(op.receives.amount ?? 0), asset_id: op.receives.asset_id ?? '' },
340
- fee: { amount: Number(op.fee?.amount ?? 0), asset_id: op.fee?.asset_id ?? '' },
341
- isMaker: op.is_maker ?? false,
342
- sort: hit.sort,
343
- });
344
- }
345
- if (hits.length < pageSize)
346
- break;
347
- searchAfter = hits[hits.length - 1].sort;
348
- if (!Array.isArray(searchAfter))
349
- break;
350
- }
351
- return fills;
352
- }
353
- // ─── Fill Classification ─────────────────────────────────────────────────────
354
- function classifyFills(fills, filterAsset) {
355
- const trades = [];
356
- const pairs = new Set();
357
- let skipped = 0;
358
- for (const f of fills) {
359
- const pAsset = f.pays.asset_id;
360
- const rAsset = f.receives.asset_id;
361
- let direction;
362
- let baseAsset;
363
- let quoteAsset;
364
- let baseAmount;
365
- let quoteAmount;
366
- let price;
367
- let marketFeeReal;
368
- let marketFeeAsset;
369
- const feePrec = getPrec(f.fee.asset_id);
370
- if (feePrec === undefined || isNaN(f.fee.amount)) {
371
- skipped++;
372
- continue;
373
- }
374
- const feeReal = f.fee.amount / Math.pow(10, feePrec);
375
- if (pAsset === BTS_ID && rAsset !== BTS_ID) {
376
- direction = 'buy';
377
- baseAsset = rAsset;
378
- quoteAsset = BTS_ID;
379
- baseAmount = toReal(f.receives.amount, rAsset);
380
- quoteAmount = toReal(f.pays.amount, BTS_ID);
381
- if (isNaN(baseAmount) || isNaN(quoteAmount)) {
382
- skipped++;
383
- continue;
384
- }
385
- price = quoteAmount / baseAmount;
386
- marketFeeReal = feeReal;
387
- marketFeeAsset = f.fee.asset_id;
388
- }
389
- else if (rAsset === BTS_ID && pAsset !== BTS_ID) {
390
- direction = 'sell';
391
- baseAsset = pAsset;
392
- quoteAsset = BTS_ID;
393
- baseAmount = toReal(f.pays.amount, pAsset);
394
- quoteAmount = toReal(f.receives.amount, BTS_ID);
395
- if (isNaN(baseAmount) || isNaN(quoteAmount)) {
396
- skipped++;
397
- continue;
398
- }
399
- price = quoteAmount / baseAmount;
400
- marketFeeReal = feeReal;
401
- marketFeeAsset = f.fee.asset_id;
402
- }
403
- else {
404
- // Non-BTS cross-pair: use consistent ordering (lower asset ID = base)
405
- const baseForCheck = pAsset < rAsset ? pAsset : rAsset;
406
- const quoteForCheck = pAsset < rAsset ? rAsset : pAsset;
407
- // Skip if either asset precision is unknown
408
- if (getPrec(baseForCheck) === undefined || getPrec(quoteForCheck) === undefined) {
409
- skipped++;
410
- continue;
411
- }
412
- const isSell = pAsset < rAsset;
413
- direction = isSell ? 'sell' : 'buy';
414
- baseAsset = isSell ? pAsset : rAsset;
415
- quoteAsset = isSell ? rAsset : pAsset;
416
- baseAmount = toReal(isSell ? f.pays.amount : f.receives.amount, baseAsset);
417
- quoteAmount = toReal(isSell ? f.receives.amount : f.pays.amount, quoteAsset);
418
- if (isNaN(baseAmount) || isNaN(quoteAmount)) {
419
- skipped++;
420
- continue;
421
- }
422
- price = quoteAmount / baseAmount;
423
- marketFeeReal = feeReal;
424
- marketFeeAsset = f.fee.asset_id;
425
- }
426
- if (filterAsset && baseAsset !== filterAsset)
427
- continue;
428
- // Validate market fee asset: fee is always deducted from receives
429
- // (base for buys, quote for sells). Warn if unexpected.
430
- if (marketFeeReal > 0 && marketFeeAsset !== '' && marketFeeAsset !== rAsset) {
431
- console.warn(` [warn] Fill ${f.orderId}: fee asset ${marketFeeAsset} ≠ receives asset ${rAsset}. Market fee PnL may be incorrect.`);
432
- }
433
- const pairKey = `${baseAsset}:${quoteAsset}`;
434
- pairs.add(pairKey);
435
- trades.push({
436
- time: f.time,
437
- orderId: f.orderId,
438
- direction,
439
- baseAsset,
440
- quoteAsset,
441
- baseAmount,
442
- quoteAmount,
443
- price,
444
- isMaker: f.isMaker,
445
- sequence: f.blockNum * 1e6 + f.opNum,
446
- marketFeeReal,
447
- marketFeeAsset,
448
- });
449
- }
450
- if (skipped > 0) {
451
- console.warn(` [warn] ${skipped} fill(s) skipped due to unknown asset precision.`);
452
- }
453
- return { trades, pairs };
454
- }
455
- // ─── PnL Calculation (FIFO / Sequential) ─────────────────────────────────────
456
- function analyzePair(trades, matchMode = 'sequential') {
457
- const buys = trades.filter(t => t.direction === 'buy').sort((a, b) => a.sequence - b.sequence);
458
- const sells = trades.filter(t => t.direction === 'sell').sort((a, b) => a.sequence - b.sequence);
459
- const totalBuyBase = buys.reduce((s, t) => s + t.baseAmount, 0);
460
- const totalSellBase = sells.reduce((s, t) => s + t.baseAmount, 0);
461
- const totalBuyQuote = buys.reduce((s, t) => s + t.quoteAmount, 0);
462
- const totalSellQuote = sells.reduce((s, t) => s + t.quoteAmount, 0);
463
- // Merge all trades chronologically.
464
- // FIFO: buys add to queue, sells consume oldest lots (queue front).
465
- // Sequential: buys add to queue, sells consume newest lots (queue back / LIFO).
466
- const all = [...trades].sort((a, b) => a.sequence - b.sequence);
467
- const inventory = [];
468
- const realizedPnls = [];
469
- let unmatchedSellBase = 0;
470
- for (const trade of all) {
471
- const grossPrice = trade.price;
472
- if (trade.direction === 'buy') {
473
- // Enter lot with net amount (gross receives minus market fee on receives)
474
- const lotAmount = trade.baseAmount - trade.marketFeeReal;
475
- if (lotAmount < 1e-12)
476
- continue;
477
- const lotEffPrice = trade.quoteAmount / lotAmount;
478
- inventory.push({
479
- amount: lotAmount,
480
- grossPrice: grossPrice,
481
- effPrice: lotEffPrice,
482
- time: trade.time,
483
- entryOrderId: trade.orderId,
484
- entryIsMaker: trade.isMaker,
485
- });
486
- }
487
- else {
488
- let remaining = trade.baseAmount;
489
- while (remaining > 0.00000001 && inventory.length > 0) {
490
- const lotIndex = matchMode === 'sequential' ? inventory.length - 1 : 0;
491
- const lot = inventory[lotIndex];
492
- const matched = Math.min(remaining, lot.amount);
493
- // Gross PnL using gross prices (before market fee deduction)
494
- const grossPnl = (grossPrice - lot.grossPrice) * matched;
495
- const grossPnlPct = lot.grossPrice > 0 ? ((grossPrice - lot.grossPrice) / lot.grossPrice) * 100 : 0;
496
- realizedPnls.push({
497
- sellPrice: grossPrice,
498
- buyPrice: lot.grossPrice,
499
- amount: matched,
500
- pnl: grossPnl,
501
- pnlPct: grossPnlPct,
502
- effPrice: lot.effPrice,
503
- marketFeeEntry: 0,
504
- marketFeeExit: 0,
505
- feeBts: 0,
506
- pnlNet: grossPnl,
507
- pnlNetPct: grossPnlPct,
508
- entryTime: lot.time,
509
- exitTime: trade.time,
510
- entryOrderId: lot.entryOrderId,
511
- exitOrderId: trade.orderId,
512
- entryIsMaker: lot.entryIsMaker,
513
- exitIsMaker: trade.isMaker,
514
- });
515
- lot.amount -= matched;
516
- remaining -= matched;
517
- if (lot.amount < 0.00000001) {
518
- if (matchMode === 'sequential') {
519
- inventory.pop();
520
- }
521
- else {
522
- inventory.shift();
523
- }
524
- }
525
- }
526
- if (remaining > 0.00000001) {
527
- unmatchedSellBase += remaining;
528
- }
529
- }
530
- }
531
- // ─── Market fee allocation (aggregated per order) ──────────────────────
532
- // A limit order may be filled across multiple fill_order_operations with
533
- // the same orderId. Aggregate all fills' market fees per order, then
534
- // allocate pro-rata using the fill's net acquired amount as denominator.
535
- // (Market fee is paid on acquisition; the portion tied to unsold inventory
536
- // is not yet realised.)
537
- const entryOrderFees = new Map();
538
- const exitOrderFees = new Map();
539
- for (const t of buys) {
540
- const e = entryOrderFees.get(t.orderId) || { feeInQuote: 0, totalAcquired: 0 };
541
- if (t.marketFeeReal > 0) {
542
- // Buy-side fee is in base → convert to quote using effective price
543
- const netBase = t.baseAmount - t.marketFeeReal;
544
- e.feeInQuote += netBase > 0 ? t.marketFeeReal * (t.quoteAmount / netBase) : 0;
545
- }
546
- e.totalAcquired += t.baseAmount - t.marketFeeReal;
547
- entryOrderFees.set(t.orderId, e);
548
- }
549
- for (const t of sells) {
550
- const e = exitOrderFees.get(t.orderId) || { feeInQuote: 0, totalDisposed: 0 };
551
- if (t.marketFeeReal > 0)
552
- e.feeInQuote += t.marketFeeReal; // Sell-side fee is already in quote
553
- e.totalDisposed += t.baseAmount;
554
- exitOrderFees.set(t.orderId, e);
555
- }
556
- for (const r of realizedPnls) {
557
- const eObj = entryOrderFees.get(r.entryOrderId);
558
- if (eObj && eObj.totalAcquired > 0)
559
- r.marketFeeEntry = eObj.feeInQuote * (r.amount / eObj.totalAcquired);
560
- const xObj = exitOrderFees.get(r.exitOrderId);
561
- if (xObj && xObj.totalDisposed > 0)
562
- r.marketFeeExit = xObj.feeInQuote * (r.amount / xObj.totalDisposed);
563
- r.pnlNet = r.pnl - r.marketFeeEntry - r.marketFeeExit;
564
- r.pnlNetPct = r.buyPrice > 0 ? (r.pnlNet / (r.buyPrice * r.amount)) * 100 : 0;
565
- }
566
- // ─── Blockchain fee allocation ─────────────────────────────────────────
567
- const buyOrderIds = new Set(buys.map(t => t.orderId));
568
- const sellOrderIds = new Set(sells.map(t => t.orderId));
569
- const entryTotalMatched = new Map();
570
- const exitTotalMatched = new Map();
571
- for (const r of realizedPnls) {
572
- entryTotalMatched.set(r.entryOrderId, (entryTotalMatched.get(r.entryOrderId) || 0) + r.amount);
573
- exitTotalMatched.set(r.exitOrderId, (exitTotalMatched.get(r.exitOrderId) || 0) + r.amount);
574
- }
575
- const totalBlockchainFees = (buyOrderIds.size + sellOrderIds.size) * BLOCKCHAIN_FEE_PER_FILL;
576
- for (const r of realizedPnls) {
577
- const eTotal = entryTotalMatched.get(r.entryOrderId) || 1;
578
- const xTotal = exitTotalMatched.get(r.exitOrderId) || 1;
579
- r.feeBts = BLOCKCHAIN_FEE_PER_FILL * (r.amount / eTotal) + BLOCKCHAIN_FEE_PER_FILL * (r.amount / xTotal);
580
- r.pnlNet -= r.feeBts;
581
- const costBasis = r.effPrice * r.amount;
582
- r.pnlNetPct = costBasis > 0 ? (r.pnlNet / costBasis) * 100 : 0;
583
- }
584
- const totalBuyBaseNet = buys.reduce((s, t) => s + t.baseAmount - t.marketFeeReal, 0);
585
- const totalRealizedPnl = realizedPnls.reduce((s, r) => s + r.pnl, 0);
586
- const totalMarketFees = realizedPnls.reduce((s, r) => s + r.marketFeeEntry + r.marketFeeExit, 0);
587
- const totalRealizedPnlNet = realizedPnls.reduce((s, r) => s + r.pnlNet, 0);
588
- const netPosition = totalBuyBaseNet - totalSellBase;
589
- const baseAsset = trades[0]?.baseAsset ?? '';
590
- const quoteAsset = trades[0]?.quoteAsset ?? '';
591
- return {
592
- baseAsset,
593
- quoteAsset,
594
- buys,
595
- sells,
596
- realizedPnls,
597
- totalBuyBase,
598
- totalSellBase,
599
- totalBuyQuote,
600
- totalSellQuote,
601
- unmatchedSellBase,
602
- totalRealizedPnl,
603
- totalMarketFees,
604
- totalBlockchainFees,
605
- totalRealizedPnlNet,
606
- netPosition,
607
- };
608
- }
609
- // ─── Output Helpers ──────────────────────────────────────────────────────────
610
- function fmt(n, decimals = 4) {
611
- if (!Number.isFinite(n))
612
- return 'NaN';
613
- return n.toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
614
- }
615
- function fmtPct(n) {
616
- if (!Number.isFinite(n))
617
- return 'NaN%';
618
- return (n >= 0 ? '+' : '') + n.toFixed(2) + '%';
619
- }
620
- function fmtAsset(id) {
621
- return assetSymbol(id);
622
- }
623
- function printSummary(pairs, accountId, start, end, matchMode = 'sequential') {
624
- console.log('');
625
- for (const pair of pairs) {
626
- const pairLabel = `${fmtAsset(pair.baseAsset)}/${fmtAsset(pair.quoteAsset)}`;
627
- const totalBought = pair.totalBuyBase;
628
- const totalSold = pair.totalSellBase;
629
- const avgBuy = pair.totalBuyBase > 0 ? pair.totalBuyQuote / pair.totalBuyBase : 0;
630
- const avgSell = pair.totalSellBase > 0 ? pair.totalSellQuote / pair.totalSellBase : 0;
631
- console.log(` ── ${pairLabel}`);
632
- console.log(` Buys: ${fmt(totalBought, 4)} @ ${fmt(avgBuy, 6)} = ${fmt(pair.totalBuyQuote, 4)} ${fmtAsset(pair.quoteAsset)}`);
633
- console.log(` Sells: ${fmt(totalSold, 4)} @ ${fmt(avgSell, 6)} = ${fmt(pair.totalSellQuote, 4)} ${fmtAsset(pair.quoteAsset)}`);
634
- console.log(` Net traded: ${fmt(pair.netPosition, 4)} ${fmtAsset(pair.baseAsset)} (window flow)`);
635
- console.log(` Trades: ${pair.realizedPnls.length} matched lots, ${pair.buys.length} buys, ${pair.sells.length} sells`);
636
- if (pair.unmatchedSellBase > 0.0001) {
637
- console.log(` Unmatched: ${fmt(pair.unmatchedSellBase, 4)} ${fmtAsset(pair.baseAsset)} (sold without prior buy in window — expected if inventory predates window)`);
638
- }
639
- console.log(` Gross PnL: ${fmtAsset(pair.quoteAsset)} ${fmt(pair.totalRealizedPnl, 4)}`);
640
- const mktFee = pair.totalMarketFees;
641
- const blkFee = pair.totalBlockchainFees;
642
- if (mktFee > 0.0001) {
643
- console.log(` Market fees: ${fmtAsset(pair.quoteAsset)} ${fmt(-mktFee, 4)}`);
644
- }
645
- if (blkFee > 0.0001) {
646
- console.log(` Blockchain: BTS ${fmt(-blkFee, 4)}`);
647
- }
648
- console.log(` Net PnL: ${fmtAsset(pair.quoteAsset)} ${fmt(pair.totalRealizedPnlNet, 4)}`);
649
- if (pair.quoteAsset !== BTS_ID) {
650
- console.log(` ⚠ Non-BTS quote — PnL is in ${fmtAsset(pair.quoteAsset)}, not BTS`);
651
- }
652
- console.log('');
653
- }
654
- // Grand totals grouped by quote asset
655
- const quoteGroups = new Map();
656
- for (const p of pairs) {
657
- const q = p.quoteAsset;
658
- if (!quoteGroups.has(q))
659
- quoteGroups.set(q, []);
660
- quoteGroups.get(q).push(p);
661
- }
662
- if (pairs.length > 1 && quoteGroups.size > 0) {
663
- for (const [quoteAsset, group] of quoteGroups) {
664
- const groupPnl = group.reduce((s, p) => s + p.totalRealizedPnl, 0);
665
- const groupMktFees = group.reduce((s, p) => s + p.totalMarketFees, 0);
666
- const groupBlkFees = group.reduce((s, p) => s + p.totalBlockchainFees, 0);
667
- const groupNet = group.reduce((s, p) => s + p.totalRealizedPnlNet, 0);
668
- const groupVol = group.reduce((s, p) => s + p.totalBuyQuote + p.totalSellQuote, 0);
669
- const qSymbol = fmtAsset(quoteAsset);
670
- console.log(` ── TOTAL (${qSymbol}) — ${group.length} pair(s)`);
671
- console.log(` Gross PnL: ${fmtAsset(quoteAsset)} ${fmt(groupPnl, 4)}`);
672
- if (groupMktFees > 0.0001) {
673
- console.log(` Market fees: ${fmtAsset(quoteAsset)} ${fmt(-groupMktFees, 4)}`);
674
- }
675
- if (groupBlkFees > 0.0001) {
676
- console.log(` Blockchain: BTS ${fmt(-groupBlkFees, 4)}`);
677
- }
678
- console.log(` Net PnL: ${fmtAsset(quoteAsset)} ${fmt(groupNet, 4)}`);
679
- console.log(` Volume: ${fmt(groupVol, 4)} ${qSymbol}`);
680
- console.log('');
681
- }
682
- }
683
- console.log(` Note: PnL uses gross prices. Net PnL deducts market fees (charged by`);
684
- console.log(` asset issuer on receives, both issuer and network portions) and`);
685
- console.log(` blockchain operation fees (BTS per limit_order_create). Market`);
686
- console.log(` fees are converted to quote asset. Buy lots are entered at net`);
687
- console.log(` receives (gross minus buy-side market fee) so inventory matching`);
688
- console.log(` reflects what the account actually held. If inventory predates the`);
689
- console.log(` window or crosses asset pairs, the matched lots may not reflect`);
690
- console.log(` true trade economics.`);
691
- console.log('');
692
- }
693
- function printPnlDetail(pairs) {
694
- for (const pair of pairs) {
695
- if (pair.realizedPnls.length === 0)
696
- continue;
697
- const pairLabel = `${fmtAsset(pair.baseAsset)}/${fmtAsset(pair.quoteAsset)}`;
698
- console.log('');
699
- console.log(` ── ${pairLabel} — Realized PnL Detail`);
700
- console.log('');
701
- const hdr = ' # Buy Price EffBuy Sell Price Amount PnL PnL% MktFee OpFeeBTS Net PnL Net% Legs Entry Time Exit Time';
702
- console.log(hdr);
703
- console.log(' ' + '─'.repeat(hdr.length - 1));
704
- for (let i = 0; i < pair.realizedPnls.length; i++) {
705
- const r = pair.realizedPnls[i];
706
- const idx = String(i + 1).padStart(2);
707
- const bp = fmt(r.buyPrice, 8).padStart(11);
708
- const ep = fmt(r.effPrice, 8).padStart(11);
709
- const sp = fmt(r.sellPrice, 8).padStart(11);
710
- const amt = fmt(r.amount, 4).padStart(9);
711
- const pnlStr = fmt(r.pnl, 6).padStart(9);
712
- const pctStr = fmtPct(r.pnlPct).padStart(8);
713
- const mktFeeStr = fmt(r.marketFeeEntry + r.marketFeeExit, 4).padStart(8);
714
- const feeStr = fmt(r.feeBts, 4).padStart(8);
715
- const netStr = fmt(r.pnlNet, 6).padStart(10);
716
- const netPctStr = fmtPct(r.pnlNetPct).padStart(8);
717
- const mk = (r.entryIsMaker ? 'M' : 'T') + '/' + (r.exitIsMaker ? 'M' : 'T') + ' ';
718
- const et = (r.entryTime || '').slice(0, 22).padEnd(22);
719
- const xt = (r.exitTime || '').slice(0, 22).padEnd(22);
720
- console.log(` ${idx} ${bp} ${ep} ${sp} ${amt} ${pnlStr} ${pctStr} ${mktFeeStr} ${feeStr} ${netStr} ${netPctStr} ${mk} ${et} ${xt}`);
721
- }
722
- console.log('');
723
- }
724
- }
725
- function percentile(sorted, p) {
726
- const n = sorted.length;
727
- if (n === 0)
728
- return 0;
729
- if (n === 1)
730
- return sorted[0];
731
- const k = (p / 100) * (n - 1);
732
- const f = Math.floor(k);
733
- const c = Math.ceil(k);
734
- if (f === c)
735
- return sorted[f];
736
- return sorted[f] * (c - k) + sorted[c] * (k - f);
737
- }
738
- function computeMetrics(pair) {
739
- const pnls = pair.realizedPnls;
740
- const total = pnls.length;
741
- if (total === 0) {
742
- return {
743
- totalLots: 0, winRate: 0, profitFactor: 0,
744
- avgWin: 0, avgLoss: 0, avgWinLossRatio: 0,
745
- expectancyBts: 0, expectancyPct: 0, expectancyR: 0,
746
- netExpectancyBts: 0,
747
- dailyPnlRatio: 0, dailyDownsideRatio: 0,
748
- maxConsecWins: 0, maxConsecLosses: 0,
749
- avgHoldHours: 0, limitOrderRatio: 0,
750
- bestTradePct: 0, worstTradePct: 0,
751
- mddPct: 0,
752
- mddHadStablePeak: false,
753
- isOngoingRecovery: false,
754
- currentDrawdownDays: 0,
755
- medianPnlPct: 0, p25PnlPct: 0, p75PnlPct: 0,
756
- feeDragPct: 0, maxRecoveryDays: 0,
757
- medianR: 0, pctRGreater1: 0, pctRGreater2: 0, pctRLessNeg1: 0,
758
- sellOrdersFilled: 0, fillsPerOrderMean: 0, fillsPerOrderMedian: 0,
759
- fillsPerOrderMax: 0, oneShotOrderRatio: 0, fillsPerDay: 0, avgVolumePerDay: 0,
760
- };
761
- }
762
- const wins = pnls.filter(r => r.pnl > 0);
763
- const losses = pnls.filter(r => r.pnl < 0);
764
- const winRate = wins.length / total;
765
- const makerEntryCount = pnls.filter(r => r.entryIsMaker).length;
766
- const makerExitCount = pnls.filter(r => r.exitIsMaker).length;
767
- const totalMakerLegs = makerEntryCount + makerExitCount;
768
- const grossProfit = wins.reduce((s, r) => s + r.pnl, 0);
769
- const grossLoss = Math.abs(losses.reduce((s, r) => s + r.pnl, 0));
770
- const profitFactor = grossLoss > 0 ? grossProfit / grossLoss : grossProfit > 0 ? Infinity : 0;
771
- const totalFeeDrag = pair.totalMarketFees + pair.totalBlockchainFees;
772
- const feeDragPct = grossProfit > 0 ? (totalFeeDrag / grossProfit) * 100 : 0;
773
- const avgWin = wins.length > 0 ? grossProfit / wins.length : 0;
774
- const avgLoss = losses.length > 0 ? losses.reduce((s, r) => s + r.pnl, 0) / losses.length : 0;
775
- const avgWinPct = wins.length > 0 ? wins.reduce((s, r) => s + r.pnlPct, 0) / wins.length : 0;
776
- const avgLossPct = losses.length > 0 ? losses.reduce((s, r) => s + r.pnlPct, 0) / losses.length : 0;
777
- const avgWinLossRatio = avgLoss !== 0 ? avgWin / Math.abs(avgLoss) : avgWin > 0 ? Infinity : 0;
778
- const expectancyBts = (winRate * avgWin) + ((1 - winRate) * avgLoss);
779
- const expectancyPct = (winRate * avgWinPct) + ((1 - winRate) * avgLossPct);
780
- const rMultiple = Math.abs(avgLoss);
781
- const expectancyR = rMultiple > 0
782
- ? winRate * (avgWin / rMultiple) - (1 - winRate)
783
- : Infinity;
784
- const netExpectancyBts = pair.totalRealizedPnlNet / total;
785
- // Daily-binned net PnL for mean/std ratio (dimensionful — not a Sharpe ratio)
786
- const dayBuckets = {};
787
- for (const r of pnls) {
788
- const day = r.exitTime.slice(0, 10);
789
- dayBuckets[day] = (dayBuckets[day] || 0) + r.pnlNet;
790
- }
791
- const dailyRets = Object.values(dayBuckets);
792
- const nDays = dailyRets.length;
793
- const meanDailyRet = nDays > 0 ? dailyRets.reduce((s, v) => s + v, 0) / nDays : 0;
794
- const dailyVar = nDays > 0
795
- ? dailyRets.reduce((s, v) => s + (v - meanDailyRet) ** 2, 0) / nDays
796
- : 0;
797
- const dailyStd = Math.sqrt(dailyVar);
798
- const annFactor = Math.sqrt(365);
799
- const dailyPnlRatio = dailyStd > 0 ? (meanDailyRet / dailyStd) * annFactor : 0;
800
- // Downside deviation uses only negative returns; same N denominator
801
- const downsideVar = nDays > 0
802
- ? dailyRets.reduce((s, v) => s + (v < 0 ? v * v : 0), 0) / nDays
803
- : 0;
804
- const downsideStd = Math.sqrt(downsideVar);
805
- const dailyDownsideRatio = downsideStd > 0 ? (meanDailyRet / downsideStd) * annFactor : 0;
806
- // Fills-per-order distribution (grouped by sell order)
807
- const fillCounts = [];
808
- const orderMap = new Map();
809
- for (const r of pnls) {
810
- orderMap.set(r.exitOrderId, (orderMap.get(r.exitOrderId) || 0) + 1);
811
- }
812
- for (const c of orderMap.values())
813
- fillCounts.push(c);
814
- const sellOrdersFilled = orderMap.size;
815
- const fillsPerOrderMean = sellOrdersFilled > 0
816
- ? fillCounts.reduce((s, v) => s + v, 0) / sellOrdersFilled
817
- : 0;
818
- const fillsPerOrderMax = sellOrdersFilled > 0
819
- ? fillCounts.reduce((a, b) => Math.max(a, b), 0)
820
- : 0;
821
- const sortedCounts = [...fillCounts].sort((a, b) => a - b);
822
- const fillsPerOrderMedian = sellOrdersFilled > 0 ? percentile(sortedCounts, 50) : 0;
823
- const oneShotOrderRatio = sellOrdersFilled > 0
824
- ? fillCounts.filter(c => c === 1).length / sellOrdersFilled
825
- : 0;
826
- const fillsPerDay = nDays > 0 ? total / nDays : 0;
827
- const avgVolumePerDay = nDays > 0 ? (pair.totalBuyQuote + pair.totalSellQuote) / nDays : 0;
828
- // Avg hold duration
829
- let totalHours = 0;
830
- let hourCount = 0;
831
- for (const r of pnls) {
832
- const entry = new Date(r.entryTime).getTime();
833
- const exit = new Date(r.exitTime).getTime();
834
- if (!isNaN(entry) && !isNaN(exit) && exit > entry) {
835
- totalHours += (exit - entry) / 3600000;
836
- hourCount++;
837
- }
838
- }
839
- const avgHoldHours = hourCount > 0 ? totalHours / hourCount : 0;
840
- // Max consecutive wins / losses (aggregated by exit order)
841
- const orderPnls = new Map();
842
- for (const r of pnls) {
843
- const existing = orderPnls.get(r.exitOrderId);
844
- if (existing) {
845
- existing.pnl += r.pnl;
846
- }
847
- else {
848
- orderPnls.set(r.exitOrderId, { pnl: r.pnl, time: r.exitTime });
849
- }
850
- }
851
- const orderResults = [...orderPnls.values()].sort((a, b) => new Date(a.time).getTime() - new Date(b.time).getTime());
852
- let consecW = 0, consecL = 0;
853
- let maxW = 0, maxL = 0;
854
- for (const { pnl } of orderResults) {
855
- if (pnl > 0) {
856
- consecW++;
857
- consecL = 0;
858
- maxW = Math.max(maxW, consecW);
859
- }
860
- else if (pnl < 0) {
861
- consecL++;
862
- consecW = 0;
863
- maxL = Math.max(maxL, consecL);
864
- }
865
- else {
866
- consecW = 0;
867
- consecL = 0;
868
- }
869
- }
870
- // ─── Max Drawdown + Recovery Time ───────────────────────────────────
871
- const STABILITY_TRADES = 3;
872
- const MIN_TRADES_FOR_PEAK = 10; // backstop for monotonic equity curves
873
- const chronological = [...pnls].sort((a, b) => new Date(a.exitTime).getTime() - new Date(b.exitTime).getTime());
874
- let equity = 0, peak = 0, mddPct = 0;
875
- let maxRecoveryDays = 0;
876
- let isOngoingRecovery = false;
877
- let currentDrawdownDays = 0;
878
- let drawdownStartTime = 0;
879
- let troughTime = 0;
880
- let currentTroughEquity = Infinity;
881
- let hadStablePeak = false;
882
- let tradesSincePeakSet = 0;
883
- let hasPrePeakEquity = false;
884
- let prePeakMinEquity = 0;
885
- let totalTradesProcessed = 0;
886
- for (const r of chronological) {
887
- totalTradesProcessed++;
888
- equity += r.pnlNet;
889
- if (equity > peak) {
890
- if (troughTime > 0 && hadStablePeak) {
891
- const recoveryDays = (new Date(r.exitTime).getTime() - troughTime) / 86400000;
892
- if (recoveryDays > maxRecoveryDays)
893
- maxRecoveryDays = recoveryDays;
894
- }
895
- peak = equity;
896
- tradesSincePeakSet = 0;
897
- currentTroughEquity = Infinity;
898
- troughTime = 0;
899
- drawdownStartTime = 0;
900
- }
901
- else {
902
- tradesSincePeakSet++;
903
- if (tradesSincePeakSet >= STABILITY_TRADES) {
904
- hadStablePeak = true;
905
- }
906
- }
907
- if (!hadStablePeak && totalTradesProcessed >= MIN_TRADES_FOR_PEAK) {
908
- hadStablePeak = true;
909
- }
910
- if (hadStablePeak && equity < peak && peak > 0) {
911
- if (drawdownStartTime === 0)
912
- drawdownStartTime = new Date(r.exitTime).getTime();
913
- if (equity < currentTroughEquity) {
914
- currentTroughEquity = equity;
915
- troughTime = new Date(r.exitTime).getTime();
916
- }
917
- const dd = (equity - peak) / peak;
918
- if (dd < mddPct)
919
- mddPct = dd;
920
- }
921
- if (peak > 0 && !hadStablePeak) {
922
- if (!hasPrePeakEquity || equity < prePeakMinEquity) {
923
- prePeakMinEquity = equity;
924
- hasPrePeakEquity = true;
925
- }
926
- }
927
- }
928
- if (drawdownStartTime > 0 && hadStablePeak) {
929
- const lastTime = new Date(chronological[chronological.length - 1].exitTime).getTime();
930
- currentDrawdownDays = (lastTime - drawdownStartTime) / 86400000;
931
- isOngoingRecovery = true;
932
- if (currentDrawdownDays > maxRecoveryDays) {
933
- maxRecoveryDays = currentDrawdownDays;
934
- }
935
- }
936
- if (hadStablePeak) {
937
- mddPct *= 100;
938
- }
939
- else {
940
- mddPct = hasPrePeakEquity ? prePeakMinEquity : 0;
941
- }
942
- // Payoff distribution stats
943
- const pnlPcts = [...pnls.map(r => r.pnlPct)].sort((a, b) => a - b);
944
- const medianPnlPct = percentile(pnlPcts, 50);
945
- const p25PnlPct = percentile(pnlPcts, 25);
946
- const p75PnlPct = percentile(pnlPcts, 75);
947
- const absAvgLoss = Math.abs(avgLoss);
948
- let rValues = [];
949
- if (absAvgLoss > 0) {
950
- rValues = pnls.map(r => r.pnl / absAvgLoss).sort((a, b) => a - b);
951
- }
952
- const medianR = rValues.length > 0 ? percentile(rValues, 50) : 0;
953
- const pctRGreater1 = rValues.length > 0 ? rValues.filter(r => r > 1).length / rValues.length : 0;
954
- const pctRGreater2 = rValues.length > 0 ? rValues.filter(r => r > 2).length / rValues.length : 0;
955
- const pctRLessNeg1 = rValues.length > 0 ? rValues.filter(r => r < -1).length / rValues.length : 0;
956
- const bestTradePct = pnlPcts.length > 0 ? pnlPcts[pnlPcts.length - 1] : 0;
957
- const worstTradePct = pnlPcts.length > 0 ? pnlPcts[0] : 0;
958
- return {
959
- totalLots: total,
960
- winRate,
961
- profitFactor,
962
- avgWin,
963
- avgLoss,
964
- avgWinLossRatio,
965
- expectancyBts,
966
- expectancyPct,
967
- expectancyR,
968
- netExpectancyBts,
969
- dailyPnlRatio,
970
- dailyDownsideRatio,
971
- feeDragPct,
972
- maxConsecWins: maxW,
973
- maxConsecLosses: maxL,
974
- avgHoldHours,
975
- limitOrderRatio: total > 0 ? totalMakerLegs / (total * 2) : 0,
976
- bestTradePct,
977
- worstTradePct,
978
- mddPct,
979
- mddHadStablePeak: hadStablePeak,
980
- isOngoingRecovery,
981
- currentDrawdownDays,
982
- maxRecoveryDays,
983
- medianPnlPct,
984
- p25PnlPct,
985
- p75PnlPct,
986
- medianR,
987
- pctRGreater1,
988
- pctRGreater2,
989
- pctRLessNeg1,
990
- sellOrdersFilled,
991
- fillsPerOrderMean,
992
- fillsPerOrderMedian,
993
- fillsPerOrderMax,
994
- oneShotOrderRatio,
995
- fillsPerDay,
996
- avgVolumePerDay,
997
- };
998
- }
999
- function printMetrics(pairs) {
1000
- for (const pair of pairs) {
1001
- if (pair.realizedPnls.length === 0)
1002
- continue;
1003
- const m = computeMetrics(pair);
1004
- const pairLabel = `${fmtAsset(pair.baseAsset)}/${fmtAsset(pair.quoteAsset)}`;
1005
- console.log('');
1006
- console.log(` ── ${pairLabel} — Performance Metrics`);
1007
- console.log('');
1008
- // Edge
1009
- console.log(` Win Rate: ${(m.winRate * 100).toFixed(1)}%`);
1010
- console.log(` Profit Factor: ${m.profitFactor === Infinity ? '∞' : m.profitFactor.toFixed(2)}`);
1011
- const mktFeeStr = pair.totalMarketFees > 0.0001 ? ` (market ${fmt(pair.totalMarketFees, 4)})` : '';
1012
- const blkFeeStr = pair.totalBlockchainFees > 0.0001 ? ` (op ${fmt(pair.totalBlockchainFees, 4)} BTS)` : '';
1013
- console.log(` Fee Drag: ${m.feeDragPct > 0 ? m.feeDragPct.toFixed(2) + '% of gross profit' + mktFeeStr + blkFeeStr : '—'}`);
1014
- console.log(` Avg Win / Avg Loss: ${m.avgWinLossRatio === Infinity ? '∞' : m.avgWinLossRatio.toFixed(2)}`);
1015
- const qSymbol = fmtAsset(pair.quoteAsset);
1016
- console.log(` Expectancy (gross): ${fmt(m.expectancyBts, 4)} ${qSymbol} (${fmtPct(m.expectancyPct)}) per trade`);
1017
- const rDisplay = m.expectancyR === Infinity ? '∞' : m.expectancyR.toFixed(3) + 'R';
1018
- console.log(` Expectancy (R): ${rDisplay}`);
1019
- console.log(` Expectancy (net): ${fmt(m.netExpectancyBts, 4)} ${qSymbol} per trade`);
1020
- console.log('');
1021
- // Edge quality
1022
- console.log(` Median R: ${m.medianR.toFixed(2)}`);
1023
- console.log(` Trades > 1R / > 2R: ${(m.pctRGreater1 * 100).toFixed(1)}% / ${(m.pctRGreater2 * 100).toFixed(1)}%`);
1024
- console.log(` Trades < -1R: ${(m.pctRLessNeg1 * 100).toFixed(1)}%`);
1025
- console.log('');
1026
- // PnL distribution
1027
- console.log(` Median PnL: ${fmtPct(m.medianPnlPct)}`);
1028
- console.log(` P25 / P75: ${fmtPct(m.p25PnlPct)} / ${fmtPct(m.p75PnlPct)}`);
1029
- console.log(` Best / Worst Trade: ${fmtPct(m.bestTradePct)} / ${fmtPct(m.worstTradePct)}`);
1030
- console.log('');
1031
- // Risk-adjusted (dimensionful — based on absolute daily PnL, not % returns)
1032
- console.log(` Sharpe (ann): ${m.dailyPnlRatio.toFixed(2)}`);
1033
- console.log(` Sortino (ann): ${m.dailyDownsideRatio.toFixed(2)}`);
1034
- console.log('');
1035
- // Tail risk
1036
- if (m.mddHadStablePeak) {
1037
- console.log(` Max Drawdown: ${fmtPct(m.mddPct)}`);
1038
- }
1039
- else {
1040
- console.log(` Min Equity: ${fmt(m.mddPct, 4)} ${fmtAsset(pair.quoteAsset)}`);
1041
- }
1042
- const recLabel = m.maxRecoveryDays > 0 ? m.maxRecoveryDays.toFixed(1) + ' days' + (m.isOngoingRecovery ? ' (ongoing)' : '') : '—';
1043
- console.log(` Max Recovery Time: ${recLabel}`);
1044
- if (m.currentDrawdownDays > 0) {
1045
- console.log(` Current Drawdown: ${m.currentDrawdownDays.toFixed(1)} days (active)`);
1046
- }
1047
- console.log('');
1048
- // Behavioral
1049
- console.log(` Max Consecutive W/L: ${m.maxConsecWins} / ${m.maxConsecLosses}`);
1050
- const holdDisplay = m.avgHoldHours > 0 ? m.avgHoldHours.toFixed(1) : '—';
1051
- console.log(` Avg hold time: ${holdDisplay} hours`);
1052
- console.log(` Maker / Taker: ${(m.limitOrderRatio * 100).toFixed(1)}% / ${((1 - m.limitOrderRatio) * 100).toFixed(1)}%`);
1053
- console.log('');
1054
- // Activity
1055
- console.log(` Sell orders filled: ${m.sellOrdersFilled}`);
1056
- console.log(` Partial fills/order: ${m.fillsPerOrderMean.toFixed(2)} mean, ${m.fillsPerOrderMedian.toFixed(1)} med, ${m.fillsPerOrderMax} max`);
1057
- console.log(` One-shot orders: ${(m.oneShotOrderRatio * 100).toFixed(0)}%`);
1058
- console.log(` Fills/day: ${m.fillsPerDay.toFixed(2)}`);
1059
- console.log(` Avg vol/day: ${fmt(m.avgVolumePerDay, 2)} ${fmtAsset(pair.quoteAsset)}`);
1060
- console.log('');
1061
- }
1062
- // Grand totals grouped by quote asset
1063
- const quoteGroups = new Map();
1064
- for (const p of pairs) {
1065
- const q = p.quoteAsset;
1066
- if (!quoteGroups.has(q))
1067
- quoteGroups.set(q, []);
1068
- quoteGroups.get(q).push(p);
1069
- }
1070
- if (pairs.length > 1 && quoteGroups.size > 0) {
1071
- for (const [quoteAsset, group] of quoteGroups) {
1072
- const totalLots = group.reduce((s, p) => s + p.realizedPnls.length, 0);
1073
- const totalNet = group.reduce((s, p) => s + p.totalRealizedPnlNet, 0);
1074
- const totalMktFees = group.reduce((s, p) => s + p.totalMarketFees, 0);
1075
- const totalBlkFees = group.reduce((s, p) => s + p.totalBlockchainFees, 0);
1076
- const qSymbol = fmtAsset(quoteAsset);
1077
- console.log(` ── TOTAL (${qSymbol}) — ${group.length} pair(s)`);
1078
- console.log(` Lots: ${totalLots}`);
1079
- const feeParts = [];
1080
- if (totalMktFees > 0.0001)
1081
- feeParts.push(`market ${fmt(totalMktFees, 4)} ${qSymbol}`);
1082
- if (totalBlkFees > 0.0001)
1083
- feeParts.push(`op ${fmt(totalBlkFees, 4)} BTS`);
1084
- const feeSuffix = feeParts.length > 0 ? ` (${feeParts.join(', ')})` : '';
1085
- console.log(` Net PnL: ${fmtAsset(quoteAsset)} ${fmt(totalNet, 4)}${feeSuffix}`);
1086
- console.log('');
1087
- }
1088
- }
1089
- }
1090
- // ─── CSV Export ──────────────────────────────────────────────────────────────
1091
- function exportCsv(pairs, filePath) {
1092
- const esc = (v) => { const s = String(v); return /[,"\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s; };
1093
- const lines = ['time,orderId,direction,baseAsset,quoteAsset,baseAmount,quoteAmount,price,isMaker,marketFeeReal,marketFeeAsset'];
1094
- for (const pair of pairs) {
1095
- for (const t of [...pair.buys, ...pair.sells].sort((a, b) => a.sequence - b.sequence)) {
1096
- lines.push([
1097
- esc(t.time),
1098
- esc(t.orderId),
1099
- esc(t.direction),
1100
- esc(t.baseAsset),
1101
- esc(t.quoteAsset),
1102
- t.baseAmount,
1103
- t.quoteAmount,
1104
- t.price,
1105
- t.isMaker ? '1' : '0',
1106
- t.marketFeeReal,
1107
- esc(t.marketFeeAsset),
1108
- ].join(','));
1109
- }
1110
- }
1111
- node_fs_1.default.writeFileSync(filePath, lines.join('\n'), 'utf-8');
1112
- console.log(` Trades exported to ${filePath}`);
1113
- }
1114
- // ─── JSON Export ─────────────────────────────────────────────────────────────
1115
- function exportJson(accountId, start, end, pairs, filePath) {
1116
- const data = {
1117
- accountId,
1118
- period: { start, end },
1119
- pairs: pairs.map(p => ({
1120
- baseAsset: p.baseAsset,
1121
- quoteAsset: p.quoteAsset,
1122
- summary: {
1123
- totalBuyBase: p.totalBuyBase,
1124
- totalSellBase: p.totalSellBase,
1125
- totalBuyQuote: p.totalBuyQuote,
1126
- totalSellQuote: p.totalSellQuote,
1127
- netPosition: p.netPosition,
1128
- totalRealizedPnl: p.totalRealizedPnl,
1129
- totalMarketFees: p.totalMarketFees,
1130
- totalBlockchainFees: p.totalBlockchainFees,
1131
- totalRealizedPnlNet: p.totalRealizedPnlNet,
1132
- },
1133
- realizedPnls: p.realizedPnls.map(r => ({
1134
- ...r,
1135
- marketFeeEntry: r.marketFeeEntry,
1136
- marketFeeExit: r.marketFeeExit,
1137
- feeBts: r.feeBts,
1138
- pnlNet: r.pnlNet,
1139
- pnlNetPct: r.pnlNetPct,
1140
- })),
1141
- totalBuys: p.buys.length,
1142
- totalSells: p.sells.length,
1143
- })),
1144
- };
1145
- node_fs_1.default.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
1146
- console.log(` Full analysis exported to ${filePath}`);
1147
- }
1148
- // ─── Main ────────────────────────────────────────────────────────────────────
1149
- async function run() {
1150
- const opts = parseArgs();
1151
- let accountId = opts.accountId;
1152
- if (opts.lookup) {
1153
- const resolved = await resolveAccountId(accountId, opts.node);
1154
- if (!resolved) {
1155
- console.error(` Could not resolve "${accountId}" to an account ID`);
1156
- process.exit(1);
1157
- }
1158
- accountId = resolved;
1159
- }
1160
- // Build time range
1161
- const now = new Date();
1162
- let gte, lte;
1163
- if (opts.start && opts.end) {
1164
- gte = opts.start;
1165
- lte = opts.end;
1166
- }
1167
- else if (opts.start) {
1168
- gte = opts.start;
1169
- lte = now.toISOString();
1170
- }
1171
- else {
1172
- const hours = opts.hours || 168;
1173
- const start = new Date(now.getTime() - hours * 3600 * 1000);
1174
- gte = start.toISOString();
1175
- lte = now.toISOString();
1176
- }
1177
- // Ensure times end with Z for ES
1178
- if (!gte.endsWith('Z'))
1179
- gte += gte.includes('T') ? 'Z' : 'T00:00:00Z';
1180
- if (!lte.endsWith('Z'))
1181
- lte += lte.includes('T') ? 'Z' : 'T00:00:00Z';
1182
- const KIBANA_CFG = { timeout: 60000 };
1183
- const fills = await fetchAllFills(KIBANA_CFG, accountId, gte, lte);
1184
- if (fills.length === 0) {
1185
- console.log(' No fills found in the specified time range.');
1186
- process.exit(0);
1187
- }
1188
- // Resolve unknown asset precisions from blockchain
1189
- await resolveAssetPrecisions(fills, opts.node);
1190
- // Classify fills
1191
- const { trades, pairs } = classifyFills(fills, opts.asset);
1192
- if (trades.length === 0) {
1193
- console.log(' No trades could be classified (check asset filter or time range).');
1194
- process.exit(0);
1195
- }
1196
- console.log(`Account: ${accountId}`);
1197
- console.log(`Period: ${gte.slice(0, 10)} → ${lte.slice(0, 10)}`);
1198
- console.log(`Pairs: ${pairs.size}, ${trades.length} classified trades`);
1199
- const hasCrossPair = [...pairs].some(p => p.split(':')[1] !== BTS_ID);
1200
- if (hasCrossPair) {
1201
- console.log(` Note: cross-pair trades (non-BTS quote) are included but PnL is in the pair's quote asset.`);
1202
- }
1203
- console.log('');
1204
- // Override blockchain fee from CLI if provided
1205
- if (opts.feePerOrder)
1206
- BLOCKCHAIN_FEE_PER_FILL = opts.feePerOrder;
1207
- // Analyze each pair
1208
- const pairMap = new Map();
1209
- for (const t of trades) {
1210
- const pairKey = `${t.baseAsset}:${t.quoteAsset}`;
1211
- if (!pairMap.has(pairKey))
1212
- pairMap.set(pairKey, []);
1213
- pairMap.get(pairKey).push(t);
1214
- }
1215
- const analyses = [];
1216
- for (const [key, pairTrades] of pairMap) {
1217
- const analysis = analyzePair(pairTrades, opts.matchMode);
1218
- analyses.push(analysis);
1219
- if (opts.verbose) {
1220
- const [base, quote] = key.split(':');
1221
- console.log(` ${fmtAsset(base)}/${fmtAsset(quote)}: ${pairTrades.filter(t => t.direction === 'buy').length} buys, ${pairTrades.filter(t => t.direction === 'sell').length} sells, ${analysis.realizedPnls.length} matched lots`);
1222
- }
1223
- }
1224
- // Sort pairs by volume (total quote)
1225
- analyses.sort((a, b) => (b.totalBuyQuote + b.totalSellQuote) - (a.totalBuyQuote + a.totalSellQuote));
1226
- // Output: summaries → grand total → per-match detail
1227
- printSummary(analyses, accountId, gte, lte, opts.matchMode);
1228
- if (opts.showPnlDetail) {
1229
- printPnlDetail(analyses);
1230
- }
1231
- printMetrics(analyses);
1232
- if (opts.csv) {
1233
- exportCsv(analyses, opts.csv);
1234
- }
1235
- if (opts.json) {
1236
- exportJson(accountId, gte, lte, analyses, opts.json);
1237
- }
1238
- }
1239
- if (require.main === module) {
1240
- run().then(() => process.exit(0)).catch(e => {
1241
- console.error('\n[fatal]', e.message);
1242
- if (process.env.DEBUG)
1243
- console.error(e.stack);
1244
- process.exit(1);
1245
- });
1246
- }
1247
- //# sourceMappingURL=trade_profitability.js.map