dexbot 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (807) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -0
  3. package/claw/README.md +513 -0
  4. package/claw/scripts/memu_runner.py +385 -0
  5. package/claw/skills/bitshares-guide/SKILL.md +14 -0
  6. package/claw/skills/bitshares-guide/references/example-skill-shells.md +18 -0
  7. package/claw/skills/bitshares-guide/references/presentation-patterns.md +19 -0
  8. package/claw/skills/bitshares-guide/references/scope-guardrails.md +9 -0
  9. package/claw/skills/launcher-ops/SKILL.md +18 -0
  10. package/claw/skills/launcher-ops/references/launcher-workflow.md +23 -0
  11. package/claw/skills/margin-trading/SKILL.md +23 -0
  12. package/claw/skills/margin-trading/references/honest-asset-list.md +74 -0
  13. package/claw/skills/margin-trading/references/honest-assets.md +44 -0
  14. package/claw/skills/margin-trading/references/position-management.md +203 -0
  15. package/claw/skills/margin-trading/references/trading-concepts.md +80 -0
  16. package/claw/skills/memu-memory/SKILL.md +218 -0
  17. package/claw/skills/shared/references/js-automation-overview.md +24 -0
  18. package/claw/skills/shared/references/safety-and-staleness.md +11 -0
  19. package/claw/skills/shared/references/skill-boundaries.md +17 -0
  20. package/claw/skills/trend-detection/SKILL.md +33 -0
  21. package/claw/skills/trend-detection/agents/openai.yaml +3 -0
  22. package/claw/skills/trend-detection/references/service.md +45 -0
  23. package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts +3 -0
  24. package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts.map +1 -0
  25. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js +149 -0
  26. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js.map +1 -0
  27. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts +3 -0
  28. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts.map +1 -0
  29. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js +387 -0
  30. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js.map +1 -0
  31. package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts +3 -0
  32. package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts.map +1 -0
  33. package/dist/analysis/ama_fitting/calibrate_convergence_er.js +200 -0
  34. package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +1 -0
  35. package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts +3 -0
  36. package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts.map +1 -0
  37. package/dist/analysis/ama_fitting/fetch_lp_candles.js +212 -0
  38. package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +1 -0
  39. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts +31 -0
  40. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts.map +1 -0
  41. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js +249 -0
  42. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js.map +1 -0
  43. package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts +2 -0
  44. package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts.map +1 -0
  45. package/dist/analysis/ama_fitting/optimizer_high_resolution.js +782 -0
  46. package/dist/analysis/ama_fitting/optimizer_high_resolution.js.map +1 -0
  47. package/dist/analysis/analyze_derivatives.d.ts +95 -0
  48. package/dist/analysis/analyze_derivatives.d.ts.map +1 -0
  49. package/dist/analysis/analyze_derivatives.js +295 -0
  50. package/dist/analysis/analyze_derivatives.js.map +1 -0
  51. package/dist/analysis/analyze_dynamic_weight.d.ts +14 -0
  52. package/dist/analysis/analyze_dynamic_weight.d.ts.map +1 -0
  53. package/dist/analysis/analyze_dynamic_weight.js +208 -0
  54. package/dist/analysis/analyze_dynamic_weight.js.map +1 -0
  55. package/dist/analysis/analyze_kalman.d.ts +13 -0
  56. package/dist/analysis/analyze_kalman.d.ts.map +1 -0
  57. package/dist/analysis/analyze_kalman.js +123 -0
  58. package/dist/analysis/analyze_kalman.js.map +1 -0
  59. package/dist/analysis/analyze_regime.d.ts +20 -0
  60. package/dist/analysis/analyze_regime.d.ts.map +1 -0
  61. package/dist/analysis/analyze_regime.js +139 -0
  62. package/dist/analysis/analyze_regime.js.map +1 -0
  63. package/dist/analysis/analyze_regime_windows.d.ts +19 -0
  64. package/dist/analysis/analyze_regime_windows.d.ts.map +1 -0
  65. package/dist/analysis/analyze_regime_windows.js +413 -0
  66. package/dist/analysis/analyze_regime_windows.js.map +1 -0
  67. package/dist/analysis/analyze_risk_profile.d.ts +3 -0
  68. package/dist/analysis/analyze_risk_profile.d.ts.map +1 -0
  69. package/dist/analysis/analyze_risk_profile.js +159 -0
  70. package/dist/analysis/analyze_risk_profile.js.map +1 -0
  71. package/dist/analysis/analyze_trade_heatmap.d.ts +3 -0
  72. package/dist/analysis/analyze_trade_heatmap.d.ts.map +1 -0
  73. package/dist/analysis/analyze_trade_heatmap.js +367 -0
  74. package/dist/analysis/analyze_trade_heatmap.js.map +1 -0
  75. package/dist/analysis/analyze_volatility.d.ts +22 -0
  76. package/dist/analysis/analyze_volatility.d.ts.map +1 -0
  77. package/dist/analysis/analyze_volatility.js +172 -0
  78. package/dist/analysis/analyze_volatility.js.map +1 -0
  79. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts +99 -0
  80. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts.map +1 -0
  81. package/dist/analysis/bot_fitting/backtest_ama_sweep.js +804 -0
  82. package/dist/analysis/bot_fitting/backtest_ama_sweep.js.map +1 -0
  83. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts +2 -0
  84. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts.map +1 -0
  85. package/dist/analysis/bot_fitting/backtest_bot_fitting.js +347 -0
  86. package/dist/analysis/bot_fitting/backtest_bot_fitting.js.map +1 -0
  87. package/dist/analysis/bot_fitting/shared_utils.d.ts +15 -0
  88. package/dist/analysis/bot_fitting/shared_utils.d.ts.map +1 -0
  89. package/dist/analysis/bot_fitting/shared_utils.js +48 -0
  90. package/dist/analysis/bot_fitting/shared_utils.js.map +1 -0
  91. package/dist/analysis/bot_key_utils.d.ts +16 -0
  92. package/dist/analysis/bot_key_utils.d.ts.map +1 -0
  93. package/dist/analysis/bot_key_utils.js +61 -0
  94. package/dist/analysis/bot_key_utils.js.map +1 -0
  95. package/dist/analysis/bot_usage/discover_bot_accounts.d.ts +3 -0
  96. package/dist/analysis/bot_usage/discover_bot_accounts.d.ts.map +1 -0
  97. package/dist/analysis/bot_usage/discover_bot_accounts.js +498 -0
  98. package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -0
  99. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +546 -0
  100. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -0
  101. package/dist/analysis/bot_usage/kibana_bot_queries.js +427 -0
  102. package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -0
  103. package/dist/analysis/chart_utils.d.ts +13 -0
  104. package/dist/analysis/chart_utils.d.ts.map +1 -0
  105. package/dist/analysis/chart_utils.js +142 -0
  106. package/dist/analysis/chart_utils.js.map +1 -0
  107. package/dist/analysis/derivative_chart_generator.d.ts +18 -0
  108. package/dist/analysis/derivative_chart_generator.d.ts.map +1 -0
  109. package/dist/analysis/derivative_chart_generator.js +896 -0
  110. package/dist/analysis/derivative_chart_generator.js.map +1 -0
  111. package/dist/analysis/math_utils.d.ts +35 -0
  112. package/dist/analysis/math_utils.d.ts.map +1 -0
  113. package/dist/analysis/math_utils.js +121 -0
  114. package/dist/analysis/math_utils.js.map +1 -0
  115. package/dist/analysis/price_sources.d.ts +34 -0
  116. package/dist/analysis/price_sources.d.ts.map +1 -0
  117. package/dist/analysis/price_sources.js +103 -0
  118. package/dist/analysis/price_sources.js.map +1 -0
  119. package/dist/analysis/trade_profitability.d.ts +115 -0
  120. package/dist/analysis/trade_profitability.d.ts.map +1 -0
  121. package/dist/analysis/trade_profitability.js +1247 -0
  122. package/dist/analysis/trade_profitability.js.map +1 -0
  123. package/dist/analysis/tradingview/analyze_tradingview.d.ts +38 -0
  124. package/dist/analysis/tradingview/analyze_tradingview.d.ts.map +1 -0
  125. package/dist/analysis/tradingview/analyze_tradingview.js +212 -0
  126. package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -0
  127. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +9 -0
  128. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -0
  129. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +1717 -0
  130. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -0
  131. package/dist/analysis/trend_detection/derivative_analyzer.d.ts +250 -0
  132. package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +1 -0
  133. package/dist/analysis/trend_detection/derivative_analyzer.js +903 -0
  134. package/dist/analysis/trend_detection/derivative_analyzer.js.map +1 -0
  135. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts +6 -0
  136. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +1 -0
  137. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +1449 -0
  138. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +1 -0
  139. package/dist/analysis/trend_detection/hurst_analyzer.d.ts +42 -0
  140. package/dist/analysis/trend_detection/hurst_analyzer.d.ts.map +1 -0
  141. package/dist/analysis/trend_detection/hurst_analyzer.js +159 -0
  142. package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -0
  143. package/dist/analysis/trend_detection/kalman_chart_generator.d.ts +6 -0
  144. package/dist/analysis/trend_detection/kalman_chart_generator.d.ts.map +1 -0
  145. package/dist/analysis/trend_detection/kalman_chart_generator.js +408 -0
  146. package/dist/analysis/trend_detection/kalman_chart_generator.js.map +1 -0
  147. package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts +103 -0
  148. package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts.map +1 -0
  149. package/dist/analysis/trend_detection/kalman_trend_analyzer.js +229 -0
  150. package/dist/analysis/trend_detection/kalman_trend_analyzer.js.map +1 -0
  151. package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts +34 -0
  152. package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts.map +1 -0
  153. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js +89 -0
  154. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js.map +1 -0
  155. package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts +39 -0
  156. package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts.map +1 -0
  157. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js +132 -0
  158. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js.map +1 -0
  159. package/dist/analysis/trend_detection/regime_chart_generator.d.ts +6 -0
  160. package/dist/analysis/trend_detection/regime_chart_generator.d.ts.map +1 -0
  161. package/dist/analysis/trend_detection/regime_chart_generator.js +345 -0
  162. package/dist/analysis/trend_detection/regime_chart_generator.js.map +1 -0
  163. package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts +2 -0
  164. package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts.map +1 -0
  165. package/dist/analysis/trend_detection/tests/test_kalman_trend.js +130 -0
  166. package/dist/analysis/trend_detection/tests/test_kalman_trend.js.map +1 -0
  167. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts +2 -0
  168. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts.map +1 -0
  169. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js +38 -0
  170. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js.map +1 -0
  171. package/dist/analysis/trend_detection/volatility_chart_generator.d.ts +6 -0
  172. package/dist/analysis/trend_detection/volatility_chart_generator.d.ts.map +1 -0
  173. package/dist/analysis/trend_detection/volatility_chart_generator.js +732 -0
  174. package/dist/analysis/trend_detection/volatility_chart_generator.js.map +1 -0
  175. package/dist/bot.d.ts +49 -0
  176. package/dist/bot.d.ts.map +1 -0
  177. package/dist/bot.js +221 -0
  178. package/dist/bot.js.map +1 -0
  179. package/dist/credential-daemon.d.ts +64 -0
  180. package/dist/credential-daemon.d.ts.map +1 -0
  181. package/dist/credential-daemon.js +987 -0
  182. package/dist/credential-daemon.js.map +1 -0
  183. package/dist/dexbot.d.ts +87 -0
  184. package/dist/dexbot.d.ts.map +1 -0
  185. package/dist/dexbot.js +1222 -0
  186. package/dist/dexbot.js.map +1 -0
  187. package/dist/market_adapter/ama_signal_runner.d.ts +3 -0
  188. package/dist/market_adapter/ama_signal_runner.d.ts.map +1 -0
  189. package/dist/market_adapter/ama_signal_runner.js +175 -0
  190. package/dist/market_adapter/ama_signal_runner.js.map +1 -0
  191. package/dist/market_adapter/candle_utils.d.ts +57 -0
  192. package/dist/market_adapter/candle_utils.d.ts.map +1 -0
  193. package/dist/market_adapter/candle_utils.js +252 -0
  194. package/dist/market_adapter/candle_utils.js.map +1 -0
  195. package/dist/market_adapter/core/asymmetric_bounds.d.ts +20 -0
  196. package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -0
  197. package/dist/market_adapter/core/asymmetric_bounds.js +88 -0
  198. package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -0
  199. package/dist/market_adapter/core/config_normalizers.d.ts +10 -0
  200. package/dist/market_adapter/core/config_normalizers.d.ts.map +1 -0
  201. package/dist/market_adapter/core/config_normalizers.js +24 -0
  202. package/dist/market_adapter/core/config_normalizers.js.map +1 -0
  203. package/dist/market_adapter/core/kibana_candles.d.ts +74 -0
  204. package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -0
  205. package/dist/market_adapter/core/kibana_candles.js +249 -0
  206. package/dist/market_adapter/core/kibana_candles.js.map +1 -0
  207. package/dist/market_adapter/core/kibana_client.d.ts +27 -0
  208. package/dist/market_adapter/core/kibana_client.d.ts.map +1 -0
  209. package/dist/market_adapter/core/kibana_client.js +120 -0
  210. package/dist/market_adapter/core/kibana_client.js.map +1 -0
  211. package/dist/market_adapter/core/kibana_market_candles.d.ts +143 -0
  212. package/dist/market_adapter/core/kibana_market_candles.d.ts.map +1 -0
  213. package/dist/market_adapter/core/kibana_market_candles.js +170 -0
  214. package/dist/market_adapter/core/kibana_market_candles.js.map +1 -0
  215. package/dist/market_adapter/core/market_adapter_service.d.ts +210 -0
  216. package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -0
  217. package/dist/market_adapter/core/market_adapter_service.js +2328 -0
  218. package/dist/market_adapter/core/market_adapter_service.js.map +1 -0
  219. package/dist/market_adapter/core/strategies/ama.d.ts +2 -0
  220. package/dist/market_adapter/core/strategies/ama.d.ts.map +1 -0
  221. package/dist/market_adapter/core/strategies/ama.js +138 -0
  222. package/dist/market_adapter/core/strategies/ama.js.map +1 -0
  223. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts +50 -0
  224. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts.map +1 -0
  225. package/dist/market_adapter/core/strategies/ama_slope_model.js +143 -0
  226. package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -0
  227. package/dist/market_adapter/core/strategies/atr/calculator.d.ts +12 -0
  228. package/dist/market_adapter/core/strategies/atr/calculator.d.ts.map +1 -0
  229. package/dist/market_adapter/core/strategies/atr/calculator.js +47 -0
  230. package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -0
  231. package/dist/market_adapter/core/strategies/collateral_manager.d.ts +32 -0
  232. package/dist/market_adapter/core/strategies/collateral_manager.d.ts.map +1 -0
  233. package/dist/market_adapter/core/strategies/collateral_manager.js +68 -0
  234. package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -0
  235. package/dist/market_adapter/core/strategies/regime_gate.d.ts +66 -0
  236. package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -0
  237. package/dist/market_adapter/core/strategies/regime_gate.js +189 -0
  238. package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -0
  239. package/dist/market_adapter/index.d.ts +10 -0
  240. package/dist/market_adapter/index.d.ts.map +1 -0
  241. package/dist/market_adapter/index.js +71 -0
  242. package/dist/market_adapter/index.js.map +1 -0
  243. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts +3 -0
  244. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts.map +1 -0
  245. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +1165 -0
  246. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -0
  247. package/dist/market_adapter/inputs/fetch_lp_data.d.ts +54 -0
  248. package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -0
  249. package/dist/market_adapter/inputs/fetch_lp_data.js +743 -0
  250. package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -0
  251. package/dist/market_adapter/inputs/kibana_source.d.ts +68 -0
  252. package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -0
  253. package/dist/market_adapter/inputs/kibana_source.js +143 -0
  254. package/dist/market_adapter/inputs/kibana_source.js.map +1 -0
  255. package/dist/market_adapter/interval_utils.d.ts +6 -0
  256. package/dist/market_adapter/interval_utils.d.ts.map +1 -0
  257. package/dist/market_adapter/interval_utils.js +14 -0
  258. package/dist/market_adapter/interval_utils.js.map +1 -0
  259. package/dist/market_adapter/log_format.d.ts +16 -0
  260. package/dist/market_adapter/log_format.d.ts.map +1 -0
  261. package/dist/market_adapter/log_format.js +72 -0
  262. package/dist/market_adapter/log_format.js.map +1 -0
  263. package/dist/market_adapter/lp_chart_core.d.ts +6 -0
  264. package/dist/market_adapter/lp_chart_core.d.ts.map +1 -0
  265. package/dist/market_adapter/lp_chart_core.js +874 -0
  266. package/dist/market_adapter/lp_chart_core.js.map +1 -0
  267. package/dist/market_adapter/lp_chart_runner.d.ts +135 -0
  268. package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -0
  269. package/dist/market_adapter/lp_chart_runner.js +337 -0
  270. package/dist/market_adapter/lp_chart_runner.js.map +1 -0
  271. package/dist/market_adapter/lp_chart_strategy_loader.d.ts +23 -0
  272. package/dist/market_adapter/lp_chart_strategy_loader.d.ts.map +1 -0
  273. package/dist/market_adapter/lp_chart_strategy_loader.js +169 -0
  274. package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -0
  275. package/dist/market_adapter/market_adapter.d.ts +133 -0
  276. package/dist/market_adapter/market_adapter.d.ts.map +1 -0
  277. package/dist/market_adapter/market_adapter.js +1331 -0
  278. package/dist/market_adapter/market_adapter.js.map +1 -0
  279. package/dist/market_adapter/merge_lp_data.d.ts +3 -0
  280. package/dist/market_adapter/merge_lp_data.d.ts.map +1 -0
  281. package/dist/market_adapter/merge_lp_data.js +125 -0
  282. package/dist/market_adapter/merge_lp_data.js.map +1 -0
  283. package/dist/market_adapter/test_helpers.d.ts +14 -0
  284. package/dist/market_adapter/test_helpers.d.ts.map +1 -0
  285. package/dist/market_adapter/test_helpers.js +22 -0
  286. package/dist/market_adapter/test_helpers.js.map +1 -0
  287. package/dist/market_adapter/utils/adapter_client.d.ts +20 -0
  288. package/dist/market_adapter/utils/adapter_client.d.ts.map +1 -0
  289. package/dist/market_adapter/utils/adapter_client.js +88 -0
  290. package/dist/market_adapter/utils/adapter_client.js.map +1 -0
  291. package/dist/market_adapter/utils/atomic_write.d.ts +9 -0
  292. package/dist/market_adapter/utils/atomic_write.d.ts.map +1 -0
  293. package/dist/market_adapter/utils/atomic_write.js +13 -0
  294. package/dist/market_adapter/utils/atomic_write.js.map +1 -0
  295. package/dist/market_adapter/utils/chain.d.ts +50 -0
  296. package/dist/market_adapter/utils/chain.d.ts.map +1 -0
  297. package/dist/market_adapter/utils/chain.js +196 -0
  298. package/dist/market_adapter/utils/chain.js.map +1 -0
  299. package/dist/market_adapter/utils/data_discovery.d.ts +6 -0
  300. package/dist/market_adapter/utils/data_discovery.d.ts.map +1 -0
  301. package/dist/market_adapter/utils/data_discovery.js +35 -0
  302. package/dist/market_adapter/utils/data_discovery.js.map +1 -0
  303. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts +15 -0
  304. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -0
  305. package/dist/market_adapter/utils/dynamic_grid_snapshot.js +60 -0
  306. package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -0
  307. package/dist/market_adapter/utils/file_lock.d.ts +19 -0
  308. package/dist/market_adapter/utils/file_lock.d.ts.map +1 -0
  309. package/dist/market_adapter/utils/file_lock.js +191 -0
  310. package/dist/market_adapter/utils/file_lock.js.map +1 -0
  311. package/dist/market_adapter/utils/native_history.d.ts +19 -0
  312. package/dist/market_adapter/utils/native_history.d.ts.map +1 -0
  313. package/dist/market_adapter/utils/native_history.js +172 -0
  314. package/dist/market_adapter/utils/native_history.js.map +1 -0
  315. package/dist/market_adapter/utils/paths.d.ts +5 -0
  316. package/dist/market_adapter/utils/paths.d.ts.map +1 -0
  317. package/dist/market_adapter/utils/paths.js +7 -0
  318. package/dist/market_adapter/utils/paths.js.map +1 -0
  319. package/dist/modules/account_bots.d.ts +112 -0
  320. package/dist/modules/account_bots.d.ts.map +1 -0
  321. package/dist/modules/account_bots.js +1259 -0
  322. package/dist/modules/account_bots.js.map +1 -0
  323. package/dist/modules/account_orders.d.ts +273 -0
  324. package/dist/modules/account_orders.d.ts.map +1 -0
  325. package/dist/modules/account_orders.js +662 -0
  326. package/dist/modules/account_orders.js.map +1 -0
  327. package/dist/modules/authority_resolver.d.ts +2 -0
  328. package/dist/modules/authority_resolver.d.ts.map +1 -0
  329. package/dist/modules/authority_resolver.js +231 -0
  330. package/dist/modules/authority_resolver.js.map +1 -0
  331. package/dist/modules/bitshares-native/chain_client.d.ts +38 -0
  332. package/dist/modules/bitshares-native/chain_client.d.ts.map +1 -0
  333. package/dist/modules/bitshares-native/chain_client.js +322 -0
  334. package/dist/modules/bitshares-native/chain_client.js.map +1 -0
  335. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts +59 -0
  336. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -0
  337. package/dist/modules/bitshares-native/crypto/ecc.browser.js +456 -0
  338. package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -0
  339. package/dist/modules/bitshares-native/crypto/ecc.d.ts +66 -0
  340. package/dist/modules/bitshares-native/crypto/ecc.d.ts.map +1 -0
  341. package/dist/modules/bitshares-native/crypto/ecc.js +557 -0
  342. package/dist/modules/bitshares-native/crypto/ecc.js.map +1 -0
  343. package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts +2 -0
  344. package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts.map +1 -0
  345. package/dist/modules/bitshares-native/crypto/ecc_selector.js +20 -0
  346. package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -0
  347. package/dist/modules/bitshares-native/index.d.ts +3 -0
  348. package/dist/modules/bitshares-native/index.d.ts.map +1 -0
  349. package/dist/modules/bitshares-native/index.js +32 -0
  350. package/dist/modules/bitshares-native/index.js.map +1 -0
  351. package/dist/modules/bitshares-native/resolvers.d.ts +40 -0
  352. package/dist/modules/bitshares-native/resolvers.d.ts.map +1 -0
  353. package/dist/modules/bitshares-native/resolvers.js +161 -0
  354. package/dist/modules/bitshares-native/resolvers.js.map +1 -0
  355. package/dist/modules/bitshares-native/serial/chain_constants.d.ts +56 -0
  356. package/dist/modules/bitshares-native/serial/chain_constants.d.ts.map +1 -0
  357. package/dist/modules/bitshares-native/serial/chain_constants.js +92 -0
  358. package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -0
  359. package/dist/modules/bitshares-native/serial/index.d.ts +10 -0
  360. package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -0
  361. package/dist/modules/bitshares-native/serial/index.js +14 -0
  362. package/dist/modules/bitshares-native/serial/index.js.map +1 -0
  363. package/dist/modules/bitshares-native/serial/operations.d.ts +102 -0
  364. package/dist/modules/bitshares-native/serial/operations.d.ts.map +1 -0
  365. package/dist/modules/bitshares-native/serial/operations.js +615 -0
  366. package/dist/modules/bitshares-native/serial/operations.js.map +1 -0
  367. package/dist/modules/bitshares-native/serial/serializer.d.ts +64 -0
  368. package/dist/modules/bitshares-native/serial/serializer.d.ts.map +1 -0
  369. package/dist/modules/bitshares-native/serial/serializer.js +252 -0
  370. package/dist/modules/bitshares-native/serial/serializer.js.map +1 -0
  371. package/dist/modules/bitshares-native/serial/types.d.ts +120 -0
  372. package/dist/modules/bitshares-native/serial/types.d.ts.map +1 -0
  373. package/dist/modules/bitshares-native/serial/types.js +837 -0
  374. package/dist/modules/bitshares-native/serial/types.js.map +1 -0
  375. package/dist/modules/bitshares-native/signing_client.d.ts +6 -0
  376. package/dist/modules/bitshares-native/signing_client.d.ts.map +1 -0
  377. package/dist/modules/bitshares-native/signing_client.js +141 -0
  378. package/dist/modules/bitshares-native/signing_client.js.map +1 -0
  379. package/dist/modules/bitshares-native/subscriptions.d.ts +6 -0
  380. package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -0
  381. package/dist/modules/bitshares-native/subscriptions.js +865 -0
  382. package/dist/modules/bitshares-native/subscriptions.js.map +1 -0
  383. package/dist/modules/bitshares-native/transport.d.ts +51 -0
  384. package/dist/modules/bitshares-native/transport.d.ts.map +1 -0
  385. package/dist/modules/bitshares-native/transport.js +447 -0
  386. package/dist/modules/bitshares-native/transport.js.map +1 -0
  387. package/dist/modules/bitshares-native/tx/builder.d.ts +30 -0
  388. package/dist/modules/bitshares-native/tx/builder.d.ts.map +1 -0
  389. package/dist/modules/bitshares-native/tx/builder.js +262 -0
  390. package/dist/modules/bitshares-native/tx/builder.js.map +1 -0
  391. package/dist/modules/bitshares_client.d.ts +129 -0
  392. package/dist/modules/bitshares_client.d.ts.map +1 -0
  393. package/dist/modules/bitshares_client.js +627 -0
  394. package/dist/modules/bitshares_client.js.map +1 -0
  395. package/dist/modules/bot_settings.d.ts +33 -0
  396. package/dist/modules/bot_settings.d.ts.map +1 -0
  397. package/dist/modules/bot_settings.js +328 -0
  398. package/dist/modules/bot_settings.js.map +1 -0
  399. package/dist/modules/bots_file_lock.d.ts +88 -0
  400. package/dist/modules/bots_file_lock.d.ts.map +1 -0
  401. package/dist/modules/bots_file_lock.js +161 -0
  402. package/dist/modules/bots_file_lock.js.map +1 -0
  403. package/dist/modules/chain_keys.d.ts +302 -0
  404. package/dist/modules/chain_keys.d.ts.map +1 -0
  405. package/dist/modules/chain_keys.js +1095 -0
  406. package/dist/modules/chain_keys.js.map +1 -0
  407. package/dist/modules/chain_orders.d.ts +423 -0
  408. package/dist/modules/chain_orders.d.ts.map +1 -0
  409. package/dist/modules/chain_orders.js +1201 -0
  410. package/dist/modules/chain_orders.js.map +1 -0
  411. package/dist/modules/cli_whitelist_args.d.ts +6 -0
  412. package/dist/modules/cli_whitelist_args.d.ts.map +1 -0
  413. package/dist/modules/cli_whitelist_args.js +13 -0
  414. package/dist/modules/cli_whitelist_args.js.map +1 -0
  415. package/dist/modules/config.d.ts +57 -0
  416. package/dist/modules/config.d.ts.map +1 -0
  417. package/dist/modules/config.js +107 -0
  418. package/dist/modules/config.js.map +1 -0
  419. package/dist/modules/constants.d.ts +635 -0
  420. package/dist/modules/constants.d.ts.map +1 -0
  421. package/dist/modules/constants.js +1464 -0
  422. package/dist/modules/constants.js.map +1 -0
  423. package/dist/modules/cr_planner.d.ts +51 -0
  424. package/dist/modules/cr_planner.d.ts.map +1 -0
  425. package/dist/modules/cr_planner.js +299 -0
  426. package/dist/modules/cr_planner.js.map +1 -0
  427. package/dist/modules/credential_policy.d.ts +188 -0
  428. package/dist/modules/credential_policy.d.ts.map +1 -0
  429. package/dist/modules/credential_policy.js +1452 -0
  430. package/dist/modules/credential_policy.js.map +1 -0
  431. package/dist/modules/credential_runtime.d.ts +42 -0
  432. package/dist/modules/credential_runtime.d.ts.map +1 -0
  433. package/dist/modules/credential_runtime.js +148 -0
  434. package/dist/modules/credential_runtime.js.map +1 -0
  435. package/dist/modules/credential_session_cache.d.ts +36 -0
  436. package/dist/modules/credential_session_cache.d.ts.map +1 -0
  437. package/dist/modules/credential_session_cache.js +106 -0
  438. package/dist/modules/credential_session_cache.js.map +1 -0
  439. package/dist/modules/credit_runtime.d.ts +412 -0
  440. package/dist/modules/credit_runtime.d.ts.map +1 -0
  441. package/dist/modules/credit_runtime.js +2866 -0
  442. package/dist/modules/credit_runtime.js.map +1 -0
  443. package/dist/modules/crypto/browser_provider.d.ts +15 -0
  444. package/dist/modules/crypto/browser_provider.d.ts.map +1 -0
  445. package/dist/modules/crypto/browser_provider.js +113 -0
  446. package/dist/modules/crypto/browser_provider.js.map +1 -0
  447. package/dist/modules/crypto/index.d.ts +9 -0
  448. package/dist/modules/crypto/index.d.ts.map +1 -0
  449. package/dist/modules/crypto/index.js +44 -0
  450. package/dist/modules/crypto/index.js.map +1 -0
  451. package/dist/modules/crypto/node_provider.d.ts +15 -0
  452. package/dist/modules/crypto/node_provider.d.ts.map +1 -0
  453. package/dist/modules/crypto/node_provider.js +74 -0
  454. package/dist/modules/crypto/node_provider.js.map +1 -0
  455. package/dist/modules/crypto/provider.d.ts +34 -0
  456. package/dist/modules/crypto/provider.d.ts.map +1 -0
  457. package/dist/modules/crypto/provider.js +3 -0
  458. package/dist/modules/crypto/provider.js.map +1 -0
  459. package/dist/modules/crypto/pure_ripemd160.d.ts +8 -0
  460. package/dist/modules/crypto/pure_ripemd160.d.ts.map +1 -0
  461. package/dist/modules/crypto/pure_ripemd160.js +142 -0
  462. package/dist/modules/crypto/pure_ripemd160.js.map +1 -0
  463. package/dist/modules/crypto/pure_scrypt.d.ts +23 -0
  464. package/dist/modules/crypto/pure_scrypt.d.ts.map +1 -0
  465. package/dist/modules/crypto/pure_scrypt.js +161 -0
  466. package/dist/modules/crypto/pure_scrypt.js.map +1 -0
  467. package/dist/modules/crypto/pure_secp256k1.d.ts +29 -0
  468. package/dist/modules/crypto/pure_secp256k1.d.ts.map +1 -0
  469. package/dist/modules/crypto/pure_secp256k1.js +195 -0
  470. package/dist/modules/crypto/pure_secp256k1.js.map +1 -0
  471. package/dist/modules/crypto/sync.d.ts +13 -0
  472. package/dist/modules/crypto/sync.d.ts.map +1 -0
  473. package/dist/modules/crypto/sync.js +37 -0
  474. package/dist/modules/crypto/sync.js.map +1 -0
  475. package/dist/modules/dexbot_class.d.ts +1074 -0
  476. package/dist/modules/dexbot_class.d.ts.map +1 -0
  477. package/dist/modules/dexbot_class.js +4613 -0
  478. package/dist/modules/dexbot_class.js.map +1 -0
  479. package/dist/modules/dexbot_credential_client.d.ts +71 -0
  480. package/dist/modules/dexbot_credential_client.d.ts.map +1 -0
  481. package/dist/modules/dexbot_credential_client.js +224 -0
  482. package/dist/modules/dexbot_credential_client.js.map +1 -0
  483. package/dist/modules/dexbot_fill_runtime.d.ts +173 -0
  484. package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -0
  485. package/dist/modules/dexbot_fill_runtime.js +217 -0
  486. package/dist/modules/dexbot_fill_runtime.js.map +1 -0
  487. package/dist/modules/dexbot_maintenance_runtime.d.ts +279 -0
  488. package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -0
  489. package/dist/modules/dexbot_maintenance_runtime.js +1613 -0
  490. package/dist/modules/dexbot_maintenance_runtime.js.map +1 -0
  491. package/dist/modules/env.d.ts +12 -0
  492. package/dist/modules/env.d.ts.map +1 -0
  493. package/dist/modules/env.js +57 -0
  494. package/dist/modules/env.js.map +1 -0
  495. package/dist/modules/fund_registry.d.ts +96 -0
  496. package/dist/modules/fund_registry.d.ts.map +1 -0
  497. package/dist/modules/fund_registry.js +261 -0
  498. package/dist/modules/fund_registry.js.map +1 -0
  499. package/dist/modules/general_settings.d.ts +36 -0
  500. package/dist/modules/general_settings.d.ts.map +1 -0
  501. package/dist/modules/general_settings.js +63 -0
  502. package/dist/modules/general_settings.js.map +1 -0
  503. package/dist/modules/graceful_shutdown.d.ts +86 -0
  504. package/dist/modules/graceful_shutdown.d.ts.map +1 -0
  505. package/dist/modules/graceful_shutdown.js +164 -0
  506. package/dist/modules/graceful_shutdown.js.map +1 -0
  507. package/dist/modules/key_store.d.ts +60 -0
  508. package/dist/modules/key_store.d.ts.map +1 -0
  509. package/dist/modules/key_store.js +215 -0
  510. package/dist/modules/key_store.js.map +1 -0
  511. package/dist/modules/launcher/bot_supervisor.d.ts +84 -0
  512. package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -0
  513. package/dist/modules/launcher/bot_supervisor.js +1067 -0
  514. package/dist/modules/launcher/bot_supervisor.js.map +1 -0
  515. package/dist/modules/launcher/child_env.d.ts +9 -0
  516. package/dist/modules/launcher/child_env.d.ts.map +1 -0
  517. package/dist/modules/launcher/child_env.js +78 -0
  518. package/dist/modules/launcher/child_env.js.map +1 -0
  519. package/dist/modules/launcher/credential_bootstrap.d.ts +22 -0
  520. package/dist/modules/launcher/credential_bootstrap.d.ts.map +1 -0
  521. package/dist/modules/launcher/credential_bootstrap.js +303 -0
  522. package/dist/modules/launcher/credential_bootstrap.js.map +1 -0
  523. package/dist/modules/launcher/credential_daemon.d.ts +32 -0
  524. package/dist/modules/launcher/credential_daemon.d.ts.map +1 -0
  525. package/dist/modules/launcher/credential_daemon.js +173 -0
  526. package/dist/modules/launcher/credential_daemon.js.map +1 -0
  527. package/dist/modules/launcher/credential_secret.d.ts +6 -0
  528. package/dist/modules/launcher/credential_secret.d.ts.map +1 -0
  529. package/dist/modules/launcher/credential_secret.js +15 -0
  530. package/dist/modules/launcher/credential_secret.js.map +1 -0
  531. package/dist/modules/launcher/foreign_cred_daemon.d.ts +2 -0
  532. package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -0
  533. package/dist/modules/launcher/foreign_cred_daemon.js +166 -0
  534. package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -0
  535. package/dist/modules/launcher/headless_password.d.ts +8 -0
  536. package/dist/modules/launcher/headless_password.d.ts.map +1 -0
  537. package/dist/modules/launcher/headless_password.js +33 -0
  538. package/dist/modules/launcher/headless_password.js.map +1 -0
  539. package/dist/modules/launcher/launch_modes.d.ts +36 -0
  540. package/dist/modules/launcher/launch_modes.d.ts.map +1 -0
  541. package/dist/modules/launcher/launch_modes.js +129 -0
  542. package/dist/modules/launcher/launch_modes.js.map +1 -0
  543. package/dist/modules/launcher/market_adapter_runtime.d.ts +43 -0
  544. package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -0
  545. package/dist/modules/launcher/market_adapter_runtime.js +217 -0
  546. package/dist/modules/launcher/market_adapter_runtime.js.map +1 -0
  547. package/dist/modules/launcher/market_adapter_watchdog.d.ts +26 -0
  548. package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -0
  549. package/dist/modules/launcher/market_adapter_watchdog.js +214 -0
  550. package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -0
  551. package/dist/modules/launcher/monolithic_runtime.d.ts +89 -0
  552. package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -0
  553. package/dist/modules/launcher/monolithic_runtime.js +425 -0
  554. package/dist/modules/launcher/monolithic_runtime.js.map +1 -0
  555. package/dist/modules/launcher/runtime_entry.d.ts +26 -0
  556. package/dist/modules/launcher/runtime_entry.d.ts.map +1 -0
  557. package/dist/modules/launcher/runtime_entry.js +49 -0
  558. package/dist/modules/launcher/runtime_entry.js.map +1 -0
  559. package/dist/modules/launcher/status_reporting.d.ts +48 -0
  560. package/dist/modules/launcher/status_reporting.d.ts.map +1 -0
  561. package/dist/modules/launcher/status_reporting.js +113 -0
  562. package/dist/modules/launcher/status_reporting.js.map +1 -0
  563. package/dist/modules/launcher/supervisor_control.d.ts +6 -0
  564. package/dist/modules/launcher/supervisor_control.d.ts.map +1 -0
  565. package/dist/modules/launcher/supervisor_control.js +59 -0
  566. package/dist/modules/launcher/supervisor_control.js.map +1 -0
  567. package/dist/modules/logger.d.ts +2 -0
  568. package/dist/modules/logger.d.ts.map +1 -0
  569. package/dist/modules/logger.js +71 -0
  570. package/dist/modules/logger.js.map +1 -0
  571. package/dist/modules/market_adapter_whitelist.d.ts +22 -0
  572. package/dist/modules/market_adapter_whitelist.d.ts.map +1 -0
  573. package/dist/modules/market_adapter_whitelist.js +82 -0
  574. package/dist/modules/market_adapter_whitelist.js.map +1 -0
  575. package/dist/modules/node_health_cache.d.ts +55 -0
  576. package/dist/modules/node_health_cache.d.ts.map +1 -0
  577. package/dist/modules/node_health_cache.js +134 -0
  578. package/dist/modules/node_health_cache.js.map +1 -0
  579. package/dist/modules/node_manager.d.ts +215 -0
  580. package/dist/modules/node_manager.d.ts.map +1 -0
  581. package/dist/modules/node_manager.js +628 -0
  582. package/dist/modules/node_manager.js.map +1 -0
  583. package/dist/modules/order/accounting.d.ts +349 -0
  584. package/dist/modules/order/accounting.d.ts.map +1 -0
  585. package/dist/modules/order/accounting.js +1191 -0
  586. package/dist/modules/order/accounting.js.map +1 -0
  587. package/dist/modules/order/async_lock.d.ts +126 -0
  588. package/dist/modules/order/async_lock.d.ts.map +1 -0
  589. package/dist/modules/order/async_lock.js +195 -0
  590. package/dist/modules/order/async_lock.js.map +1 -0
  591. package/dist/modules/order/export.d.ts +129 -0
  592. package/dist/modules/order/export.d.ts.map +1 -0
  593. package/dist/modules/order/export.js +316 -0
  594. package/dist/modules/order/export.js.map +1 -0
  595. package/dist/modules/order/format.d.ts +158 -0
  596. package/dist/modules/order/format.d.ts.map +1 -0
  597. package/dist/modules/order/format.js +232 -0
  598. package/dist/modules/order/format.js.map +1 -0
  599. package/dist/modules/order/grid.d.ts +549 -0
  600. package/dist/modules/order/grid.d.ts.map +1 -0
  601. package/dist/modules/order/grid.js +1746 -0
  602. package/dist/modules/order/grid.js.map +1 -0
  603. package/dist/modules/order/grid_reconcile.d.ts +154 -0
  604. package/dist/modules/order/grid_reconcile.d.ts.map +1 -0
  605. package/dist/modules/order/grid_reconcile.js +1192 -0
  606. package/dist/modules/order/grid_reconcile.js.map +1 -0
  607. package/dist/modules/order/index.d.ts +55 -0
  608. package/dist/modules/order/index.d.ts.map +1 -0
  609. package/dist/modules/order/index.js +79 -0
  610. package/dist/modules/order/index.js.map +1 -0
  611. package/dist/modules/order/logger.d.ts +136 -0
  612. package/dist/modules/order/logger.d.ts.map +1 -0
  613. package/dist/modules/order/logger.js +614 -0
  614. package/dist/modules/order/logger.js.map +1 -0
  615. package/dist/modules/order/logger_state.d.ts +133 -0
  616. package/dist/modules/order/logger_state.d.ts.map +1 -0
  617. package/dist/modules/order/logger_state.js +170 -0
  618. package/dist/modules/order/logger_state.js.map +1 -0
  619. package/dist/modules/order/manager.d.ts +413 -0
  620. package/dist/modules/order/manager.d.ts.map +1 -0
  621. package/dist/modules/order/manager.js +1605 -0
  622. package/dist/modules/order/manager.js.map +1 -0
  623. package/dist/modules/order/processed_fill_store.d.ts +135 -0
  624. package/dist/modules/order/processed_fill_store.d.ts.map +1 -0
  625. package/dist/modules/order/processed_fill_store.js +288 -0
  626. package/dist/modules/order/processed_fill_store.js.map +1 -0
  627. package/dist/modules/order/runner.d.ts +70 -0
  628. package/dist/modules/order/runner.d.ts.map +1 -0
  629. package/dist/modules/order/runner.js +140 -0
  630. package/dist/modules/order/runner.js.map +1 -0
  631. package/dist/modules/order/strategy.d.ts +196 -0
  632. package/dist/modules/order/strategy.d.ts.map +1 -0
  633. package/dist/modules/order/strategy.js +398 -0
  634. package/dist/modules/order/strategy.js.map +1 -0
  635. package/dist/modules/order/sync_engine.d.ts +386 -0
  636. package/dist/modules/order/sync_engine.d.ts.map +1 -0
  637. package/dist/modules/order/sync_engine.js +1459 -0
  638. package/dist/modules/order/sync_engine.js.map +1 -0
  639. package/dist/modules/order/utils/math.d.ts +677 -0
  640. package/dist/modules/order/utils/math.d.ts.map +1 -0
  641. package/dist/modules/order/utils/math.js +1172 -0
  642. package/dist/modules/order/utils/math.js.map +1 -0
  643. package/dist/modules/order/utils/order.d.ts +572 -0
  644. package/dist/modules/order/utils/order.d.ts.map +1 -0
  645. package/dist/modules/order/utils/order.js +1145 -0
  646. package/dist/modules/order/utils/order.js.map +1 -0
  647. package/dist/modules/order/utils/system.d.ts +268 -0
  648. package/dist/modules/order/utils/system.d.ts.map +1 -0
  649. package/dist/modules/order/utils/system.js +1261 -0
  650. package/dist/modules/order/utils/system.js.map +1 -0
  651. package/dist/modules/order/utils/validate.d.ts +280 -0
  652. package/dist/modules/order/utils/validate.d.ts.map +1 -0
  653. package/dist/modules/order/utils/validate.js +918 -0
  654. package/dist/modules/order/utils/validate.js.map +1 -0
  655. package/dist/modules/order/working_grid.d.ts +212 -0
  656. package/dist/modules/order/working_grid.d.ts.map +1 -0
  657. package/dist/modules/order/working_grid.js +279 -0
  658. package/dist/modules/order/working_grid.js.map +1 -0
  659. package/dist/modules/path_api.d.ts +32 -0
  660. package/dist/modules/path_api.d.ts.map +1 -0
  661. package/dist/modules/path_api.js +148 -0
  662. package/dist/modules/path_api.js.map +1 -0
  663. package/dist/modules/paths.d.ts +58 -0
  664. package/dist/modules/paths.d.ts.map +1 -0
  665. package/dist/modules/paths.js +82 -0
  666. package/dist/modules/paths.js.map +1 -0
  667. package/dist/modules/process_discovery.d.ts +58 -0
  668. package/dist/modules/process_discovery.d.ts.map +1 -0
  669. package/dist/modules/process_discovery.js +265 -0
  670. package/dist/modules/process_discovery.js.map +1 -0
  671. package/dist/modules/runtime.d.ts +34 -0
  672. package/dist/modules/runtime.d.ts.map +1 -0
  673. package/dist/modules/runtime.js +98 -0
  674. package/dist/modules/runtime.js.map +1 -0
  675. package/dist/modules/runtime_settings.d.ts +12 -0
  676. package/dist/modules/runtime_settings.d.ts.map +1 -0
  677. package/dist/modules/runtime_settings.js +122 -0
  678. package/dist/modules/runtime_settings.js.map +1 -0
  679. package/dist/modules/settings_merge.d.ts +38 -0
  680. package/dist/modules/settings_merge.d.ts.map +1 -0
  681. package/dist/modules/settings_merge.js +246 -0
  682. package/dist/modules/settings_merge.js.map +1 -0
  683. package/dist/modules/storage/browser_adapter.d.ts +56 -0
  684. package/dist/modules/storage/browser_adapter.d.ts.map +1 -0
  685. package/dist/modules/storage/browser_adapter.js +231 -0
  686. package/dist/modules/storage/browser_adapter.js.map +1 -0
  687. package/dist/modules/storage/index.d.ts +28 -0
  688. package/dist/modules/storage/index.d.ts.map +1 -0
  689. package/dist/modules/storage/index.js +52 -0
  690. package/dist/modules/storage/index.js.map +1 -0
  691. package/dist/modules/storage/node_adapter.d.ts +49 -0
  692. package/dist/modules/storage/node_adapter.d.ts.map +1 -0
  693. package/dist/modules/storage/node_adapter.js +167 -0
  694. package/dist/modules/storage/node_adapter.js.map +1 -0
  695. package/dist/modules/storage/types.d.ts +92 -0
  696. package/dist/modules/storage/types.d.ts.map +1 -0
  697. package/dist/modules/storage/types.js +3 -0
  698. package/dist/modules/storage/types.js.map +1 -0
  699. package/dist/modules/types.d.ts +1382 -0
  700. package/dist/modules/types.d.ts.map +1 -0
  701. package/dist/modules/types.js +11 -0
  702. package/dist/modules/types.js.map +1 -0
  703. package/dist/modules/utils/base58check.d.ts +12 -0
  704. package/dist/modules/utils/base58check.d.ts.map +1 -0
  705. package/dist/modules/utils/base58check.js +112 -0
  706. package/dist/modules/utils/base58check.js.map +1 -0
  707. package/dist/modules/utils/build_dir.d.ts +7 -0
  708. package/dist/modules/utils/build_dir.d.ts.map +1 -0
  709. package/dist/modules/utils/build_dir.js +8 -0
  710. package/dist/modules/utils/build_dir.js.map +1 -0
  711. package/dist/modules/utils/fs_utils.d.ts +25 -0
  712. package/dist/modules/utils/fs_utils.d.ts.map +1 -0
  713. package/dist/modules/utils/fs_utils.js +27 -0
  714. package/dist/modules/utils/fs_utils.js.map +1 -0
  715. package/dist/modules/utils/math_utils.d.ts +10 -0
  716. package/dist/modules/utils/math_utils.d.ts.map +1 -0
  717. package/dist/modules/utils/math_utils.js +17 -0
  718. package/dist/modules/utils/math_utils.js.map +1 -0
  719. package/dist/modules/validate_profiles.d.ts +37 -0
  720. package/dist/modules/validate_profiles.d.ts.map +1 -0
  721. package/dist/modules/validate_profiles.js +369 -0
  722. package/dist/modules/validate_profiles.js.map +1 -0
  723. package/dist/pm2.d.ts +167 -0
  724. package/dist/pm2.d.ts.map +1 -0
  725. package/dist/pm2.js +998 -0
  726. package/dist/pm2.js.map +1 -0
  727. package/dist/scripts/analyze-git.d.ts +11 -0
  728. package/dist/scripts/analyze-git.d.ts.map +1 -0
  729. package/dist/scripts/analyze-git.js +851 -0
  730. package/dist/scripts/analyze-git.js.map +1 -0
  731. package/dist/scripts/analyze-orders.d.ts +17 -0
  732. package/dist/scripts/analyze-orders.d.ts.map +1 -0
  733. package/dist/scripts/analyze-orders.js +1568 -0
  734. package/dist/scripts/analyze-orders.js.map +1 -0
  735. package/dist/scripts/diagnose-kibana-candles.d.ts +3 -0
  736. package/dist/scripts/diagnose-kibana-candles.d.ts.map +1 -0
  737. package/dist/scripts/diagnose-kibana-candles.js +82 -0
  738. package/dist/scripts/diagnose-kibana-candles.js.map +1 -0
  739. package/dist/scripts/diagnose-pool-history.d.ts +3 -0
  740. package/dist/scripts/diagnose-pool-history.d.ts.map +1 -0
  741. package/dist/scripts/diagnose-pool-history.js +296 -0
  742. package/dist/scripts/diagnose-pool-history.js.map +1 -0
  743. package/dist/scripts/divergence-calc.d.ts +26 -0
  744. package/dist/scripts/divergence-calc.d.ts.map +1 -0
  745. package/dist/scripts/divergence-calc.js +119 -0
  746. package/dist/scripts/divergence-calc.js.map +1 -0
  747. package/dist/scripts/generate_lp_chart.d.ts +31 -0
  748. package/dist/scripts/generate_lp_chart.d.ts.map +1 -0
  749. package/dist/scripts/generate_lp_chart.js +92 -0
  750. package/dist/scripts/generate_lp_chart.js.map +1 -0
  751. package/dist/scripts/generate_mainnet_corpus_report.d.ts +24 -0
  752. package/dist/scripts/generate_mainnet_corpus_report.d.ts.map +1 -0
  753. package/dist/scripts/generate_mainnet_corpus_report.js +237 -0
  754. package/dist/scripts/generate_mainnet_corpus_report.js.map +1 -0
  755. package/dist/scripts/generate_market_adapter_whitelist.d.ts +2 -0
  756. package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +1 -0
  757. package/dist/scripts/generate_market_adapter_whitelist.js +111 -0
  758. package/dist/scripts/generate_market_adapter_whitelist.js.map +1 -0
  759. package/dist/scripts/migrate_bot_keys.d.ts +6 -0
  760. package/dist/scripts/migrate_bot_keys.d.ts.map +1 -0
  761. package/dist/scripts/migrate_bot_keys.js +301 -0
  762. package/dist/scripts/migrate_bot_keys.js.map +1 -0
  763. package/dist/scripts/native_release_gates.d.ts +3 -0
  764. package/dist/scripts/native_release_gates.d.ts.map +1 -0
  765. package/dist/scripts/native_release_gates.js +52 -0
  766. package/dist/scripts/native_release_gates.js.map +1 -0
  767. package/dist/scripts/print_grid.d.ts +16 -0
  768. package/dist/scripts/print_grid.d.ts.map +1 -0
  769. package/dist/scripts/print_grid.js +80 -0
  770. package/dist/scripts/print_grid.js.map +1 -0
  771. package/dist/scripts/run-tests.d.ts +2 -0
  772. package/dist/scripts/run-tests.d.ts.map +1 -0
  773. package/dist/scripts/run-tests.js +49 -0
  774. package/dist/scripts/run-tests.js.map +1 -0
  775. package/dist/scripts/sync-version.d.ts +14 -0
  776. package/dist/scripts/sync-version.d.ts.map +1 -0
  777. package/dist/scripts/sync-version.js +158 -0
  778. package/dist/scripts/sync-version.js.map +1 -0
  779. package/dist/scripts/test-credit-renewal.d.ts +2 -0
  780. package/dist/scripts/test-credit-renewal.d.ts.map +1 -0
  781. package/dist/scripts/test-credit-renewal.js +329 -0
  782. package/dist/scripts/test-credit-renewal.js.map +1 -0
  783. package/dist/scripts/update.d.ts +24 -0
  784. package/dist/scripts/update.d.ts.map +1 -0
  785. package/dist/scripts/update.js +650 -0
  786. package/dist/scripts/update.js.map +1 -0
  787. package/dist/scripts/validate_bots.d.ts +16 -0
  788. package/dist/scripts/validate_bots.d.ts.map +1 -0
  789. package/dist/scripts/validate_bots.js +106 -0
  790. package/dist/scripts/validate_bots.js.map +1 -0
  791. package/dist/scripts/verify-browser-bundle.d.ts +22 -0
  792. package/dist/scripts/verify-browser-bundle.d.ts.map +1 -0
  793. package/dist/scripts/verify-browser-bundle.js +339 -0
  794. package/dist/scripts/verify-browser-bundle.js.map +1 -0
  795. package/dist/unlock.d.ts +48 -0
  796. package/dist/unlock.d.ts.map +1 -0
  797. package/dist/unlock.js +925 -0
  798. package/dist/unlock.js.map +1 -0
  799. package/package.json +112 -0
  800. package/scripts/README.md +356 -0
  801. package/scripts/clear-all.sh +195 -0
  802. package/scripts/clear-logs.sh +95 -0
  803. package/scripts/clear-market-adapter.sh +196 -0
  804. package/scripts/clear-orders.sh +113 -0
  805. package/scripts/create-bot-symlinks.sh +51 -0
  806. package/scripts/postinstall.js +9 -0
  807. package/scripts/reset-settings.sh +118 -0
@@ -0,0 +1,1717 @@
1
+ 'use strict';
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const { MARKET_ADAPTER } = require('../../modules/constants');
5
+ const { escapeHtml, serializeJsonForScript } = require('../chart_utils');
6
+ const { normalizeCandle } = require('../math_utils');
7
+ const { PATHS } = require('../../modules/paths');
8
+ const { readJSON } = require('../../modules/utils/fs_utils');
9
+ function inferBaseIntervalSeconds(candles, fallback = 3600) {
10
+ if (!Array.isArray(candles) || candles.length < 2)
11
+ return fallback;
12
+ const deltas = [];
13
+ for (let i = 1; i < candles.length; i++) {
14
+ const prev = Number(candles[i - 1]?.time);
15
+ const curr = Number(candles[i]?.time);
16
+ if (!Number.isFinite(prev) || !Number.isFinite(curr))
17
+ continue;
18
+ const d = curr - prev;
19
+ if (d > 0)
20
+ deltas.push(d);
21
+ }
22
+ if (deltas.length === 0)
23
+ return fallback;
24
+ deltas.sort((a, b) => a - b);
25
+ const mid = Math.floor(deltas.length / 2);
26
+ const med = deltas.length % 2 === 0 ? (deltas[mid - 1] + deltas[mid]) / 2 : deltas[mid];
27
+ return Math.max(60, Math.round(med));
28
+ }
29
+ function loadMarketProfiles(filePath = PATHS.PROFILES.MARKET_PROFILES_JSON) {
30
+ if (!filePath || !fs.existsSync(filePath))
31
+ return null;
32
+ try {
33
+ return readJSON(filePath);
34
+ }
35
+ catch (err) {
36
+ console.warn(`[WARN] Failed to parse ${filePath}: ${err.message}. Falling back to built-in AMA defaults.`);
37
+ return null;
38
+ }
39
+ }
40
+ function findMarketProfile(profiles, meta = {}) {
41
+ const entries = Array.isArray(profiles?.profiles) ? profiles.profiles : [];
42
+ if (!entries.length)
43
+ return null;
44
+ const assetA = meta.assetA?.symbol || meta.assetA?.id || meta.assetA;
45
+ const assetB = meta.assetB?.symbol || meta.assetB?.id || meta.assetB;
46
+ const intervalSeconds = Number(meta.intervalSeconds);
47
+ return entries.find((entry) => {
48
+ if (!entry || typeof entry !== 'object')
49
+ return false;
50
+ if (assetA && assetB) {
51
+ const matchesPair = (String(entry.assetA) === String(assetA) || String(entry.assetAId) === String(assetA))
52
+ && (String(entry.assetB) === String(assetB) || String(entry.assetBId) === String(assetB));
53
+ if (!matchesPair)
54
+ return false;
55
+ }
56
+ else {
57
+ return false;
58
+ }
59
+ if (Number.isFinite(intervalSeconds) && intervalSeconds > 0 && Number(entry.intervalSeconds) !== intervalSeconds) {
60
+ return false;
61
+ }
62
+ return true;
63
+ }) || null;
64
+ }
65
+ function resolveAmaDefaults({ meta, data, marketProfiles } = {}) {
66
+ const amaDefaultsSource = MARKET_ADAPTER.AMAS.AMA3;
67
+ const profile = findMarketProfile(marketProfiles, meta);
68
+ const profileAmaKey = profile?.defaultAma && profile.amas && profile.amas[profile.defaultAma]
69
+ ? profile.defaultAma
70
+ : null;
71
+ const profileAma = profileAmaKey ? profile.amas[profileAmaKey] : null;
72
+ const source = data?.amaDefaults || profileAma || amaDefaultsSource;
73
+ return {
74
+ erPeriod: Math.max(1, Math.round(Number(data?.amaErPeriod ?? source.erPeriod))),
75
+ fastPeriod: Number.isFinite(Number(data?.amaFastPeriod))
76
+ ? Number(data.amaFastPeriod)
77
+ : Number(source.fastPeriod),
78
+ slowPeriod: Number.isFinite(Number(data?.amaSlowPeriod))
79
+ ? Number(data.amaSlowPeriod)
80
+ : Number(source.slowPeriod),
81
+ };
82
+ }
83
+ function generateHTML(data, title = 'TradingView Style Research') {
84
+ const rawCandles = Array.isArray(data.candles) ? data.candles : [];
85
+ const candles = rawCandles.map(normalizeCandle).filter(Boolean);
86
+ if (candles.length === 0)
87
+ throw new Error('No candle data in input');
88
+ const meta = data.meta || {};
89
+ const baseIntervalSeconds = Number(meta.intervalSeconds) > 0
90
+ ? Number(meta.intervalSeconds)
91
+ : inferBaseIntervalSeconds(candles, 3600);
92
+ const timeframes = [
93
+ { label: '1h', seconds: 3600 },
94
+ { label: '4h', seconds: 14400 },
95
+ { label: '1d', seconds: 86400 },
96
+ { label: '1w', seconds: 604800 },
97
+ ].map((item) => ({ ...item, enabled: item.seconds >= baseIntervalSeconds }));
98
+ const defaultTimeframe = timeframes.find((item) => item.label === data.defaultTimeframe && item.enabled)
99
+ || timeframes.find((item) => item.enabled)
100
+ || timeframes[0];
101
+ const marketProfiles = data.marketProfiles || loadMarketProfiles();
102
+ const defaultAmaConfig = resolveAmaDefaults({ meta, data, marketProfiles });
103
+ const defaults = {
104
+ smaPeriod: Math.max(1, Math.round(data.smaPeriod ?? 500)),
105
+ amaDefaults: defaultAmaConfig,
106
+ smaEnabled: data.smaEnabled === true,
107
+ amaEnabled: data.amaEnabled === true,
108
+ vwapEnabled: data.vwapEnabled === true,
109
+ vwapBars: Math.max(5, Math.round(data.vwapBars ?? 500)),
110
+ priceScale: data.priceScale === 'linear' ? 'linear' : 'log',
111
+ };
112
+ const assetLabelA = meta.assetA?.symbol || meta.assetA?.id || 'Asset A';
113
+ const assetLabelB = meta.assetB?.symbol || meta.assetB?.id || 'Asset B';
114
+ const pairLabelNormal = `${assetLabelA}/${assetLabelB}`;
115
+ const pairLabelInverse = `${assetLabelB}/${assetLabelA}`;
116
+ const poolLabel = meta.pool ? `Pool ${String(meta.pool).replace(/^1\.19\./, '')}` : 'Pair';
117
+ const intervalLabel = baseIntervalSeconds >= 86400
118
+ ? `${Math.round(baseIntervalSeconds / 86400)}d`
119
+ : `${Math.round(baseIntervalSeconds / 3600)}h`;
120
+ const defaultPairMode = data.defaultPairMode === 'inverse' ? 'inverse' : 'normal';
121
+ const payload = {
122
+ candles,
123
+ timeframes,
124
+ defaultTimeframe: defaultTimeframe.label,
125
+ smaPeriod: defaults.smaPeriod,
126
+ amaDefaults: defaultAmaConfig,
127
+ smaEnabled: defaults.smaEnabled,
128
+ amaEnabled: defaults.amaEnabled,
129
+ vwapEnabled: defaults.vwapEnabled,
130
+ vwapBars: defaults.vwapBars,
131
+ priceScale: defaults.priceScale,
132
+ defaultPairMode,
133
+ assetLabelA,
134
+ assetLabelB,
135
+ pairLabelNormal,
136
+ pairLabelInverse,
137
+ poolLabel,
138
+ intervalLabel,
139
+ amaDefaultsSource: marketProfiles ? 'market_profiles' : 'constants',
140
+ };
141
+ return `<!doctype html>
142
+ <html lang="en">
143
+ <head>
144
+ <meta charset="utf-8">
145
+ <meta name="color-scheme" content="dark">
146
+ <meta name="darkreader-lock">
147
+ <meta name="viewport" content="width=device-width, initial-scale=1">
148
+ <title>${escapeHtml(title)}</title>
149
+ <link rel="stylesheet" href="../uplot/uPlot.min.css">
150
+ <script src="../uplot/uPlot.iife.min.js"></script>
151
+ <style>
152
+ * { box-sizing: border-box; }
153
+ :root { color-scheme: dark; }
154
+ body {
155
+ margin: 0;
156
+ overflow: hidden;
157
+ background: linear-gradient(180deg, #090d12 0%, #0b0f14 40%, #0a0c11 100%);
158
+ color: #d7e0ea;
159
+ font-family: Inter, "Segoe UI", system-ui, sans-serif;
160
+ }
161
+ #app { height: 100vh; display: flex; flex-direction: column; }
162
+ #topbar {
163
+ display: flex;
164
+ justify-content: space-between;
165
+ gap: 16px;
166
+ padding: 12px 16px 10px;
167
+ border-bottom: 1px solid #263241;
168
+ background: rgba(15,19,26,0.94);
169
+ backdrop-filter: blur(10px);
170
+ }
171
+ #brand { display: flex; flex-direction: column; gap: 4px; min-width: 240px; }
172
+ #title { font-size: 15px; font-weight: 700; color: #f5f8fb; }
173
+ #subtitle { font-size: 11px; color: #8290a2; text-transform: uppercase; letter-spacing: 0.6px; }
174
+ #toolbar { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px 12px; align-items: center; }
175
+ .group { display: inline-flex; align-items: center; gap: 8px; padding-left: 12px; border-left: 1px solid #263241; }
176
+ .group:first-child { padding-left: 0; border-left: 0; }
177
+ :root {
178
+ --control-height: 36px;
179
+ }
180
+ .time-btn {
181
+ appearance: none;
182
+ border: 1px solid #263241;
183
+ background: rgba(24,30,39,0.85);
184
+ color: #8290a2;
185
+ font-size: 11px;
186
+ font-weight: 700;
187
+ letter-spacing: 0.5px;
188
+ text-transform: uppercase;
189
+ padding: 7px 10px;
190
+ border-radius: 8px;
191
+ cursor: pointer;
192
+ }
193
+ .time-btn.active {
194
+ color: #fff;
195
+ border-color: rgba(94,161,255,0.85);
196
+ background: linear-gradient(180deg, rgba(35,53,79,0.95), rgba(22,32,47,0.98));
197
+ }
198
+ .time-btn:disabled { opacity: 0.35; cursor: not-allowed; text-decoration: line-through; }
199
+ .indicator {
200
+ display: inline-flex;
201
+ align-items: center;
202
+ gap: 8px;
203
+ min-height: var(--control-height);
204
+ padding: 0 13px;
205
+ border: 1px solid #263241;
206
+ border-radius: 10px;
207
+ background: rgba(20,25,33,0.86);
208
+ }
209
+ .indicator label {
210
+ display: inline-flex;
211
+ align-items: center;
212
+ gap: 6px;
213
+ min-height: var(--control-height);
214
+ font-size: 11px;
215
+ font-weight: 700;
216
+ color: #d7e0ea;
217
+ text-transform: uppercase;
218
+ white-space: nowrap;
219
+ }
220
+ .indicator input[type="checkbox"] { width: 14px; height: 14px; accent-color: #5ea1ff; }
221
+ .indicator input[type="number"], .indicator select {
222
+ appearance: none;
223
+ border: 1px solid #263241;
224
+ background: rgba(10,14,19,0.92);
225
+ color: #d7e0ea;
226
+ border-radius: 8px;
227
+ padding: 7px 10px;
228
+ font-size: 11px;
229
+ outline: none;
230
+ width: 79px;
231
+ min-width: 79px;
232
+ height: calc(var(--control-height) - 8px);
233
+ }
234
+ .pair-toggle {
235
+ appearance: none;
236
+ width: 32px;
237
+ height: 32px;
238
+ display: inline-flex;
239
+ align-items: center;
240
+ justify-content: center;
241
+ border: 1px solid #263241;
242
+ border-radius: 999px;
243
+ background: radial-gradient(circle at 30% 30%, rgba(94,161,255,0.18), rgba(10,14,19,0.96));
244
+ color: #d7e0ea;
245
+ cursor: pointer;
246
+ padding: 0;
247
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,0.03);
248
+ transition: transform 120ms ease, border-color 120ms ease, background 120ms ease, color 120ms ease;
249
+ }
250
+ .pair-toggle:hover {
251
+ transform: translateY(-1px);
252
+ border-color: rgba(94,161,255,0.85);
253
+ color: #fff;
254
+ }
255
+ .pair-toggle:active {
256
+ transform: translateY(0);
257
+ }
258
+ .pair-toggle svg {
259
+ width: 17px;
260
+ height: 17px;
261
+ fill: currentColor;
262
+ display: block;
263
+ }
264
+ .pair-toggle.is-inverse {
265
+ color: #5ea1ff;
266
+ border-color: rgba(94,161,255,0.45);
267
+ }
268
+ .indicator .step-stack {
269
+ display: inline-flex;
270
+ flex-direction: column;
271
+ vertical-align: middle;
272
+ margin-left: 2px;
273
+ }
274
+ .indicator .step-btn {
275
+ appearance: none;
276
+ display: block;
277
+ width: 24px;
278
+ height: 13px;
279
+ border: 1px solid #3d4a5a;
280
+ background: #1a2332;
281
+ color: #8b949e;
282
+ font-size: 9px;
283
+ line-height: 1;
284
+ cursor: pointer;
285
+ padding: 0;
286
+ margin: 0;
287
+ }
288
+ .indicator .step-btn:first-child {
289
+ border-radius: 3px 3px 0 0;
290
+ border-bottom: none;
291
+ }
292
+ .indicator .step-btn:last-child {
293
+ border-radius: 0 0 3px 3px;
294
+ }
295
+ .indicator .step-btn:hover {
296
+ background: #263241;
297
+ }
298
+ .indicator .step-btn:active {
299
+ background: #3d4a5a;
300
+ }
301
+ .indicator input[type="text"] {
302
+ appearance: none;
303
+ border: 1px solid #263241;
304
+ background: rgba(6,8,12,0.95);
305
+ color: #d7e0ea;
306
+ border-radius: 8px;
307
+ padding: 7px 4px;
308
+ font-size: 12px;
309
+ outline: none;
310
+ width: 44px;
311
+ text-align: center;
312
+ }
313
+ .indicator input[type="text"]:focus {
314
+ border-color: #5ea1ff;
315
+ }
316
+ #ama-fast {
317
+ width: 38px;
318
+ }
319
+ .scale-toggle {
320
+ appearance: none;
321
+ min-width: 76px;
322
+ height: 32px;
323
+ display: inline-flex;
324
+ align-items: center;
325
+ justify-content: center;
326
+ border: 1px solid #263241;
327
+ border-radius: 999px;
328
+ background: rgba(10,14,19,0.92);
329
+ color: #d7e0ea;
330
+ font-size: 11px;
331
+ font-weight: 700;
332
+ letter-spacing: 0.45px;
333
+ text-transform: uppercase;
334
+ cursor: pointer;
335
+ padding: 0 11px;
336
+ transition: transform 120ms ease, border-color 120ms ease, background 120ms ease, color 120ms ease;
337
+ }
338
+ .scale-toggle:hover {
339
+ transform: translateY(-1px);
340
+ border-color: rgba(94,161,255,0.85);
341
+ color: #fff;
342
+ }
343
+ .scale-toggle:active {
344
+ transform: translateY(0);
345
+ }
346
+ .scale-toggle.is-linear {
347
+ color: #5ea1ff;
348
+ border-color: rgba(94,161,255,0.45);
349
+ }
350
+ .reset-btn {
351
+ appearance: none;
352
+ border: 1px solid #263241;
353
+ background: rgba(24,30,39,0.85);
354
+ color: #d7e0ea;
355
+ font-size: 11px;
356
+ font-weight: 700;
357
+ letter-spacing: 0.45px;
358
+ text-transform: uppercase;
359
+ padding: 6px 11px;
360
+ border-radius: 8px;
361
+ cursor: pointer;
362
+ }
363
+ .reset-btn:hover {
364
+ border-color: rgba(94,161,255,0.85);
365
+ color: #fff;
366
+ }
367
+ .indicator .tag { font-size: 10px; color: #8290a2; text-transform: uppercase; letter-spacing: 0.5px; }
368
+ #chart-shell { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
369
+ #price-chart { position: relative; flex: 1 1 auto; min-height: 0; }
370
+ #volume-chart { position: relative; flex: 0 0 19%; min-height: 0; border-top: 1px solid #263241; }
371
+ #legend {
372
+ position: absolute;
373
+ top: 14px;
374
+ left: 14px;
375
+ z-index: 4;
376
+ padding: 10px 12px;
377
+ min-width: 280px;
378
+ max-width: calc(100vw - 28px);
379
+ border: 1px solid #263241;
380
+ border-radius: 12px;
381
+ background: rgba(10,14,20,0.72);
382
+ backdrop-filter: blur(10px);
383
+ }
384
+ .legend-line { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; font-size: 11px; }
385
+ .legend-line + .legend-line { margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(255,255,255,0.06); }
386
+ .legend-item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
387
+ .legend-dot { width: 10px; height: 10px; border-radius: 999px; flex: 0 0 auto; }
388
+ .legend-label { color: #8290a2; text-transform: uppercase; letter-spacing: 0.45px; font-size: 10px; }
389
+ .legend-value { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: #eef4fb; font-weight: 700; }
390
+ .status { display: inline-flex; align-items: center; gap: 8px; font-size: 10px; color: #8290a2; text-transform: uppercase; letter-spacing: 0.5px; }
391
+ .pill { border: 1px solid rgba(255,255,255,0.06); border-radius: 999px; padding: 4px 8px; background: rgba(255,255,255,0.03); }
392
+ .uplot { background: #0b0f14; }
393
+ .u-cursor-x { border-left: 1px dashed rgba(255,255,255,0.3) !important; }
394
+ .u-cursor-y { border-top: 1px dashed rgba(255,255,255,0.3) !important; display: none; }
395
+ .is-hovered .u-cursor-y { display: block; }
396
+ @media (max-width: 980px) {
397
+ #topbar { flex-direction: column; align-items: flex-start; }
398
+ #toolbar { justify-content: flex-start; }
399
+ .group { padding-left: 0; border-left: 0; flex-wrap: wrap; }
400
+ #legend { min-width: 0; max-width: calc(100vw - 24px); }
401
+ }
402
+ </style>
403
+ </head>
404
+ <body>
405
+ <div id="app">
406
+ <div id="topbar">
407
+ <div id="brand">
408
+ <div id="title">${escapeHtml(title)}</div>
409
+ <div id="subtitle">${escapeHtml(poolLabel)} · ${escapeHtml(pairLabelNormal)} · ${escapeHtml(intervalLabel)} base · indicators from 1h · volume · uPlot</div>
410
+ </div>
411
+ <div id="toolbar">
412
+ <div class="group" id="tf-group">
413
+ ${timeframes.map((item) => `<button class="time-btn${item.label === defaultTimeframe.label ? ' active' : ''}" data-timeframe="${escapeHtml(item.label)}"${item.enabled ? '' : ' disabled'}>${escapeHtml(item.label)}</button>`).join('')}
414
+ </div>
415
+ <div class="group">
416
+ <div class="indicator">
417
+ <span class="tag">pair</span>
418
+ <button type="button" class="pair-toggle${defaultPairMode === 'inverse' ? ' is-inverse' : ''}" id="pair-toggle" aria-label="Swap pair orientation" title="Swap pair orientation" data-pair-mode="${escapeHtml(defaultPairMode)}">
419
+ <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
420
+ <path d="M6.5 7H19v2H6.5v3L2 8.5 6.5 5v2Zm11 10H5v-2h12.5v-3L22 15.5 17.5 19v-2Z"/>
421
+ </svg>
422
+ </button>
423
+ </div>
424
+ <div class="indicator">
425
+ <span class="tag">scale</span>
426
+ <button type="button" class="scale-toggle${defaults.priceScale === 'linear' ? ' is-linear' : ''}" id="scale-toggle" data-scale="${escapeHtml(defaults.priceScale)}" aria-label="Toggle price scale" title="Toggle price scale">${defaults.priceScale === 'linear' ? 'Linear' : 'Log'}</button>
427
+ </div>
428
+ <div class="indicator">
429
+ <label><input type="checkbox" id="sma-toggle"${defaults.smaEnabled ? ' checked' : ''}> SMA</label>
430
+ <span class="tag">period</span>
431
+ <input type="text" inputmode="numeric" id="sma-period" value="${defaults.smaPeriod}">
432
+ <span class="step-stack">
433
+ <button type="button" class="step-btn" id="sma-period-inc">▲</button>
434
+ <button type="button" class="step-btn" id="sma-period-dec">▼</button>
435
+ </span>
436
+ </div>
437
+ <div class="indicator">
438
+ <label><input type="checkbox" id="vwap-toggle"${defaults.vwapEnabled ? ' checked' : ''}> VWMA</label>
439
+ <span class="tag">bars</span>
440
+ <input type="text" inputmode="numeric" id="vwap-bars" value="${defaults.vwapBars}">
441
+ <span class="step-stack">
442
+ <button type="button" class="step-btn" id="vwap-bars-inc">▲</button>
443
+ <button type="button" class="step-btn" id="vwap-bars-dec">▼</button>
444
+ </span>
445
+ </div>
446
+ <div class="indicator">
447
+ <label><input type="checkbox" id="ama-toggle"${defaults.amaEnabled ? ' checked' : ''}> AMA</label>
448
+ <span class="tag">er</span>
449
+ <input type="text" inputmode="numeric" id="ama-er" value="${defaults.amaDefaults.erPeriod}">
450
+ <span class="step-stack">
451
+ <button type="button" class="step-btn" id="ama-er-inc">▲</button>
452
+ <button type="button" class="step-btn" id="ama-er-dec">▼</button>
453
+ </span>
454
+ <span class="tag">fast</span>
455
+ <input type="text" inputmode="decimal" id="ama-fast" value="${defaults.amaDefaults.fastPeriod}">
456
+ <span class="step-stack">
457
+ <button type="button" class="step-btn" id="ama-fast-inc">▲</button>
458
+ <button type="button" class="step-btn" id="ama-fast-dec">▼</button>
459
+ </span>
460
+ <span class="tag">slow</span>
461
+ <input type="text" inputmode="decimal" id="ama-slow" value="${defaults.amaDefaults.slowPeriod}">
462
+ <span class="step-stack">
463
+ <button type="button" class="step-btn" id="ama-slow-inc">▲</button>
464
+ <button type="button" class="step-btn" id="ama-slow-dec">▼</button>
465
+ </span>
466
+ <button type="button" class="reset-btn" id="ama-reset">Reset</button>
467
+ </div>
468
+ <div class="indicator" style="margin-top:4px">
469
+ <label><input type="checkbox" id="ama-init-offset-toggle"> Init Offset</label>
470
+ <input type="range" id="ama-init-offset" min="-50" max="50" value="0" step="1" style="width:120px;vertical-align:middle" disabled>
471
+ <span id="ama-init-offset-val" style="font-size:11px;color:#8b949e;width:32px;display:inline-block;text-align:right">0%</span>
472
+ </div>
473
+ </div>
474
+ <div class="group"></div>
475
+ </div>
476
+ </div>
477
+ <div id="chart-shell">
478
+ <div id="legend">
479
+ <div class="legend-line">
480
+ <span class="legend-item"><span class="legend-label">Time</span> <span class="legend-value" id="legend-time">-</span></span>
481
+ <span class="legend-item"><span class="legend-label">C</span> <span class="legend-value" id="legend-close">-</span></span>
482
+ <span class="legend-item"><span class="legend-label">Delta</span> <span class="legend-value" id="legend-delta">-</span></span>
483
+ <span class="legend-item"><span class="legend-label">Vol</span> <span class="legend-value" id="legend-volume">-</span></span>
484
+ <span class="legend-item"><span class="legend-label">Scale</span> <span class="legend-value" id="legend-scale">-</span></span>
485
+ </div>
486
+ <div class="legend-line">
487
+ <span class="legend-item"><span class="legend-dot" style="background:#f59e0b"></span><span class="legend-label">SMA</span> <span class="legend-value" id="legend-sma">-</span></span>
488
+ <span class="legend-item"><span class="legend-dot" style="background:#2dd4bf"></span><span class="legend-label">AMA</span> <span class="legend-value" id="legend-ama">-</span></span>
489
+ <span class="legend-item"><span class="legend-dot" style="background:#22c55e"></span><span class="legend-label">AMA Init</span> <span class="legend-value" id="legend-sma-init">-</span></span>
490
+ <span class="legend-item"><span class="legend-dot" style="background:#a855f7"></span><span class="legend-label">Off Init</span> <span class="legend-value" id="legend-off-init">-</span></span>
491
+ <span class="legend-item"><span class="legend-dot" style="background:#a855f7"></span><span class="legend-label">AMA Off</span> <span class="legend-value" id="legend-ama-off">-</span></span>
492
+
493
+ <span class="legend-item"><span class="legend-dot" style="background:#93c5fd"></span><span class="legend-label">VWMA</span> <span class="legend-value" id="legend-vwap">-</span></span>
494
+ </div>
495
+ </div>
496
+ <div id="price-chart"></div>
497
+ <div id="volume-chart"></div>
498
+ </div>
499
+ </div>
500
+
501
+ <script id="payload" type="application/json">${serializeJsonForScript(payload)}</script>
502
+ <script>
503
+ (function () {
504
+ const payload = JSON.parse(document.getElementById('payload').textContent);
505
+ const priceEl = document.getElementById('price-chart');
506
+ const volumeEl = document.getElementById('volume-chart');
507
+ const baseCandles = Array.isArray(payload.candles) ? payload.candles.slice() : [];
508
+ const baseCloseValues = baseCandles.map((c) => c.close);
509
+ const timeframes = Array.isArray(payload.timeframes) ? payload.timeframes.slice() : [];
510
+ const timeframeMap = new Map(timeframes.map((item) => [item.label, item]));
511
+ const STORAGE_KEY = 'dexbot2-tradingview-uplot-v2';
512
+
513
+ const state = loadState();
514
+ let currentTimeframe = state.timeframe || payload.defaultTimeframe || '1h';
515
+ let currentSmaEnabled = state.smaEnabled ?? !!payload.smaEnabled;
516
+ let currentSmaPeriod = Number.isFinite(state.smaPeriod) ? state.smaPeriod : Number(payload.smaPeriod || 500);
517
+ let currentAmaEnabled = state.amaEnabled ?? !!payload.amaEnabled;
518
+ let currentAmaErPeriod = Number.isFinite(state.amaErPeriod)
519
+ ? Number(state.amaErPeriod)
520
+ : Number(payload.amaDefaults?.erPeriod || ${MARKET_ADAPTER.AMAS.AMA3.erPeriod});
521
+ let currentAmaFastPeriod = Number.isFinite(state.amaFastPeriod)
522
+ ? Number(state.amaFastPeriod)
523
+ : Number(payload.amaDefaults?.fastPeriod || ${MARKET_ADAPTER.AMAS.AMA3.fastPeriod});
524
+ let currentAmaSlowPeriod = Number.isFinite(state.amaSlowPeriod)
525
+ ? Number(state.amaSlowPeriod)
526
+ : Number(payload.amaDefaults?.slowPeriod || ${MARKET_ADAPTER.AMAS.AMA3.slowPeriod});
527
+ let currentVwapEnabled = state.vwapEnabled ?? !!payload.vwapEnabled;
528
+ let currentVwapBars = Number.isFinite(state.vwapBars) ? state.vwapBars : Number(payload.vwapBars || 500);
529
+ let currentAmaInitOffsetEnabled = false;
530
+ let currentAmaInitOffset = Number.isFinite(state.amaInitOffset) ? state.amaInitOffset : 0;
531
+ let currentPriceScale = state.priceScale || payload.priceScale || 'log';
532
+ let currentPairMode = state.pairMode === 'inverse' ? 'inverse' : (payload.defaultPairMode === 'inverse' ? 'inverse' : 'normal');
533
+ let currentCandles = [];
534
+ let currentSeriesState = null;
535
+ let currentSeriesCandles = baseCandles;
536
+ let currentSeriesCloseValues = baseCloseValues;
537
+ let currentOpen = [];
538
+ let currentHigh = [];
539
+ let currentLow = [];
540
+ let currentClose = [];
541
+ let currentDisplayCandles = [];
542
+ let currentPriceData = [];
543
+ let currentVolumeData = [];
544
+ let currentSma = [];
545
+ let currentAma = [];
546
+ let currentVwap = [];
547
+ let currentSmaInit = [];
548
+ let currentSmaInitOff = [];
549
+ let currentAmaOff = [];
550
+ let priceChart = null;
551
+ let volumeChart = null;
552
+ let lastRenderedPriceScale = null;
553
+ let charts = [];
554
+ let chartEventsBound = false;
555
+ let pendingRange = null;
556
+ let pendingRangeRaf = 0;
557
+ let smaWorker = null;
558
+ let smaWorkerJob = null;
559
+ let smaWorkerStartRaf = 0;
560
+ let smaWorkerPaintRaf = 0;
561
+ let smaWorkerSeq = 0;
562
+ const aggregateCache = new Map();
563
+ const smaCache = new Map();
564
+ const amaCache = new Map();
565
+ const vwapCache = new Map();
566
+ const seriesCache = new Map();
567
+
568
+ function clamp(v, lo, hi) { return Math.max(lo, Math.min(hi, v)); }
569
+ function fmtPrice(v) {
570
+ if (v == null || !Number.isFinite(v)) return '-';
571
+ const abs = Math.abs(v);
572
+ if (abs >= 1000) return v.toFixed(2);
573
+ if (abs >= 100) return v.toFixed(3);
574
+ if (abs >= 1) return v.toFixed(4);
575
+ return v.toPrecision(6);
576
+ }
577
+ function fmtVolume(v) {
578
+ if (v == null || !Number.isFinite(v)) return '-';
579
+ const abs = Math.abs(v);
580
+ if (abs >= 1e9) return (v / 1e9).toFixed(2) + 'B';
581
+ if (abs >= 1e6) return (v / 1e6).toFixed(2) + 'M';
582
+ if (abs >= 1e3) return (v / 1e3).toFixed(2) + 'K';
583
+ return v.toFixed(2);
584
+ }
585
+ function candleDirection(open, close) {
586
+ if (close > open) return 'up';
587
+ if (close < open) return 'down';
588
+ return 'flat';
589
+ }
590
+ function fmtTime(ts) {
591
+ if (!Number.isFinite(ts)) return '-';
592
+ const d = new Date(ts * 1000);
593
+ return d.toLocaleString(undefined, { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' });
594
+ }
595
+ function pad2(n) {
596
+ return String(n).padStart(2, '0');
597
+ }
598
+ function formatTimeLabel(tsSec, spanSec) {
599
+ const d = new Date(tsSec * 1000);
600
+ if (!Number.isFinite(spanSec)) spanSec = 0;
601
+ if (spanSec >= 365 * 24 * 3600 * 2) {
602
+ return String(d.getUTCFullYear());
603
+ }
604
+ if (spanSec >= 90 * 24 * 3600) {
605
+ return d.toLocaleString(undefined, { month: 'short', year: 'numeric', timeZone: 'UTC' });
606
+ }
607
+ if (spanSec >= 14 * 24 * 3600) {
608
+ return d.toLocaleString(undefined, { month: 'short', day: '2-digit', timeZone: 'UTC' });
609
+ }
610
+ return d.toLocaleString(undefined, { month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'UTC' });
611
+ }
612
+ function makeTimeAxis(showLabels) {
613
+ return {
614
+ show: true,
615
+ size: showLabels ? 24 : 14,
616
+ stroke: '#545d68',
617
+ grid: { stroke: '#1c2128' },
618
+ ticks: { stroke: '#30363d', width: 1 },
619
+ font: '11px Segoe UI, sans-serif',
620
+ values: showLabels ? (u, vals) => {
621
+ const xScale = u.scales.x || {};
622
+ const spanSec = Number.isFinite(xScale.min) && Number.isFinite(xScale.max)
623
+ ? Math.max(0, xScale.max - xScale.min)
624
+ : 0;
625
+ return vals.map((ts) => formatTimeLabel(ts, spanSec));
626
+ } : () => [],
627
+ };
628
+ }
629
+ function loadState() {
630
+ try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}'); } catch (e) { return {}; }
631
+ }
632
+ function saveState() {
633
+ try {
634
+ localStorage.setItem(STORAGE_KEY, JSON.stringify({
635
+ timeframe: currentTimeframe,
636
+ smaEnabled: currentSmaEnabled,
637
+ smaPeriod: currentSmaPeriod,
638
+ amaEnabled: currentAmaEnabled,
639
+ amaErPeriod: currentAmaErPeriod,
640
+ amaFastPeriod: currentAmaFastPeriod,
641
+ amaSlowPeriod: currentAmaSlowPeriod,
642
+ vwapEnabled: currentVwapEnabled,
643
+ vwapBars: currentVwapBars,
644
+ amaInitOffset: currentAmaInitOffset,
645
+ priceScale: currentPriceScale,
646
+ pairMode: currentPairMode,
647
+ }));
648
+ } catch (e) {}
649
+ }
650
+ function normalizePairMode(mode) {
651
+ return String(mode).toLowerCase() === 'inverse' ? 'inverse' : 'normal';
652
+ }
653
+ function getPairLabel(mode = currentPairMode) {
654
+ return normalizePairMode(mode) === 'inverse'
655
+ ? (payload.pairLabelInverse || (payload.assetLabelB + '/' + payload.assetLabelA))
656
+ : (payload.pairLabelNormal || (payload.assetLabelA + '/' + payload.assetLabelB));
657
+ }
658
+ function refreshSubtitle() {
659
+ const subtitleEl = document.getElementById('subtitle');
660
+ if (!subtitleEl) return;
661
+ subtitleEl.textContent = payload.poolLabel + ' · ' + getPairLabel() + ' · ' + payload.intervalLabel + ' base · indicators from 1h · volume · uPlot';
662
+ }
663
+ function snapInitOffset(value) {
664
+ const next = Math.round(Number(value) || 0);
665
+ return Math.abs(next) <= 2 ? 0 : next;
666
+ }
667
+ function setActivePairMode(mode) {
668
+ const label = normalizePairMode(mode);
669
+ const btn = document.getElementById('pair-toggle');
670
+ if (!btn) return;
671
+ btn.dataset.pairMode = label;
672
+ btn.classList.toggle('is-inverse', label === 'inverse');
673
+ btn.title = label === 'inverse' ? 'Swap to A/B' : 'Swap to B/A';
674
+ btn.setAttribute('aria-label', label === 'inverse' ? 'Swap to A/B' : 'Swap to B/A');
675
+ }
676
+ function invertCandle(candle) {
677
+ const open = Number(candle?.open);
678
+ const high = Number(candle?.high);
679
+ const low = Number(candle?.low);
680
+ const close = Number(candle?.close);
681
+ if (![open, high, low, close].every(Number.isFinite) || open <= 0 || high <= 0 || low <= 0 || close <= 0) return null;
682
+ const volume = Number(candle?.volume);
683
+ return {
684
+ time: candle.time,
685
+ open: 1 / open,
686
+ high: 1 / low,
687
+ low: 1 / high,
688
+ close: 1 / close,
689
+ // Convert base-asset volume into the inverse pair's base units approximately.
690
+ volume: Number.isFinite(volume) ? volume * close : 0,
691
+ };
692
+ }
693
+ function getSeriesState(mode = currentPairMode) {
694
+ const key = normalizePairMode(mode);
695
+ if (seriesCache.has(key)) return seriesCache.get(key);
696
+ const candles = key === 'inverse'
697
+ ? baseCandles.map(invertCandle).filter(Boolean)
698
+ : baseCandles.slice();
699
+ const state = {
700
+ candles,
701
+ closeValues: candles.map((c) => c.close),
702
+ };
703
+ seriesCache.set(key, state);
704
+ return state;
705
+ }
706
+ function aggregateCandles(rows, seconds) {
707
+ const bucketSec = Math.max(1, Math.round(seconds || 3600));
708
+ const cacheKey = currentPairMode + '|' + bucketSec;
709
+ if (aggregateCache.has(cacheKey)) return aggregateCache.get(cacheKey);
710
+ const out = [];
711
+ const idxs = [];
712
+ let cur = null;
713
+ let curBucket = null;
714
+ let curIdx = -1;
715
+ for (let i = 0; i < rows.length; i++) {
716
+ const row = rows[i];
717
+ const ts = Number(row.time);
718
+ if (!Number.isFinite(ts)) continue;
719
+ const bucket = Math.floor(ts / bucketSec) * bucketSec;
720
+ if (!cur || bucket !== curBucket) {
721
+ if (cur) {
722
+ out.push(cur);
723
+ idxs.push(curIdx);
724
+ }
725
+ curBucket = bucket;
726
+ curIdx = i;
727
+ cur = { time: bucket, open: row.open, high: row.high, low: row.low, close: row.close, volume: row.volume || 0 };
728
+ } else {
729
+ cur.high = Math.max(cur.high, row.high);
730
+ cur.low = Math.min(cur.low, row.low);
731
+ cur.close = row.close;
732
+ cur.volume += row.volume || 0;
733
+ curIdx = i;
734
+ }
735
+ }
736
+ if (cur) {
737
+ out.push(cur);
738
+ idxs.push(curIdx);
739
+ }
740
+ const result = { candles: out, idxs };
741
+ aggregateCache.set(cacheKey, result);
742
+ return result;
743
+ }
744
+ function sampleSeriesByIndex(series, idxs) {
745
+ if (!Array.isArray(series) || !Array.isArray(idxs)) return [];
746
+ return idxs.map((idx) => (Number.isFinite(idx) && series[idx] != null ? series[idx] : null));
747
+ }
748
+ function deriveDisplayCandles(candles) {
749
+ if (!Array.isArray(candles) || candles.length === 0) return [];
750
+ return candles.map((c, i) => {
751
+ const prevClose = i > 0 ? candles[i - 1].close : c.close;
752
+ const open = Number.isFinite(prevClose) ? prevClose : c.close;
753
+ const close = c.close;
754
+ return {
755
+ time: c.time,
756
+ open,
757
+ close,
758
+ volume: c.volume,
759
+ };
760
+ });
761
+ }
762
+ function computeSMA(candles, period) {
763
+ const safePeriod = Math.max(1, Math.round(period));
764
+ const cacheKey = currentPairMode + '|' + safePeriod + '|' + candles.length;
765
+ if (smaCache.has(cacheKey)) return smaCache.get(cacheKey);
766
+ const out = [];
767
+ let sum = 0;
768
+ const window = new Array(safePeriod);
769
+ let head = 0;
770
+ let count = 0;
771
+ for (const candle of candles) {
772
+ const price = candle.close;
773
+ if (count < safePeriod) {
774
+ window[count] = price;
775
+ sum += price;
776
+ count++;
777
+ out.push(count === safePeriod ? (sum / safePeriod) : null);
778
+ continue;
779
+ }
780
+ sum -= window[head];
781
+ window[head] = price;
782
+ sum += price;
783
+ head = (head + 1) % safePeriod;
784
+ out.push(sum / safePeriod);
785
+ }
786
+ smaCache.set(cacheKey, out);
787
+ return out;
788
+ }
789
+ function getSmaCacheKey(period) {
790
+ return currentPairMode + '|' + Math.max(1, Math.round(period)) + '|' + currentSeriesCloseValues.length;
791
+ }
792
+ function createSMAWorker() {
793
+ if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined') return null;
794
+ const workerSource = [
795
+ 'self.onmessage = function(e) {',
796
+ ' const data = e.data || {};',
797
+ ' const id = data.id;',
798
+ ' const key = data.key;',
799
+ ' const closes = Array.isArray(data.closes) ? data.closes : [];',
800
+ ' const period = Math.max(1, Math.round(Number(data.period) || 1));',
801
+ ' const out = new Array(closes.length);',
802
+ ' const window = new Array(period);',
803
+ ' let sum = 0;',
804
+ ' let head = 0;',
805
+ ' let count = 0;',
806
+ ' for (let i = 0; i < closes.length; i++) {',
807
+ ' const price = Number(closes[i]);',
808
+ ' if (count < period) {',
809
+ ' window[count] = price;',
810
+ ' sum += price;',
811
+ ' count++;',
812
+ ' out[i] = count === period ? (sum / period) : null;',
813
+ ' continue;',
814
+ ' }',
815
+ ' sum -= window[head];',
816
+ ' window[head] = price;',
817
+ ' sum += price;',
818
+ ' head = (head + 1) % period;',
819
+ ' out[i] = sum / period;',
820
+ ' }',
821
+ ' self.postMessage({ id, key, series: out });',
822
+ '};',
823
+ ].join('\\n');
824
+ const blob = new Blob([workerSource], { type: 'text/javascript' });
825
+ const worker = new Worker(URL.createObjectURL(blob));
826
+ worker.onmessage = (e) => {
827
+ const msg = e && e.data ? e.data : {};
828
+ if (!smaWorkerJob || msg.id !== smaWorkerJob.id || msg.key !== smaWorkerJob.key) return;
829
+ smaCache.set(msg.key, Array.isArray(msg.series) ? msg.series : []);
830
+ smaWorkerJob = null;
831
+ if (currentSmaEnabled && msg.key === getSmaCacheKey(currentSmaPeriod)) {
832
+ rerender(false);
833
+ }
834
+ };
835
+ worker.onerror = () => {
836
+ try { worker.terminate(); } catch (e) {}
837
+ smaWorker = null;
838
+ smaWorkerJob = null;
839
+ };
840
+ return worker;
841
+ }
842
+ function clearSMAWorker() {
843
+ if (smaWorkerStartRaf) {
844
+ cancelAnimationFrame(smaWorkerStartRaf);
845
+ smaWorkerStartRaf = 0;
846
+ }
847
+ if (smaWorkerPaintRaf) {
848
+ cancelAnimationFrame(smaWorkerPaintRaf);
849
+ smaWorkerPaintRaf = 0;
850
+ }
851
+ if (!smaWorker) return;
852
+ try { smaWorker.terminate(); } catch (e) {}
853
+ smaWorker = null;
854
+ smaWorkerJob = null;
855
+ }
856
+ function requestSMA(period) {
857
+ const safePeriod = Math.max(1, Math.round(period));
858
+ const key = getSmaCacheKey(safePeriod);
859
+ if (smaCache.has(key)) return;
860
+ if (smaWorkerJob && smaWorkerJob.key === key) return;
861
+ if (smaWorkerJob && smaWorkerJob.key !== key) clearSMAWorker();
862
+ if (!smaWorker) smaWorker = createSMAWorker();
863
+ if (!smaWorker) {
864
+ smaCache.set(key, computeSMA(currentSeriesCandles, safePeriod));
865
+ if (currentSmaEnabled && key === getSmaCacheKey(currentSmaPeriod)) rerender(false);
866
+ return;
867
+ }
868
+ smaWorkerJob = { id: ++smaWorkerSeq, key };
869
+ if (smaWorkerStartRaf) cancelAnimationFrame(smaWorkerStartRaf);
870
+ if (smaWorkerPaintRaf) cancelAnimationFrame(smaWorkerPaintRaf);
871
+ smaWorkerStartRaf = requestAnimationFrame(() => {
872
+ smaWorkerStartRaf = 0;
873
+ smaWorkerPaintRaf = requestAnimationFrame(() => {
874
+ smaWorkerPaintRaf = 0;
875
+ if (!smaWorker || !smaWorkerJob || smaWorkerJob.key !== key || !currentSmaEnabled) return;
876
+ smaWorker.postMessage({
877
+ id: smaWorkerJob.id,
878
+ key,
879
+ period: safePeriod,
880
+ closes: currentSeriesCloseValues,
881
+ });
882
+ });
883
+ });
884
+ }
885
+ function currentAmaConfig() {
886
+ return {
887
+ erPeriod: Math.max(1, Math.round(currentAmaErPeriod)),
888
+ fastPeriod: Math.max(0.1, Number(currentAmaFastPeriod) || 0.1),
889
+ slowPeriod: Math.max(0.1, Number(currentAmaSlowPeriod) || 0.1),
890
+ };
891
+ }
892
+ function computeAMA(candles, cfg, initOffset = 0) {
893
+ const params = cfg || currentAmaConfig();
894
+ const erPeriod = Math.max(1, Math.round(params.erPeriod ?? 10));
895
+ const fastPeriod = Math.max(0.1, Number(params.fastPeriod ?? 2));
896
+ const slowPeriod = Math.max(0.1, Number(params.slowPeriod ?? 30));
897
+ const cacheKey = currentPairMode + '|' + erPeriod + '|' + fastPeriod + '|' + slowPeriod + '|' + candles.length + '|' + initOffset;
898
+ if (amaCache.has(cacheKey)) return amaCache.get(cacheKey);
899
+ const fastSC = 2 / (fastPeriod + 1);
900
+ const slowSC = 2 / (slowPeriod + 1);
901
+ const out = [];
902
+ const windowSize = erPeriod + 1;
903
+ const history = new Array(windowSize);
904
+ let head = 0;
905
+ let len = 0;
906
+ let volatility = 0;
907
+ let prev = null;
908
+ let smaSum = 0;
909
+ for (const candle of candles) {
910
+ const price = candle.close;
911
+ if (len < windowSize) {
912
+ history[(head + len) % windowSize] = price;
913
+ smaSum += price;
914
+ if (len > 0) {
915
+ volatility += Math.abs(price - history[(head + len - 1) % windowSize]);
916
+ }
917
+ len++;
918
+ if (len < windowSize) {
919
+ out.push(null);
920
+ continue;
921
+ }
922
+ prev = initOffset !== 0 ? (smaSum / windowSize) * (1 + initOffset / 100) : smaSum / windowSize;
923
+ out.push(prev);
924
+ continue;
925
+ }
926
+ const oldest = history[head];
927
+ const second = history[(head + 1) % windowSize];
928
+ const last = history[(head + windowSize - 1) % windowSize];
929
+ volatility += Math.abs(price - last) - Math.abs(second - oldest);
930
+ history[head] = price;
931
+ head = (head + 1) % windowSize;
932
+ const first = history[head];
933
+ const direction = Math.abs(price - first);
934
+ const er = volatility === 0 ? 0 : (direction / volatility);
935
+ const smoothing = Math.pow(er * (fastSC - slowSC) + slowSC, 2);
936
+ const ama = prev + smoothing * (price - prev);
937
+ prev = ama;
938
+ out.push(ama);
939
+ }
940
+ amaCache.set(cacheKey, out);
941
+ return out;
942
+ }
943
+ function computeVWMA(candles, bars) {
944
+ const safeBars = Math.max(1, Math.round(bars || 500));
945
+ const cacheKey = currentPairMode + '|' + safeBars + '|' + candles.length;
946
+ if (vwapCache.has(cacheKey)) return vwapCache.get(cacheKey);
947
+ const out = [];
948
+ let cumPV = 0;
949
+ let cumVol = 0;
950
+ const window = new Array(safeBars);
951
+ let head = 0;
952
+ let count = 0;
953
+ for (const candle of candles) {
954
+ const typical = (candle.high + candle.low + candle.close) / 3;
955
+ const volume = Number.isFinite(candle.volume) ? candle.volume : 0;
956
+ cumPV += typical * volume;
957
+ cumVol += volume;
958
+ if (count < safeBars) {
959
+ window[count] = { typical, volume };
960
+ count++;
961
+ } else {
962
+ const old = window[head];
963
+ cumPV -= old.typical * old.volume;
964
+ cumVol -= old.volume;
965
+ window[head] = { typical, volume };
966
+ head = (head + 1) % safeBars;
967
+ }
968
+ out.push(cumVol > 0 ? (cumPV / cumVol) : null);
969
+ }
970
+ vwapCache.set(cacheKey, out);
971
+ return out;
972
+ }
973
+ function lowerBound(arr, value) {
974
+ let lo = 0;
975
+ let hi = arr.length;
976
+ while (lo < hi) {
977
+ const mid = (lo + hi) >> 1;
978
+ if (arr[mid] < value) lo = mid + 1;
979
+ else hi = mid;
980
+ }
981
+ return lo;
982
+ }
983
+ function visiblePriceRange(u) {
984
+ if (!currentCandles.length) return null;
985
+ const xs = u.data[0];
986
+ const xScale = u.scales.x || {};
987
+ const minX = Number.isFinite(xScale.min) ? xScale.min : xs[0];
988
+ const maxX = Number.isFinite(xScale.max) ? xScale.max : xs[xs.length - 1];
989
+ let start = Math.max(0, lowerBound(xs, minX) - 1);
990
+ let end = Math.min(xs.length, lowerBound(xs, maxX) + 2);
991
+ let min = Infinity;
992
+ let max = -Infinity;
993
+ for (let i = start; i < end; i++) {
994
+ const lo = currentLow[i];
995
+ const hi = currentHigh[i];
996
+ if (Number.isFinite(lo) && lo > 0 && lo < min) min = lo;
997
+ if (Number.isFinite(hi) && hi > max) max = hi;
998
+ const s = currentSma[i];
999
+ const a = currentAma[i];
1000
+ const v = currentVwap[i];
1001
+ if (Number.isFinite(s)) { if (s < min) min = s; if (s > max) max = s; }
1002
+ if (Number.isFinite(a)) { if (a < min) min = a; if (a > max) max = a; }
1003
+ if (Number.isFinite(v)) { if (v < min) min = v; if (v > max) max = v; }
1004
+ }
1005
+ if (!Number.isFinite(min) || !Number.isFinite(max) || min <= 0 || max <= 0) return null;
1006
+ if (min === max) return [min * 0.98, max * 1.02];
1007
+ return [min * 0.97, max * 1.03];
1008
+ }
1009
+ function visibleVolumeRange(u) {
1010
+ if (!currentCandles.length) return null;
1011
+ const xs = u.data[0];
1012
+ const xScale = u.scales.x || {};
1013
+ const minX = Number.isFinite(xScale.min) ? xScale.min : xs[0];
1014
+ const maxX = Number.isFinite(xScale.max) ? xScale.max : xs[xs.length - 1];
1015
+ let start = Math.max(0, lowerBound(xs, minX) - 1);
1016
+ let end = Math.min(xs.length, lowerBound(xs, maxX) + 2);
1017
+ let max = 0;
1018
+ for (let i = start; i < end; i++) {
1019
+ const v = currentCandles[i]?.volume;
1020
+ if (Number.isFinite(v) && v > max) max = v;
1021
+ }
1022
+ if (!Number.isFinite(max) || max <= 0) return [0, 1];
1023
+ return [0, max * 1.15];
1024
+ }
1025
+ function setActiveTimeframe(label) {
1026
+ document.querySelectorAll('.time-btn').forEach((btn) => btn.classList.toggle('active', btn.dataset.timeframe === label));
1027
+ }
1028
+ function setActivePriceScale(label) {
1029
+ const btn = document.getElementById('scale-toggle');
1030
+ if (!btn) return;
1031
+ const next = label === 'linear' ? 'linear' : 'log';
1032
+ btn.dataset.scale = next;
1033
+ btn.classList.toggle('is-linear', next === 'linear');
1034
+ btn.textContent = next === 'linear' ? 'Linear' : 'Log';
1035
+ btn.title = next === 'linear' ? 'Toggle to log scale' : 'Toggle to linear scale';
1036
+ btn.setAttribute('aria-label', next === 'linear' ? 'Toggle to log scale' : 'Toggle to linear scale');
1037
+ }
1038
+ function resetAmaDefaults() {
1039
+ currentAmaErPeriod = Number(payload.amaDefaults?.erPeriod || ${MARKET_ADAPTER.AMAS.AMA3.erPeriod});
1040
+ currentAmaFastPeriod = Number(payload.amaDefaults?.fastPeriod || ${MARKET_ADAPTER.AMAS.AMA3.fastPeriod});
1041
+ currentAmaSlowPeriod = Number(payload.amaDefaults?.slowPeriod || ${MARKET_ADAPTER.AMAS.AMA3.slowPeriod});
1042
+ setControls();
1043
+ rerender(false);
1044
+ }
1045
+ function setIndicatorSeriesVisible(seriesIndex, visible) {
1046
+ if (!priceChart) return;
1047
+ priceChart.setSeries(seriesIndex, { show: visible }, false, false);
1048
+ }
1049
+ function syncIndicatorSeriesVisibility() {
1050
+ if (!priceChart) return;
1051
+ setIndicatorSeriesVisible(5, currentSmaEnabled);
1052
+ setIndicatorSeriesVisible(6, currentAmaEnabled);
1053
+ setIndicatorSeriesVisible(7, currentVwapEnabled);
1054
+ setIndicatorSeriesVisible(8, currentAmaEnabled);
1055
+ setIndicatorSeriesVisible(9, currentAmaEnabled && currentAmaInitOffset !== 0);
1056
+ setIndicatorSeriesVisible(10, currentAmaEnabled && currentAmaInitOffset !== 0);
1057
+ }
1058
+ function hideSmaSeriesImmediate() {
1059
+ clearSMAWorker();
1060
+ currentSma = new Array(currentCandles.length).fill(null);
1061
+ if (Array.isArray(currentPriceData) && currentPriceData.length >= 11) {
1062
+ currentPriceData[5] = currentSma;
1063
+ }
1064
+ setIndicatorSeriesVisible(5, false);
1065
+ refreshLegend();
1066
+ saveState();
1067
+ }
1068
+ function hideAmaSeriesImmediate() {
1069
+ currentAma = new Array(currentCandles.length).fill(null);
1070
+ currentAmaOff = new Array(currentCandles.length).fill(null);
1071
+ currentSmaInit = new Array(currentCandles.length).fill(null);
1072
+ currentSmaInitOff = new Array(currentCandles.length).fill(null);
1073
+ if (Array.isArray(currentPriceData) && currentPriceData.length >= 11) {
1074
+ currentPriceData[6] = currentAma;
1075
+ currentPriceData[8] = currentSmaInit;
1076
+ currentPriceData[9] = currentSmaInitOff;
1077
+ currentPriceData[10] = currentAmaOff;
1078
+ }
1079
+ setIndicatorSeriesVisible(6, false);
1080
+ setIndicatorSeriesVisible(8, false);
1081
+ setIndicatorSeriesVisible(9, false);
1082
+ setIndicatorSeriesVisible(10, false);
1083
+ refreshLegend();
1084
+ saveState();
1085
+ }
1086
+ function hideVwapSeriesImmediate() {
1087
+ currentVwap = new Array(currentCandles.length).fill(null);
1088
+ if (Array.isArray(currentPriceData) && currentPriceData.length >= 11) {
1089
+ currentPriceData[7] = currentVwap;
1090
+ }
1091
+ setIndicatorSeriesVisible(7, false);
1092
+ refreshLegend();
1093
+ saveState();
1094
+ }
1095
+ function updateLegend(idx) {
1096
+ const c = currentCandles[idx];
1097
+ if (!c) return;
1098
+ const smaKey = getSmaCacheKey(currentSmaPeriod);
1099
+ const smaPending = currentSmaEnabled && smaWorkerJob && smaWorkerJob.key === smaKey && !smaCache.has(smaKey);
1100
+ document.getElementById('legend-time').textContent = fmtTime(c.time);
1101
+ document.getElementById('legend-close').textContent = fmtPrice(c.close);
1102
+ const delta = Number.isFinite(c.open) && Number.isFinite(c.close) ? (c.close - c.open) : null;
1103
+ document.getElementById('legend-delta').textContent = Number.isFinite(delta)
1104
+ ? ((delta >= 0 ? '+' : '') + fmtPrice(delta))
1105
+ : '-';
1106
+ document.getElementById('legend-volume').textContent = fmtVolume(c.volume);
1107
+ document.getElementById('legend-scale').textContent = currentPriceScale === 'linear' ? 'Linear' : 'Log';
1108
+ document.getElementById('legend-sma').textContent = Number.isFinite(currentSma[idx]) ? fmtPrice(currentSma[idx]) : (smaPending ? '...' : '-');
1109
+ document.getElementById('legend-ama').textContent = Number.isFinite(currentAma[idx]) ? fmtPrice(currentAma[idx]) : '-';
1110
+ document.getElementById('legend-sma-init').textContent = Number.isFinite(currentSmaInit[idx]) ? fmtPrice(currentSmaInit[idx]) : '-';
1111
+ document.getElementById('legend-off-init').textContent = Number.isFinite(currentSmaInitOff[idx]) ? fmtPrice(currentSmaInitOff[idx]) : '-';
1112
+ document.getElementById('legend-ama-off').textContent = Number.isFinite(currentAmaOff[idx]) ? fmtPrice(currentAmaOff[idx]) : '-';
1113
+ document.getElementById('legend-vwap').textContent = Number.isFinite(currentVwap[idx]) ? fmtPrice(currentVwap[idx]) : '-';
1114
+ }
1115
+ function candlePlugin() {
1116
+ function drawCandles(u) {
1117
+ u.ctx.save();
1118
+
1119
+ const offset = 0.5;
1120
+ u.ctx.translate(offset, offset);
1121
+
1122
+ const [iMin, iMax] = u.series[0].idxs;
1123
+
1124
+ for (let i = iMin; i <= iMax; i++) {
1125
+ const xVal = u.scales.x.distr == 2 ? i : u.data[0][i];
1126
+ const open = u.data[1][i];
1127
+ const high = u.data[2][i];
1128
+ const low = u.data[3][i];
1129
+ const close = u.data[4][i];
1130
+
1131
+ const x = u.valToPos(xVal, 'x', true);
1132
+ const openY = u.valToPos(open, 'y', true);
1133
+ const highY = u.valToPos(high, 'y', true);
1134
+ const lowY = u.valToPos(low, 'y', true);
1135
+ const closeY = u.valToPos(close, 'y', true);
1136
+ if (![x, openY, highY, lowY, closeY].every(Number.isFinite)) continue;
1137
+
1138
+ const nextX = i + 1 <= iMax ? u.valToPos(u.scales.x.distr == 2 ? (i + 1) : u.data[0][i + 1], 'x', true) : null;
1139
+ const prevX = i - 1 >= iMin ? u.valToPos(u.scales.x.distr == 2 ? (i - 1) : u.data[0][i - 1], 'x', true) : null;
1140
+ const spacing = Number.isFinite(nextX) ? (nextX - x) : (Number.isFinite(prevX) ? (x - prevX) : 12);
1141
+ // Wider bodies read better when zoomed in and reduce empty space between candles.
1142
+ const bodyW = Math.max(
1143
+ 4,
1144
+ Math.min(
1145
+ Math.abs(spacing) * 0.86,
1146
+ Math.max(18, Math.abs(spacing) * 0.94),
1147
+ ),
1148
+ );
1149
+ const dir = candleDirection(open, close);
1150
+ const bodyColor = dir === 'up' ? '#26a69a' : (dir === 'down' ? '#ef5350' : '#64748b');
1151
+ const wickColor = dir === 'up' ? '#b3fff3' : (dir === 'down' ? '#ffb3b3' : '#94a3b8');
1152
+ const bodyTop = Math.min(openY, closeY);
1153
+ const bodyBottom = Math.max(openY, closeY);
1154
+ const bodyH = Math.max(dir === 'flat' ? 2 : 3, Math.round(bodyBottom - bodyTop));
1155
+ const bodyX = Math.round(x - bodyW / 2);
1156
+ const bodyY = Math.round(bodyTop);
1157
+
1158
+ const wickW = Math.max(1, Math.min(5, Math.round(Math.abs(spacing) * 0.14)));
1159
+ u.ctx.strokeStyle = wickColor;
1160
+ u.ctx.lineWidth = wickW;
1161
+ u.ctx.beginPath();
1162
+ u.ctx.moveTo(x, highY);
1163
+ u.ctx.lineTo(x, lowY);
1164
+ u.ctx.stroke();
1165
+
1166
+ u.ctx.fillStyle = bodyColor;
1167
+ u.ctx.fillRect(bodyX, bodyY, Math.round(bodyW), bodyH);
1168
+ if (bodyW > 2 && bodyH > 2) {
1169
+ u.ctx.strokeStyle = dir === 'up' ? '#0f7f77' : (dir === 'down' ? '#a92d35' : '#475569');
1170
+ u.ctx.lineWidth = 1;
1171
+ u.ctx.strokeRect(bodyX + 0.5, bodyY + 0.5, Math.round(bodyW) - 1, bodyH - 1);
1172
+ }
1173
+ }
1174
+
1175
+ u.ctx.translate(-offset, -offset);
1176
+ u.ctx.restore();
1177
+ }
1178
+
1179
+ return {
1180
+ opts: (u, opts) => {
1181
+ uPlot.assign(opts, {
1182
+ cursor: { drag: { x: false, y: false, setScale: false }, focus: { prox: 20 } },
1183
+ });
1184
+ opts.series.forEach((s, i) => {
1185
+ if (i > 0 && i <= 4) {
1186
+ s.paths = () => null;
1187
+ s.points = { show: false };
1188
+ s.stroke = 'transparent';
1189
+ }
1190
+ });
1191
+ },
1192
+ hooks: { drawAxes: [drawCandles] },
1193
+ };
1194
+ }
1195
+ function volumePlugin() {
1196
+ function drawVolumeBars(u) {
1197
+ u.ctx.save();
1198
+
1199
+ const offset = 0.5;
1200
+ u.ctx.translate(offset, offset);
1201
+
1202
+ const [iMin, iMax] = u.series[0].idxs;
1203
+ const xVals = u.data[0];
1204
+ const volVals = u.data[1];
1205
+
1206
+ for (let i = iMin; i <= iMax; i++) {
1207
+ const vol = volVals[i];
1208
+ if (!Number.isFinite(vol) || vol <= 0) continue;
1209
+
1210
+ const xVal = u.scales.x.distr == 2 ? i : xVals[i];
1211
+ const x = u.valToPos(xVal, 'x', true);
1212
+ const top = u.valToPos(vol, 'y', true);
1213
+ const bottom = u.valToPos(0, 'y', true);
1214
+ if (![x, top, bottom].every(Number.isFinite)) continue;
1215
+
1216
+ const nextX = i + 1 <= iMax ? u.valToPos(u.scales.x.distr == 2 ? (i + 1) : xVals[i + 1], 'x', true) : null;
1217
+ const prevX = i - 1 >= iMin ? u.valToPos(u.scales.x.distr == 2 ? (i - 1) : xVals[i - 1], 'x', true) : null;
1218
+ const spacing = Number.isFinite(nextX) ? (nextX - x) : (Number.isFinite(prevX) ? (x - prevX) : 12);
1219
+ const barW = Math.max(
1220
+ 4,
1221
+ Math.min(
1222
+ Math.abs(spacing) * 0.86,
1223
+ Math.max(18, Math.abs(spacing) * 0.94),
1224
+ ),
1225
+ );
1226
+
1227
+ const left = Math.round(x - barW / 2);
1228
+ const topY = Math.round(Math.min(top, bottom));
1229
+ const h = Math.max(1, Math.round(Math.abs(bottom - top)));
1230
+
1231
+ u.ctx.fillStyle = '#ffffff';
1232
+ u.ctx.fillRect(left, topY, Math.round(barW), h);
1233
+ }
1234
+
1235
+ u.ctx.translate(-offset, -offset);
1236
+ u.ctx.restore();
1237
+ }
1238
+
1239
+ return {
1240
+ opts: (u, opts) => {
1241
+ uPlot.assign(opts, {
1242
+ cursor: { drag: { x: false, y: false, setScale: false }, focus: { prox: 20 } },
1243
+ });
1244
+ opts.series.forEach((s, i) => {
1245
+ if (i === 1) {
1246
+ s.paths = () => null;
1247
+ s.points = { show: false };
1248
+ s.stroke = 'transparent';
1249
+ s.fill = 'transparent';
1250
+ }
1251
+ });
1252
+ },
1253
+ hooks: { drawAxes: [drawVolumeBars] },
1254
+ };
1255
+ }
1256
+ function buildData() {
1257
+ const tf = timeframeMap.get(currentTimeframe) || timeframeMap.get(defaultTimeframe.label) || timeframes[0];
1258
+ currentSeriesState = getSeriesState(currentPairMode);
1259
+ currentSeriesCandles = currentSeriesState.candles;
1260
+ currentSeriesCloseValues = currentSeriesState.closeValues;
1261
+ const aggregated = aggregateCandles(currentSeriesCandles, tf?.seconds || 3600);
1262
+ currentCandles = aggregated.candles;
1263
+ currentDisplayCandles = deriveDisplayCandles(currentCandles);
1264
+ currentOpen = currentDisplayCandles.map((c) => c.open);
1265
+ currentHigh = currentCandles.map((c) => c.high);
1266
+ currentLow = currentCandles.map((c) => c.low);
1267
+ currentClose = currentDisplayCandles.map((c) => c.close);
1268
+ const baseAma = currentAmaEnabled ? computeAMA(currentSeriesCandles, currentAmaConfig()) : [];
1269
+ const baseAmaOff = currentAmaEnabled && currentAmaInitOffset !== 0
1270
+ ? computeAMA(currentSeriesCandles, currentAmaConfig(), currentAmaInitOffset)
1271
+ : [];
1272
+ const baseVwap = currentVwapEnabled ? computeVWMA(currentSeriesCandles, currentVwapBars) : [];
1273
+ if (currentSmaEnabled) {
1274
+ const smaKey = getSmaCacheKey(currentSmaPeriod);
1275
+ const baseSma = smaCache.get(smaKey);
1276
+ if (baseSma) {
1277
+ currentSma = sampleSeriesByIndex(baseSma, aggregated.idxs);
1278
+ } else {
1279
+ currentSma = new Array(currentCandles.length).fill(null);
1280
+ requestSMA(currentSmaPeriod);
1281
+ }
1282
+ } else {
1283
+ currentSma = new Array(currentCandles.length).fill(null);
1284
+ }
1285
+ currentAma = currentAmaEnabled ? sampleSeriesByIndex(baseAma, aggregated.idxs) : new Array(currentCandles.length).fill(null);
1286
+ currentAmaOff = currentAmaEnabled && currentAmaInitOffset !== 0 ? sampleSeriesByIndex(baseAmaOff, aggregated.idxs) : new Array(currentCandles.length).fill(null);
1287
+ currentVwap = currentVwapEnabled ? sampleSeriesByIndex(baseVwap, aggregated.idxs) : new Array(currentCandles.length).fill(null);
1288
+ const amaCfg = currentAmaConfig();
1289
+ const warmupInit = currentAmaEnabled && baseAma.length > amaCfg.erPeriod ? baseAma[amaCfg.erPeriod] : null;
1290
+ const baseSmaInit = warmupInit !== null
1291
+ ? currentSeriesCandles.map((c, i) => i <= amaCfg.erPeriod ? warmupInit : null)
1292
+ : new Array(currentSeriesCandles.length).fill(null);
1293
+ currentSmaInit = sampleSeriesByIndex(baseSmaInit, aggregated.idxs);
1294
+ const offsetInit = currentAmaEnabled && currentAmaInitOffset !== 0 && baseAmaOff.length > amaCfg.erPeriod
1295
+ ? baseAmaOff[amaCfg.erPeriod]
1296
+ : null;
1297
+ const baseSmaInitOff = offsetInit !== null
1298
+ ? currentSeriesCandles.map((c, i) => i <= amaCfg.erPeriod ? offsetInit : null)
1299
+ : new Array(currentSeriesCandles.length).fill(null);
1300
+ currentSmaInitOff = sampleSeriesByIndex(baseSmaInitOff, aggregated.idxs);
1301
+ currentPriceData = [
1302
+ currentCandles.map((c) => c.time),
1303
+ currentOpen,
1304
+ currentHigh,
1305
+ currentLow,
1306
+ currentClose,
1307
+ currentSma,
1308
+ currentAma,
1309
+ currentVwap,
1310
+ currentSmaInit,
1311
+ currentSmaInitOff,
1312
+ currentAmaOff,
1313
+ ];
1314
+ currentVolumeData = [
1315
+ currentCandles.map((c) => c.time),
1316
+ currentCandles.map((c) => c.volume),
1317
+ ];
1318
+ return {
1319
+ priceData: currentPriceData,
1320
+ volumeData: currentVolumeData,
1321
+ };
1322
+ }
1323
+ function makeChart() {
1324
+ const data = buildData();
1325
+ const isLogScale = currentPriceScale !== 'linear';
1326
+
1327
+ const priceOpts = {
1328
+ width: priceEl.clientWidth,
1329
+ height: priceEl.clientHeight,
1330
+ padding: [14, 8, 8, 8],
1331
+ legend: { show: false },
1332
+ select: { show: false },
1333
+ cursor: { sync: { key: STORAGE_KEY, setSeries: false, scales: ['x', null] }, drag: { x: false, y: false, setScale: false }, focus: { prox: 20 } },
1334
+ scales: {
1335
+ x: { time: true },
1336
+ y: {
1337
+ auto: true,
1338
+ distr: isLogScale ? 3 : 1,
1339
+ log: isLogScale ? 10 : undefined,
1340
+ range: (u, min, max) => {
1341
+ const vis = visiblePriceRange(u);
1342
+ if (vis) return vis;
1343
+ if (isLogScale) {
1344
+ if (!Number.isFinite(min) || !Number.isFinite(max) || min <= 0 || max <= 0) return [1, 10];
1345
+ } else if (!Number.isFinite(min) || !Number.isFinite(max)) {
1346
+ return [0, 1];
1347
+ }
1348
+ return [min * 0.97, max * 1.03];
1349
+ },
1350
+ },
1351
+ },
1352
+ series: [
1353
+ { label: 'Time' },
1354
+ { label: 'Open' },
1355
+ { label: 'High' },
1356
+ { label: 'Low' },
1357
+ { label: 'Close' },
1358
+ { label: 'SMA', stroke: '#ffffff', width: 2, points: { show: false }, spanGaps: true },
1359
+ { label: 'AMA', stroke: '#facc15', width: 2, points: { show: false }, spanGaps: true },
1360
+ { label: 'VWMA', stroke: '#93c5fd', width: 2, points: { show: false }, spanGaps: true },
1361
+ { label: 'AMA Init', stroke: '#22c55e', width: 1.5, dash: [6, 4], points: { show: false }, spanGaps: false },
1362
+ { label: 'Off Init', stroke: '#a855f7', width: 1.5, dash: [6, 4], points: { show: false }, spanGaps: false },
1363
+ { label: 'AMA Off', stroke: '#a855f7', width: 1.5, dash: [4, 4], points: { show: false }, spanGaps: false },
1364
+ ],
1365
+ axes: [
1366
+ makeTimeAxis(false),
1367
+ { scale: 'y', size: 62, stroke: '#545d68', grid: { stroke: '#1c2128' }, ticks: { stroke: '#30363d', width: 1 }, values: (u, vals) => vals.map((v) => (v == null ? '' : fmtPrice(v))) },
1368
+ ],
1369
+ };
1370
+
1371
+ const plugin = candlePlugin();
1372
+ plugin.opts(null, priceOpts);
1373
+ priceOpts.plugins = [plugin];
1374
+ if (!priceChart) priceChart = new uPlot(priceOpts, data.priceData, priceEl);
1375
+ else priceChart.setData(data.priceData, false);
1376
+
1377
+ const volumeOpts = {
1378
+ width: volumeEl.clientWidth,
1379
+ height: volumeEl.clientHeight,
1380
+ padding: [6, 8, 8, 8],
1381
+ legend: { show: false },
1382
+ select: { show: false },
1383
+ cursor: { sync: { key: STORAGE_KEY, setSeries: false, scales: ['x', null] }, drag: { x: false, y: false, setScale: false }, focus: { prox: 20 } },
1384
+ scales: {
1385
+ x: { time: true },
1386
+ y: {
1387
+ auto: true,
1388
+ range: (u, min, max) => {
1389
+ const vis = visibleVolumeRange(u);
1390
+ if (vis) return vis;
1391
+ if (!Number.isFinite(min) || !Number.isFinite(max) || max <= 0) return [0, 1];
1392
+ return [0, max * 1.15];
1393
+ },
1394
+ },
1395
+ },
1396
+ series: [
1397
+ { label: 'Time' },
1398
+ { label: 'Volume', stroke: '#ffffff', fill: '#ffffff', width: 1, points: { show: false } },
1399
+ ],
1400
+ axes: [
1401
+ makeTimeAxis(true),
1402
+ { scale: 'y', size: 62, stroke: '#545d68', grid: { stroke: '#1c2128' }, ticks: { stroke: '#30363d', width: 1 }, values: (u, vals) => vals.map((v) => (v == null ? '' : fmtVolume(v))) },
1403
+ ],
1404
+ };
1405
+
1406
+ const volumePluginInst = volumePlugin();
1407
+ volumePluginInst.opts(null, volumeOpts);
1408
+ volumeOpts.plugins = [volumePluginInst];
1409
+ if (!volumeChart) volumeChart = new uPlot(volumeOpts, data.volumeData, volumeEl);
1410
+ else volumeChart.setData(data.volumeData, false);
1411
+
1412
+ charts = [priceChart, volumeChart];
1413
+ lastRenderedPriceScale = currentPriceScale;
1414
+ return priceChart;
1415
+ }
1416
+ function clampRange(min, max) {
1417
+ if (!currentCandles.length || !Number.isFinite(min) || !Number.isFinite(max) || max <= min) return null;
1418
+ const first = currentCandles[0].time;
1419
+ const last = currentCandles[currentCandles.length - 1].time;
1420
+ let lo = min;
1421
+ let hi = max;
1422
+ if (lo < first) { hi += first - lo; lo = first; }
1423
+ if (hi > last) { lo -= hi - last; hi = last; }
1424
+ if (lo < first) lo = first;
1425
+ if (hi > last) hi = last;
1426
+ if (hi <= lo) return null;
1427
+ return { min: lo, max: hi };
1428
+ }
1429
+ function syncXRange(min, max) {
1430
+ pendingRange = clampRange(min, max);
1431
+ if (pendingRangeRaf) return;
1432
+ pendingRangeRaf = requestAnimationFrame(() => {
1433
+ const next = pendingRange;
1434
+ pendingRange = null;
1435
+ pendingRangeRaf = 0;
1436
+ if (!next || charts.length === 0) return;
1437
+ charts.forEach((chart) => chart.batch(() => chart.setScale('x', next)));
1438
+ });
1439
+ }
1440
+ function bindWheelZoom(chart) {
1441
+ chart.root.addEventListener('wheel', (e) => {
1442
+ if (e.ctrlKey || e.metaKey || e.altKey) return;
1443
+ e.preventDefault();
1444
+ const rect = chart.root.getBoundingClientRect();
1445
+ const center = chart.posToVal(e.clientX - rect.left, 'x');
1446
+ const s = chart.scales.x || {};
1447
+ const currMin = Number.isFinite(s.min) ? s.min : currentCandles[0].time;
1448
+ const currMax = Number.isFinite(s.max) ? s.max : currentCandles[currentCandles.length - 1].time;
1449
+ const span = currMax - currMin;
1450
+ const first = currentCandles[0]?.time;
1451
+ const last = currentCandles[currentCandles.length - 1]?.time;
1452
+ const fullSpan = Number.isFinite(first) && Number.isFinite(last) ? Math.max(1, last - first) : span;
1453
+ if (!Number.isFinite(span) || span <= 0) return;
1454
+ const factor = e.deltaY < 0 ? 0.85 : 1.15;
1455
+ const nextSpan = Math.max(1, Math.min(fullSpan, span * factor));
1456
+ const ratio = (center - currMin) / span;
1457
+ syncXRange(center - nextSpan * ratio, center - nextSpan * ratio + nextSpan);
1458
+ }, { passive: false });
1459
+ }
1460
+ function bindPan(chart) {
1461
+ let dragging = false;
1462
+ let startClientX = 0;
1463
+ let startMin = 0;
1464
+ let startMax = 0;
1465
+ const onMove = (e) => {
1466
+ if (!dragging) return;
1467
+ e.preventDefault();
1468
+ const rect = chart.root.getBoundingClientRect();
1469
+ const delta = chart.posToVal(e.clientX - rect.left, 'x') - chart.posToVal(startClientX - rect.left, 'x');
1470
+ syncXRange(startMin - delta, startMax - delta);
1471
+ };
1472
+ const endDrag = () => {
1473
+ if (!dragging) return;
1474
+ dragging = false;
1475
+ document.body.style.cursor = '';
1476
+ window.removeEventListener('mousemove', onMove);
1477
+ window.removeEventListener('mouseup', endDrag);
1478
+ };
1479
+ chart.root.addEventListener('mousedown', (e) => {
1480
+ if (!e || e.button !== 0 || e.ctrlKey || e.metaKey || e.altKey) return;
1481
+ const rect = chart.root.getBoundingClientRect();
1482
+ if (e.clientX < rect.left || e.clientX > rect.right || e.clientY < rect.top || e.clientY > rect.bottom) return;
1483
+ e.preventDefault();
1484
+ e.stopPropagation();
1485
+ dragging = true;
1486
+ startClientX = e.clientX;
1487
+ const s = chart.scales.x || {};
1488
+ startMin = Number.isFinite(s.min) ? s.min : currentCandles[0].time;
1489
+ startMax = Number.isFinite(s.max) ? s.max : currentCandles[currentCandles.length - 1].time;
1490
+ document.body.style.cursor = 'grabbing';
1491
+ window.addEventListener('mousemove', onMove);
1492
+ window.addEventListener('mouseup', endDrag, { once: true });
1493
+ });
1494
+ }
1495
+ function refreshLegend() {
1496
+ updateLegend(Math.max(0, currentCandles.length - 1));
1497
+ }
1498
+ function setControls() {
1499
+ setActivePairMode(currentPairMode);
1500
+ setActivePriceScale(currentPriceScale);
1501
+ document.getElementById('sma-toggle').checked = currentSmaEnabled;
1502
+ document.getElementById('sma-period').value = String(currentSmaPeriod);
1503
+ document.getElementById('ama-toggle').checked = currentAmaEnabled;
1504
+ document.getElementById('ama-er').value = String(currentAmaErPeriod);
1505
+ document.getElementById('ama-fast').value = currentAmaFastPeriod.toFixed(1);
1506
+ document.getElementById('ama-slow').value = currentAmaSlowPeriod.toFixed(1);
1507
+ document.getElementById('vwap-toggle').checked = currentVwapEnabled;
1508
+ document.getElementById('vwap-bars').value = String(currentVwapBars);
1509
+ document.getElementById('ama-init-offset-toggle').checked = currentAmaInitOffsetEnabled;
1510
+ document.getElementById('ama-init-offset').value = String(currentAmaInitOffset);
1511
+ document.getElementById('ama-init-offset').disabled = !currentAmaInitOffsetEnabled;
1512
+ document.getElementById('ama-init-offset-val').textContent = currentAmaInitOffset + '%';
1513
+ setActiveTimeframe(currentTimeframe);
1514
+ refreshSubtitle();
1515
+ }
1516
+ function rerender(keepRange = true) {
1517
+ const oldRange = keepRange && priceChart ? priceChart.scales.x : null;
1518
+ const needsRebuild = !priceChart || !volumeChart || lastRenderedPriceScale !== currentPriceScale;
1519
+ if (needsRebuild) {
1520
+ if (priceEl) priceEl.innerHTML = '';
1521
+ if (volumeEl) volumeEl.innerHTML = '';
1522
+ priceChart = null;
1523
+ volumeChart = null;
1524
+ charts = [];
1525
+ chartEventsBound = false;
1526
+ }
1527
+ const data = buildData();
1528
+ if (needsRebuild) {
1529
+ makeChart();
1530
+ } else {
1531
+ priceChart.setData(data.priceData, false);
1532
+ volumeChart.setData(data.volumeData, false);
1533
+ }
1534
+ syncIndicatorSeriesVisibility();
1535
+ if (!priceChart || !volumeChart) return;
1536
+ if (!chartEventsBound) {
1537
+ charts.forEach((chart) => {
1538
+ bindWheelZoom(chart);
1539
+ bindPan(chart);
1540
+ chart.over.addEventListener('mousemove', () => {
1541
+ if (chart.cursor.idx != null) updateLegend(chart.cursor.idx);
1542
+ });
1543
+ chart.over.addEventListener('mouseleave', refreshLegend);
1544
+ chart.root.addEventListener('mouseenter', () => chart.root.classList.add('is-hovered'));
1545
+ chart.root.addEventListener('mouseleave', () => chart.root.classList.remove('is-hovered'));
1546
+ });
1547
+ chartEventsBound = true;
1548
+ }
1549
+ if (oldRange && Number.isFinite(oldRange.min) && Number.isFinite(oldRange.max)) {
1550
+ const next = clampRange(oldRange.min, oldRange.max);
1551
+ if (next) charts.forEach((chart) => chart.batch(() => chart.setScale('x', next)));
1552
+ }
1553
+ refreshLegend();
1554
+ saveState();
1555
+ }
1556
+
1557
+ setControls();
1558
+ rerender(false);
1559
+
1560
+ document.querySelectorAll('.time-btn').forEach((btn) => {
1561
+ btn.addEventListener('click', () => {
1562
+ if (btn.disabled) return;
1563
+ const label = btn.dataset.timeframe;
1564
+ if (!label || label === currentTimeframe) return;
1565
+ currentTimeframe = label;
1566
+ setActiveTimeframe(label);
1567
+ rerender(true);
1568
+ });
1569
+ });
1570
+
1571
+ const scaleToggle = document.getElementById('scale-toggle');
1572
+ if (scaleToggle) {
1573
+ scaleToggle.addEventListener('click', () => {
1574
+ currentPriceScale = currentPriceScale === 'linear' ? 'log' : 'linear';
1575
+ setActivePriceScale(currentPriceScale);
1576
+ rerender(false);
1577
+ });
1578
+ }
1579
+ const pairToggle = document.getElementById('pair-toggle');
1580
+ if (pairToggle) {
1581
+ pairToggle.addEventListener('click', () => {
1582
+ currentPairMode = currentPairMode === 'inverse' ? 'normal' : 'inverse';
1583
+ setControls();
1584
+ rerender(true);
1585
+ });
1586
+ }
1587
+
1588
+ const syncInputs = () => {
1589
+ currentSmaEnabled = document.getElementById('sma-toggle').checked;
1590
+ currentSmaPeriod = clamp(Math.round(Number(document.getElementById('sma-period').value) || 20), 1, 9999);
1591
+ currentAmaEnabled = document.getElementById('ama-toggle').checked;
1592
+ currentAmaErPeriod = clamp(Math.round(Number(document.getElementById('ama-er').value) || ${MARKET_ADAPTER.AMAS.AMA3.erPeriod}), 1, 999999);
1593
+ currentAmaFastPeriod = Math.round(clamp(Number(document.getElementById('ama-fast').value) || Number(payload.amaDefaults?.fastPeriod || ${MARKET_ADAPTER.AMAS.AMA3.fastPeriod}), 0.1, 999999) * 10) / 10;
1594
+ currentAmaSlowPeriod = Math.round(clamp(Number(document.getElementById('ama-slow').value) || Number(payload.amaDefaults?.slowPeriod || ${MARKET_ADAPTER.AMAS.AMA3.slowPeriod}), 0.1, 999999) * 10) / 10;
1595
+ currentAmaInitOffsetEnabled = document.getElementById('ama-init-offset-toggle').checked;
1596
+ currentAmaInitOffset = currentAmaInitOffsetEnabled ? snapInitOffset(document.getElementById('ama-init-offset').value) : 0;
1597
+ document.getElementById('ama-init-offset').value = String(currentAmaInitOffset);
1598
+ document.getElementById('ama-init-offset').disabled = !currentAmaInitOffsetEnabled;
1599
+ document.getElementById('ama-init-offset-val').textContent = currentAmaInitOffset + '%';
1600
+ currentVwapEnabled = document.getElementById('vwap-toggle').checked;
1601
+ currentVwapBars = clamp(Math.round(Number(document.getElementById('vwap-bars').value) || 500), 24, 2000);
1602
+ setControls();
1603
+ rerender(false);
1604
+ };
1605
+
1606
+ document.getElementById('sma-toggle').addEventListener('change', () => {
1607
+ const nextEnabled = document.getElementById('sma-toggle').checked;
1608
+ if (currentSmaEnabled === nextEnabled) return;
1609
+ currentSmaEnabled = nextEnabled;
1610
+ setControls();
1611
+ if (!currentSmaEnabled) {
1612
+ hideSmaSeriesImmediate();
1613
+ return;
1614
+ }
1615
+ rerender(false);
1616
+ });
1617
+ document.getElementById('ama-toggle').addEventListener('change', () => {
1618
+ const nextEnabled = document.getElementById('ama-toggle').checked;
1619
+ if (currentAmaEnabled === nextEnabled) return;
1620
+ currentAmaEnabled = nextEnabled;
1621
+ setControls();
1622
+ if (!currentAmaEnabled) {
1623
+ hideAmaSeriesImmediate();
1624
+ return;
1625
+ }
1626
+ rerender(false);
1627
+ });
1628
+ document.getElementById('vwap-toggle').addEventListener('change', () => {
1629
+ const nextEnabled = document.getElementById('vwap-toggle').checked;
1630
+ if (currentVwapEnabled === nextEnabled) return;
1631
+ currentVwapEnabled = nextEnabled;
1632
+ setControls();
1633
+ if (!currentVwapEnabled) {
1634
+ hideVwapSeriesImmediate();
1635
+ return;
1636
+ }
1637
+ rerender(false);
1638
+ });
1639
+ document.getElementById('ama-init-offset-toggle').addEventListener('change', syncInputs);
1640
+ ['sma-period', 'ama-er', 'ama-fast', 'ama-slow', 'vwap-bars'].forEach((id) => {
1641
+ document.getElementById(id).addEventListener('change', syncInputs);
1642
+ document.getElementById(id).addEventListener('blur', syncInputs);
1643
+ });
1644
+ ['ama-er'].forEach((id) => {
1645
+ document.getElementById(id).addEventListener('input', syncInputs);
1646
+ });
1647
+ function makeStepper(id, step, lo, precision) {
1648
+ const dec = document.getElementById(id + '-dec');
1649
+ const inc = document.getElementById(id + '-inc');
1650
+ if (!dec || !inc) return;
1651
+ const input = document.getElementById(id);
1652
+ function stepVal(dir) {
1653
+ const val = parseFloat(input.value) || 0;
1654
+ let next = dir < 0 ? Math.max(lo, val - step) : val + step;
1655
+ if (precision === 0) next = Math.round(next);
1656
+ else if (precision > 0) next = Math.round(next * Math.pow(10, precision)) / Math.pow(10, precision);
1657
+ input.value = precision >= 0 ? next.toFixed(precision) : String(next);
1658
+ syncInputs();
1659
+ }
1660
+ function addHold(el, dir) {
1661
+ let timer = null;
1662
+ function start() {
1663
+ stepVal(dir);
1664
+ timer = setTimeout(() => {
1665
+ timer = setInterval(() => stepVal(dir), 100);
1666
+ }, 300);
1667
+ }
1668
+ function stop() {
1669
+ if (timer) { clearInterval(timer); clearTimeout(timer); timer = null; }
1670
+ }
1671
+ el.addEventListener('mousedown', start);
1672
+ el.addEventListener('mouseup', stop);
1673
+ el.addEventListener('mouseleave', stop);
1674
+ }
1675
+ addHold(dec, -1);
1676
+ addHold(inc, 1);
1677
+ }
1678
+ makeStepper('sma-period', 1, 1, 0);
1679
+ makeStepper('vwap-bars', 1, 24, 0);
1680
+ makeStepper('ama-er', 1, 1, 0);
1681
+ makeStepper('ama-fast', 0.1, 0.1, 1);
1682
+ makeStepper('ama-slow', 1, 0.1, 1);
1683
+ document.getElementById('ama-reset').addEventListener('click', resetAmaDefaults);
1684
+ document.getElementById('ama-init-offset').addEventListener('input', () => {
1685
+ const input = document.getElementById('ama-init-offset');
1686
+ const snapped = snapInitOffset(input.value);
1687
+ if (String(snapped) !== String(input.value)) input.value = String(snapped);
1688
+ document.getElementById('ama-init-offset-val').textContent = snapped + '%';
1689
+ syncInputs();
1690
+ });
1691
+
1692
+ window.addEventListener('resize', () => {
1693
+ if (!charts.length) return;
1694
+ charts.forEach((chart) => {
1695
+ const el = chart === priceChart ? priceEl : volumeEl;
1696
+ chart.setSize({ width: el.clientWidth, height: el.clientHeight });
1697
+ });
1698
+ });
1699
+
1700
+ window.addEventListener('keydown', (e) => {
1701
+ if ((e.ctrlKey || e.metaKey) && e.key === '0' && charts.length) {
1702
+ const first = currentCandles[0]?.time;
1703
+ const last = currentCandles[currentCandles.length - 1]?.time;
1704
+ if (Number.isFinite(first) && Number.isFinite(last)) syncXRange(first, last);
1705
+ }
1706
+ });
1707
+ })();
1708
+ </script>
1709
+ </body>
1710
+ </html>`;
1711
+ }
1712
+ module.exports = {
1713
+ generateHTML,
1714
+ normalizeCandle,
1715
+ loadMarketProfiles,
1716
+ };
1717
+ //# sourceMappingURL=tradingview_uplot_chart_generator.js.map