dexbot 1.4.21 → 1.4.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/README.md +8 -5
- package/analysis/ama_fitting/analyze_ama_price_changes.ts +7 -3
- package/analysis/ama_fitting/analyze_lambda_vs_slow.ts +6 -6
- package/analysis/ama_fitting/calibrate_convergence_er.ts +7 -5
- package/analysis/ama_fitting/fetch_lp_candles.ts +8 -3
- package/analysis/ama_fitting/generate_unified_comparison_chart.ts +30 -67
- package/analysis/ama_fitting/optimizer_high_resolution.ts +26 -17
- package/analysis/ama_fitting/package.json +1 -1
- package/analysis/analyze_derivatives.ts +4 -4
- package/analysis/analyze_dynamic_weight.ts +21 -5
- package/analysis/analyze_kalman.ts +54 -25
- package/analysis/analyze_regime.ts +2 -2
- package/analysis/analyze_regime_windows.ts +27 -19
- package/analysis/analyze_risk_profile.ts +3 -3
- package/analysis/analyze_trade_heatmap.ts +3 -3
- package/analysis/analyze_volatility.ts +2 -2
- package/analysis/bot_fitting/README.md +93 -19
- package/analysis/bot_fitting/backtest_ama_sweep.ts +316 -199
- package/analysis/bot_fitting/backtest_bot_fitting.ts +520 -85
- package/analysis/bot_fitting/shared_utils.ts +15 -9
- package/analysis/bot_key_utils.ts +13 -6
- package/analysis/bot_usage/discover_bot_accounts.ts +5 -3
- package/analysis/bot_usage/kibana_bot_queries.ts +1 -1
- package/analysis/chart_css.ts +6 -4
- package/analysis/chart_ui.ts +0 -1
- package/analysis/chart_utils.ts +11 -2
- package/analysis/derivative_chart_generator.ts +2 -2
- package/analysis/price_sources.ts +8 -2
- package/analysis/resolve_source.ts +1 -1
- package/analysis/trade_profitability.ts +61 -28
- package/analysis/tradingview/README.md +24 -4
- package/analysis/tradingview/analyze_tradingview.ts +1 -1
- package/analysis/tradingview/tradingview_uplot_chart_generator.ts +356 -86
- package/analysis/trend_detection/DYNAMIC_WEIGHT_RESEARCH.md +1 -1
- package/analysis/trend_detection/derivative_analyzer.ts +12 -3
- package/analysis/trend_detection/dynamic_weight_chart_generator.ts +25 -27
- package/analysis/trend_detection/hurst_analyzer.ts +1 -1
- package/analysis/trend_detection/kalman_chart_generator.ts +42 -14
- package/analysis/trend_detection/package.json +1 -1
- package/analysis/trend_detection/regime_chart_generator.ts +39 -19
- package/analysis/trend_detection/tests/test_kalman_trend.ts +1 -1
- package/analysis/trend_detection/tests/test_kalman_velocity_smoothing.ts +1 -1
- package/analysis/trend_detection/volatility_chart_generator.ts +1 -1
- package/claw/index.ts +1 -1
- package/claw/modules/claw_bridge.ts +3 -3
- package/claw/modules/claw_catalog.ts +1 -1
- package/claw/modules/claw_launcher.ts +1 -1
- package/claw/modules/claw_skill_md.ts +7 -10
- package/claw/modules/credit_runtime_adapter.ts +1 -1
- package/claw/modules/decision_loop.ts +5 -9
- package/claw/modules/dexbot_bridge.ts +7 -7
- package/claw/modules/feed_price_source.ts +1 -1
- package/claw/modules/kibana_price_source.ts +1 -1
- package/claw/modules/launcher_mode_detector.ts +1 -1
- package/claw/modules/launcher_paths.ts +1 -1
- package/claw/modules/position_discovery.ts +1 -1
- package/claw/modules/position_health.ts +1 -1
- package/claw/package.json +3 -3
- package/claw/runtimes/openclaw-plugin/openclaw.plugin.json +1 -1
- package/claw/runtimes/openclaw-plugin/package.json +1 -1
- package/claw/skills/launcher-ops/references/launcher-workflow.md +2 -2
- package/claw/tests/package.json +1 -1
- package/claw/tests/test_claw_bridge.ts +45 -21
- package/claw/tests/test_claw_catalog_and_credentials.ts +8 -4
- package/claw/tests/test_claw_chain_layer.ts +39 -19
- package/claw/tests/test_claw_data_flow.ts +28 -20
- package/claw/tests/test_claw_domain_logic.ts +25 -19
- package/claw/tests/test_claw_manifest_and_matrix.ts +23 -3
- package/claw/tests/test_claw_mcp_transport.ts +13 -8
- package/claw/tests/test_claw_regressions.ts +254 -128
- package/claw/tests/test_claw_skill_generation.ts +1 -1
- package/claw/tests/test_nullclaw_tmp_integration.ts +2 -3
- package/claw/tests/test_position_health.ts +1 -77
- package/claw/tests/test_position_manager.ts +20 -18
- package/claw/tests/test_position_manager_watch_health.ts +39 -43
- package/claw/tests/test_short_mpa_strategy.ts +20 -17
- package/claw/tsconfig.json +4 -3
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.js +7 -3
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.js.map +1 -1
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js +6 -6
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js.map +1 -1
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js +7 -5
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +1 -1
- package/dist/analysis/ama_fitting/fetch_lp_candles.js +8 -3
- package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +1 -1
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts +2 -2
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts.map +1 -1
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js +31 -75
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js.map +1 -1
- package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts.map +1 -1
- package/dist/analysis/ama_fitting/optimizer_high_resolution.js +25 -17
- package/dist/analysis/ama_fitting/optimizer_high_resolution.js.map +1 -1
- package/dist/analysis/analyze_derivatives.d.ts +0 -18
- package/dist/analysis/analyze_derivatives.d.ts.map +1 -1
- package/dist/analysis/analyze_derivatives.js +4 -4
- package/dist/analysis/analyze_derivatives.js.map +1 -1
- package/dist/analysis/analyze_dynamic_weight.d.ts +0 -11
- package/dist/analysis/analyze_dynamic_weight.d.ts.map +1 -1
- package/dist/analysis/analyze_dynamic_weight.js +19 -5
- package/dist/analysis/analyze_dynamic_weight.js.map +1 -1
- package/dist/analysis/analyze_kalman.d.ts +0 -10
- package/dist/analysis/analyze_kalman.d.ts.map +1 -1
- package/dist/analysis/analyze_kalman.js +51 -26
- package/dist/analysis/analyze_kalman.js.map +1 -1
- package/dist/analysis/analyze_regime.d.ts +0 -17
- package/dist/analysis/analyze_regime.d.ts.map +1 -1
- package/dist/analysis/analyze_regime.js +2 -2
- package/dist/analysis/analyze_regime.js.map +1 -1
- package/dist/analysis/analyze_regime_windows.d.ts +0 -16
- package/dist/analysis/analyze_regime_windows.d.ts.map +1 -1
- package/dist/analysis/analyze_regime_windows.js +28 -21
- package/dist/analysis/analyze_regime_windows.js.map +1 -1
- package/dist/analysis/analyze_risk_profile.js +3 -3
- package/dist/analysis/analyze_risk_profile.js.map +1 -1
- package/dist/analysis/analyze_trade_heatmap.js +3 -3
- package/dist/analysis/analyze_trade_heatmap.js.map +1 -1
- package/dist/analysis/analyze_volatility.d.ts +0 -19
- package/dist/analysis/analyze_volatility.d.ts.map +1 -1
- package/dist/analysis/analyze_volatility.js +2 -2
- package/dist/analysis/analyze_volatility.js.map +1 -1
- package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts +30 -14
- package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts.map +1 -1
- package/dist/analysis/bot_fitting/backtest_ama_sweep.js +330 -193
- package/dist/analysis/bot_fitting/backtest_ama_sweep.js.map +1 -1
- package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts +136 -1
- package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts.map +1 -1
- package/dist/analysis/bot_fitting/backtest_bot_fitting.js +527 -83
- package/dist/analysis/bot_fitting/backtest_bot_fitting.js.map +1 -1
- package/dist/analysis/bot_fitting/shared_utils.d.ts +1 -1
- package/dist/analysis/bot_fitting/shared_utils.d.ts.map +1 -1
- package/dist/analysis/bot_fitting/shared_utils.js +14 -8
- package/dist/analysis/bot_fitting/shared_utils.js.map +1 -1
- package/dist/analysis/bot_key_utils.d.ts.map +1 -1
- package/dist/analysis/bot_key_utils.js +13 -6
- package/dist/analysis/bot_key_utils.js.map +1 -1
- package/dist/analysis/bot_usage/discover_bot_accounts.js +5 -3
- package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.js +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -1
- package/dist/analysis/chart_css.d.ts +3 -1
- package/dist/analysis/chart_css.d.ts.map +1 -1
- package/dist/analysis/chart_css.js +6 -3
- package/dist/analysis/chart_css.js.map +1 -1
- package/dist/analysis/chart_ui.d.ts.map +1 -1
- package/dist/analysis/chart_ui.js.map +1 -1
- package/dist/analysis/chart_utils.d.ts.map +1 -1
- package/dist/analysis/chart_utils.js +15 -2
- package/dist/analysis/chart_utils.js.map +1 -1
- package/dist/analysis/derivative_chart_generator.js +2 -2
- package/dist/analysis/derivative_chart_generator.js.map +1 -1
- package/dist/analysis/price_sources.d.ts +1 -0
- package/dist/analysis/price_sources.d.ts.map +1 -1
- package/dist/analysis/price_sources.js +8 -2
- package/dist/analysis/price_sources.js.map +1 -1
- package/dist/analysis/resolve_source.d.ts.map +1 -1
- package/dist/analysis/resolve_source.js +1 -1
- package/dist/analysis/resolve_source.js.map +1 -1
- package/dist/analysis/trade_profitability.d.ts.map +1 -1
- package/dist/analysis/trade_profitability.js +58 -29
- package/dist/analysis/trade_profitability.js.map +1 -1
- package/dist/analysis/tradingview/analyze_tradingview.js +1 -1
- package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +356 -86
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -1
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts +1 -0
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +1 -1
- package/dist/analysis/trend_detection/derivative_analyzer.js +12 -3
- package/dist/analysis/trend_detection/derivative_analyzer.js.map +1 -1
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +1 -1
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +26 -27
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +1 -1
- package/dist/analysis/trend_detection/hurst_analyzer.d.ts +1 -1
- package/dist/analysis/trend_detection/hurst_analyzer.d.ts.map +1 -1
- package/dist/analysis/trend_detection/hurst_analyzer.js +1 -1
- package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -1
- package/dist/analysis/trend_detection/kalman_chart_generator.d.ts.map +1 -1
- package/dist/analysis/trend_detection/kalman_chart_generator.js +41 -13
- package/dist/analysis/trend_detection/kalman_chart_generator.js.map +1 -1
- package/dist/analysis/trend_detection/regime_chart_generator.d.ts.map +1 -1
- package/dist/analysis/trend_detection/regime_chart_generator.js +38 -19
- package/dist/analysis/trend_detection/regime_chart_generator.js.map +1 -1
- package/dist/analysis/trend_detection/tests/test_kalman_trend.js +1 -1
- package/dist/analysis/trend_detection/tests/test_kalman_trend.js.map +1 -1
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js +1 -1
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js.map +1 -1
- package/dist/analysis/trend_detection/volatility_chart_generator.js +1 -1
- package/dist/analysis/trend_detection/volatility_chart_generator.js.map +1 -1
- package/dist/bot.js +1 -1
- package/dist/bot.js.map +1 -1
- package/dist/credential-daemon.d.ts +1 -1
- package/dist/credential-daemon.js +1 -1
- package/dist/dexbot.d.ts.map +1 -1
- package/dist/dexbot.js +7 -8
- package/dist/dexbot.js.map +1 -1
- package/dist/market_adapter/ama_signal_runner.js +3 -1
- package/dist/market_adapter/ama_signal_runner.js.map +1 -1
- package/dist/market_adapter/candle_utils.d.ts +1 -3
- package/dist/market_adapter/candle_utils.d.ts.map +1 -1
- package/dist/market_adapter/candle_utils.js +1 -11
- package/dist/market_adapter/candle_utils.js.map +1 -1
- package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -1
- package/dist/market_adapter/core/asymmetric_bounds.js +33 -30
- package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -1
- package/dist/market_adapter/core/config_normalizers.d.ts.map +1 -1
- package/dist/market_adapter/core/config_normalizers.js +10 -1
- package/dist/market_adapter/core/config_normalizers.js.map +1 -1
- package/dist/market_adapter/core/kibana_candles.d.ts +18 -42
- package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -1
- package/dist/market_adapter/core/kibana_candles.js +101 -7
- package/dist/market_adapter/core/kibana_candles.js.map +1 -1
- package/dist/market_adapter/core/kibana_client.d.ts +0 -14
- package/dist/market_adapter/core/kibana_client.d.ts.map +1 -1
- package/dist/market_adapter/core/kibana_client.js +39 -6
- package/dist/market_adapter/core/kibana_client.js.map +1 -1
- package/dist/market_adapter/core/kibana_market_candles.d.ts +0 -27
- package/dist/market_adapter/core/kibana_market_candles.d.ts.map +1 -1
- package/dist/market_adapter/core/kibana_market_candles.js +1 -1
- package/dist/market_adapter/core/kibana_market_candles.js.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.d.ts +21 -11
- package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.js +95 -37
- package/dist/market_adapter/core/market_adapter_service.js.map +1 -1
- package/dist/market_adapter/core/signals/hurst_analyzer.d.ts +10 -1
- package/dist/market_adapter/core/signals/hurst_analyzer.d.ts.map +1 -1
- package/dist/market_adapter/core/signals/hurst_analyzer.js +28 -17
- package/dist/market_adapter/core/signals/hurst_analyzer.js.map +1 -1
- package/dist/market_adapter/core/signals/kalman_trend_analyzer.d.ts +5 -0
- package/dist/market_adapter/core/signals/kalman_trend_analyzer.d.ts.map +1 -1
- package/dist/market_adapter/core/signals/kalman_trend_analyzer.js +24 -24
- package/dist/market_adapter/core/signals/kalman_trend_analyzer.js.map +1 -1
- package/dist/market_adapter/core/signals/kalman_velocity_smoothing.d.ts.map +1 -1
- package/dist/market_adapter/core/signals/kalman_velocity_smoothing.js +5 -1
- package/dist/market_adapter/core/signals/kalman_velocity_smoothing.js.map +1 -1
- package/dist/market_adapter/core/signals/permutation_entropy_analyzer.d.ts.map +1 -1
- package/dist/market_adapter/core/signals/permutation_entropy_analyzer.js +20 -3
- package/dist/market_adapter/core/signals/permutation_entropy_analyzer.js.map +1 -1
- package/dist/market_adapter/core/strategies/ama.js +1 -1
- package/dist/market_adapter/core/strategies/ama.js.map +1 -1
- package/dist/market_adapter/core/strategies/ama_slope_model.d.ts +2 -2
- package/dist/market_adapter/core/strategies/ama_slope_model.d.ts.map +1 -1
- package/dist/market_adapter/core/strategies/ama_slope_model.js +16 -4
- package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -1
- package/dist/market_adapter/core/strategies/atr/calculator.d.ts +4 -3
- package/dist/market_adapter/core/strategies/atr/calculator.d.ts.map +1 -1
- package/dist/market_adapter/core/strategies/atr/calculator.js +16 -8
- package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -1
- package/dist/market_adapter/core/strategies/collateral_manager.d.ts.map +1 -1
- package/dist/market_adapter/core/strategies/collateral_manager.js +8 -3
- package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -1
- package/dist/market_adapter/core/strategies/dynamic_weight_series.d.ts +40 -1
- package/dist/market_adapter/core/strategies/dynamic_weight_series.d.ts.map +1 -1
- package/dist/market_adapter/core/strategies/dynamic_weight_series.js +116 -2
- package/dist/market_adapter/core/strategies/dynamic_weight_series.js.map +1 -1
- package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -1
- package/dist/market_adapter/core/strategies/regime_gate.js +26 -20
- package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -1
- package/dist/market_adapter/core/strategies/volatility_shift.d.ts.map +1 -1
- package/dist/market_adapter/core/strategies/volatility_shift.js +3 -0
- package/dist/market_adapter/core/strategies/volatility_shift.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +69 -55
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts +0 -26
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.js +67 -14
- package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
- package/dist/market_adapter/inputs/kibana_source.d.ts +4 -28
- package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -1
- package/dist/market_adapter/inputs/kibana_source.js +5 -2
- package/dist/market_adapter/inputs/kibana_source.js.map +1 -1
- package/dist/market_adapter/lp_chart_core.js +1 -1
- package/dist/market_adapter/lp_chart_core.js.map +1 -1
- package/dist/market_adapter/lp_chart_runner.d.ts +10 -1
- package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -1
- package/dist/market_adapter/lp_chart_runner.js +2 -2
- package/dist/market_adapter/lp_chart_runner.js.map +1 -1
- package/dist/market_adapter/lp_chart_strategy_loader.js +1 -1
- package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -1
- package/dist/market_adapter/market_adapter.d.ts +1 -2
- package/dist/market_adapter/market_adapter.d.ts.map +1 -1
- package/dist/market_adapter/market_adapter.js +9 -8
- package/dist/market_adapter/market_adapter.js.map +1 -1
- package/dist/market_adapter/test_helpers.d.ts +3 -3
- package/dist/market_adapter/test_helpers.d.ts.map +1 -1
- package/dist/market_adapter/test_helpers.js +3 -3
- package/dist/market_adapter/test_helpers.js.map +1 -1
- package/dist/market_adapter/utils/adapter_client.js +1 -1
- package/dist/market_adapter/utils/adapter_client.js.map +1 -1
- package/dist/market_adapter/utils/atomic_write.js +1 -1
- package/dist/market_adapter/utils/atomic_write.js.map +1 -1
- package/dist/market_adapter/utils/chain.d.ts +0 -2
- package/dist/market_adapter/utils/chain.d.ts.map +1 -1
- package/dist/market_adapter/utils/chain.js +2 -3
- package/dist/market_adapter/utils/chain.js.map +1 -1
- package/dist/market_adapter/utils/data_discovery.d.ts.map +1 -1
- package/dist/market_adapter/utils/data_discovery.js +24 -8
- package/dist/market_adapter/utils/data_discovery.js.map +1 -1
- package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -1
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js +2 -5
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -1
- package/dist/market_adapter/utils/file_lock.d.ts +4 -1
- package/dist/market_adapter/utils/file_lock.d.ts.map +1 -1
- package/dist/market_adapter/utils/file_lock.js +89 -25
- package/dist/market_adapter/utils/file_lock.js.map +1 -1
- package/dist/market_adapter/utils/native_history.d.ts.map +1 -1
- package/dist/market_adapter/utils/native_history.js +5 -1
- package/dist/market_adapter/utils/native_history.js.map +1 -1
- package/dist/modules/account_bots.d.ts.map +1 -1
- package/dist/modules/account_bots.js +47 -12
- package/dist/modules/account_bots.js.map +1 -1
- package/dist/modules/authority_resolver.js +1 -1
- package/dist/modules/authority_resolver.js.map +1 -1
- package/dist/modules/bitshares-native/chain_client.js +1 -1
- package/dist/modules/bitshares-native/chain_client.js.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts +0 -12
- package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc.browser.js +1 -1
- package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc_selector.js +1 -1
- package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -1
- package/dist/modules/bitshares-native/index.d.ts.map +1 -1
- package/dist/modules/bitshares-native/index.js +1 -1
- package/dist/modules/bitshares-native/index.js.map +1 -1
- package/dist/modules/bitshares-native/lru_cache.js +1 -1
- package/dist/modules/bitshares-native/lru_cache.js.map +1 -1
- package/dist/modules/bitshares-native/resolvers.d.ts +0 -2
- package/dist/modules/bitshares-native/resolvers.d.ts.map +1 -1
- package/dist/modules/bitshares-native/resolvers.js +18 -4
- package/dist/modules/bitshares-native/resolvers.js.map +1 -1
- package/dist/modules/bitshares-native/serial/chain_constants.js +1 -1
- package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -1
- package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -1
- package/dist/modules/bitshares-native/serial/index.js +1 -1
- package/dist/modules/bitshares-native/serial/index.js.map +1 -1
- package/dist/modules/bitshares-native/serial/operations.js +1 -1
- package/dist/modules/bitshares-native/serial/operations.js.map +1 -1
- package/dist/modules/bitshares-native/serial/serializer.js +1 -1
- package/dist/modules/bitshares-native/serial/serializer.js.map +1 -1
- package/dist/modules/bitshares-native/serial/types.js +1 -1
- package/dist/modules/bitshares-native/serial/types.js.map +1 -1
- package/dist/modules/bitshares-native/signing_client.js +2 -2
- package/dist/modules/bitshares-native/signing_client.js.map +1 -1
- package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -1
- package/dist/modules/bitshares-native/subscriptions.js +5 -14
- package/dist/modules/bitshares-native/subscriptions.js.map +1 -1
- package/dist/modules/bitshares-native/transport.js +1 -1
- package/dist/modules/bitshares-native/transport.js.map +1 -1
- package/dist/modules/bitshares-native/tx/builder.js +1 -1
- package/dist/modules/bitshares-native/tx/builder.js.map +1 -1
- package/dist/modules/bitshares-native/tx/tx_cache.d.ts +3 -2
- package/dist/modules/bitshares-native/tx/tx_cache.d.ts.map +1 -1
- package/dist/modules/bitshares-native/tx/tx_cache.js +7 -4
- package/dist/modules/bitshares-native/tx/tx_cache.js.map +1 -1
- package/dist/modules/bitshares_client.js +10 -10
- package/dist/modules/bitshares_client.js.map +1 -1
- package/dist/modules/bot_settings.d.ts.map +1 -1
- package/dist/modules/bot_settings.js +11 -18
- package/dist/modules/bot_settings.js.map +1 -1
- package/dist/modules/bots_file_lock.d.ts +1 -1
- package/dist/modules/bots_file_lock.js +1 -1
- package/dist/modules/broadcast_failure.d.ts +13 -0
- package/dist/modules/broadcast_failure.d.ts.map +1 -1
- package/dist/modules/broadcast_failure.js +0 -13
- package/dist/modules/broadcast_failure.js.map +1 -1
- package/dist/modules/chain_orders.d.ts.map +1 -1
- package/dist/modules/chain_orders.js +15 -17
- package/dist/modules/chain_orders.js.map +1 -1
- package/dist/modules/config.js +1 -1
- package/dist/modules/config.js.map +1 -1
- package/dist/modules/constants.d.ts +21 -20
- package/dist/modules/constants.d.ts.map +1 -1
- package/dist/modules/constants.js +60 -63
- package/dist/modules/constants.js.map +1 -1
- package/dist/modules/cr_planner.d.ts +1 -7
- package/dist/modules/cr_planner.d.ts.map +1 -1
- package/dist/modules/cr_planner.js +3 -77
- package/dist/modules/cr_planner.js.map +1 -1
- package/dist/modules/credential_policy.d.ts +0 -4
- package/dist/modules/credential_policy.d.ts.map +1 -1
- package/dist/modules/credential_policy.js +17 -2
- package/dist/modules/credential_policy.js.map +1 -1
- package/dist/modules/credit_runtime.d.ts +0 -7
- package/dist/modules/credit_runtime.d.ts.map +1 -1
- package/dist/modules/credit_runtime.js +21 -60
- package/dist/modules/credit_runtime.js.map +1 -1
- package/dist/modules/crypto/index.d.ts +0 -2
- package/dist/modules/crypto/index.d.ts.map +1 -1
- package/dist/modules/crypto/index.js +0 -2
- package/dist/modules/crypto/index.js.map +1 -1
- package/dist/modules/crypto/sync.js.map +1 -1
- package/dist/modules/daemon_node_health.js +1 -1
- package/dist/modules/daemon_node_health.js.map +1 -1
- package/dist/modules/dexbot_class.d.ts +8 -134
- package/dist/modules/dexbot_class.d.ts.map +1 -1
- package/dist/modules/dexbot_class.js +36 -197
- package/dist/modules/dexbot_class.js.map +1 -1
- package/dist/modules/dexbot_credential_client.js +1 -1
- package/dist/modules/dexbot_credential_client.js.map +1 -1
- package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_fill_runtime.js +3 -6
- package/dist/modules/dexbot_fill_runtime.js.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.d.ts +6 -34
- package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.js +27 -19
- package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
- package/dist/modules/dexbot_startup_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_startup_runtime.js +31 -15
- package/dist/modules/dexbot_startup_runtime.js.map +1 -1
- package/dist/modules/dexbot_state_recovery.d.ts +2 -2
- package/dist/modules/dexbot_state_recovery.d.ts.map +1 -1
- package/dist/modules/dexbot_state_recovery.js +9 -6
- package/dist/modules/dexbot_state_recovery.js.map +1 -1
- package/dist/modules/fund_registry.d.ts.map +1 -1
- package/dist/modules/fund_registry.js +19 -4
- package/dist/modules/fund_registry.js.map +1 -1
- package/dist/modules/general_settings.d.ts +1 -2
- package/dist/modules/general_settings.d.ts.map +1 -1
- package/dist/modules/general_settings.js +1 -2
- package/dist/modules/general_settings.js.map +1 -1
- package/dist/modules/graceful_shutdown.d.ts.map +1 -1
- package/dist/modules/graceful_shutdown.js +10 -1
- package/dist/modules/graceful_shutdown.js.map +1 -1
- package/dist/modules/grid_price_source.d.ts +19 -0
- package/dist/modules/grid_price_source.d.ts.map +1 -0
- package/dist/modules/grid_price_source.js +23 -0
- package/dist/modules/grid_price_source.js.map +1 -0
- package/dist/modules/key_store.d.ts +0 -5
- package/dist/modules/key_store.d.ts.map +1 -1
- package/dist/modules/key_store.js +1 -14
- package/dist/modules/key_store.js.map +1 -1
- package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -1
- package/dist/modules/launcher/bot_supervisor.js +9 -19
- package/dist/modules/launcher/bot_supervisor.js.map +1 -1
- package/dist/modules/launcher/child_env.d.ts +1 -2
- package/dist/modules/launcher/child_env.d.ts.map +1 -1
- package/dist/modules/launcher/child_env.js +1 -1
- package/dist/modules/launcher/child_env.js.map +1 -1
- package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -1
- package/dist/modules/launcher/foreign_cred_daemon.js +2 -14
- package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -1
- package/dist/modules/launcher/market_adapter_runtime.d.ts +1 -1
- package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -1
- package/dist/modules/launcher/market_adapter_runtime.js +3 -14
- package/dist/modules/launcher/market_adapter_runtime.js.map +1 -1
- package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -1
- package/dist/modules/launcher/market_adapter_watchdog.js +3 -2
- package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.d.ts +0 -1
- package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.js +3 -18
- package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
- package/dist/modules/launcher/runtime_entry.d.ts.map +1 -1
- package/dist/modules/launcher/runtime_entry.js +4 -5
- package/dist/modules/launcher/runtime_entry.js.map +1 -1
- package/dist/modules/launcher/status_reporting.js +1 -1
- package/dist/modules/launcher/status_reporting.js.map +1 -1
- package/dist/modules/launcher/supervisor_control.js +1 -1
- package/dist/modules/launcher/supervisor_control.js.map +1 -1
- package/dist/modules/market_adapter_whitelist.d.ts +2 -2
- package/dist/modules/market_adapter_whitelist.d.ts.map +1 -1
- package/dist/modules/market_adapter_whitelist.js +12 -6
- package/dist/modules/market_adapter_whitelist.js.map +1 -1
- package/dist/modules/node_failure_ledger.d.ts +23 -0
- package/dist/modules/node_failure_ledger.d.ts.map +1 -1
- package/dist/modules/node_failure_ledger.js +0 -23
- package/dist/modules/node_failure_ledger.js.map +1 -1
- package/dist/modules/node_manager.d.ts.map +1 -1
- package/dist/modules/node_manager.js +3 -3
- package/dist/modules/node_manager.js.map +1 -1
- package/dist/modules/order/accounting.js +1 -1
- package/dist/modules/order/accounting.js.map +1 -1
- package/dist/modules/order/async_lock.d.ts +6 -0
- package/dist/modules/order/async_lock.d.ts.map +1 -1
- package/dist/modules/order/async_lock.js +11 -0
- package/dist/modules/order/async_lock.js.map +1 -1
- package/dist/modules/order/export.d.ts +1 -1
- package/dist/modules/order/export.js +10 -10
- package/dist/modules/order/export.js.map +1 -1
- package/dist/modules/order/format.d.ts +1 -0
- package/dist/modules/order/format.d.ts.map +1 -1
- package/dist/modules/order/format.js +0 -6
- package/dist/modules/order/format.js.map +1 -1
- package/dist/modules/order/grid.d.ts +2 -12
- package/dist/modules/order/grid.d.ts.map +1 -1
- package/dist/modules/order/grid.js +40 -27
- package/dist/modules/order/grid.js.map +1 -1
- package/dist/modules/order/grid_reconcile.d.ts +1 -1
- package/dist/modules/order/grid_reconcile.js +1 -1
- package/dist/modules/order/grid_reconcile_internal.js +1 -1
- package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
- package/dist/modules/order/logger.d.ts +3 -0
- package/dist/modules/order/logger.d.ts.map +1 -1
- package/dist/modules/order/logger.js +22 -13
- package/dist/modules/order/logger.js.map +1 -1
- package/dist/modules/order/logger_state.d.ts +4 -9
- package/dist/modules/order/logger_state.d.ts.map +1 -1
- package/dist/modules/order/logger_state.js +5 -14
- package/dist/modules/order/logger_state.js.map +1 -1
- package/dist/modules/order/manager.d.ts +1 -4
- package/dist/modules/order/manager.d.ts.map +1 -1
- package/dist/modules/order/manager.js +34 -33
- package/dist/modules/order/manager.js.map +1 -1
- package/dist/modules/order/processed_fill_store.d.ts.map +1 -1
- package/dist/modules/order/processed_fill_store.js +9 -3
- package/dist/modules/order/processed_fill_store.js.map +1 -1
- package/dist/modules/order/strategy.d.ts +6 -4
- package/dist/modules/order/strategy.d.ts.map +1 -1
- package/dist/modules/order/strategy.js +6 -4
- package/dist/modules/order/strategy.js.map +1 -1
- package/dist/modules/order/sync_engine.js +7 -7
- package/dist/modules/order/sync_engine.js.map +1 -1
- package/dist/modules/order/utils/math.d.ts +29 -3
- package/dist/modules/order/utils/math.d.ts.map +1 -1
- package/dist/modules/order/utils/math.js +54 -10
- package/dist/modules/order/utils/math.js.map +1 -1
- package/dist/modules/order/utils/order.d.ts.map +1 -1
- package/dist/modules/order/utils/order.js +14 -2
- package/dist/modules/order/utils/order.js.map +1 -1
- package/dist/modules/order/utils/system.d.ts +3 -8
- package/dist/modules/order/utils/system.d.ts.map +1 -1
- package/dist/modules/order/utils/system.js +14 -4
- package/dist/modules/order/utils/system.js.map +1 -1
- package/dist/modules/order/utils/validate.js +1 -1
- package/dist/modules/order/utils/validate.js.map +1 -1
- package/dist/modules/path_api.js +1 -1
- package/dist/modules/path_api.js.map +1 -1
- package/dist/modules/paths.d.ts +1 -7
- package/dist/modules/paths.d.ts.map +1 -1
- package/dist/modules/paths.js +1 -1
- package/dist/modules/paths.js.map +1 -1
- package/dist/modules/process_discovery.d.ts +3 -0
- package/dist/modules/process_discovery.d.ts.map +1 -1
- package/dist/modules/process_discovery.js +15 -1
- package/dist/modules/process_discovery.js.map +1 -1
- package/dist/modules/runtime_settings.js +1 -1
- package/dist/modules/runtime_settings.js.map +1 -1
- package/dist/modules/settings_merge.d.ts +5 -1
- package/dist/modules/settings_merge.d.ts.map +1 -1
- package/dist/modules/settings_merge.js +14 -3
- package/dist/modules/settings_merge.js.map +1 -1
- package/dist/modules/socket_json_client.d.ts.map +1 -1
- package/dist/modules/socket_json_client.js +12 -2
- package/dist/modules/socket_json_client.js.map +1 -1
- package/dist/modules/storage/browser_adapter.d.ts.map +1 -1
- package/dist/modules/storage/browser_adapter.js +5 -3
- package/dist/modules/storage/browser_adapter.js.map +1 -1
- package/dist/modules/storage/index.d.ts +1 -1
- package/dist/modules/storage/index.js +1 -1
- package/dist/modules/types.d.ts +1 -1
- package/dist/modules/types.d.ts.map +1 -1
- package/dist/modules/validate_profiles.d.ts.map +1 -1
- package/dist/modules/validate_profiles.js +6 -8
- package/dist/modules/validate_profiles.js.map +1 -1
- package/dist/pm2.d.ts.map +1 -1
- package/dist/pm2.js +2 -3
- package/dist/pm2.js.map +1 -1
- package/dist/scripts/analyze-git.d.ts +1 -1
- package/dist/scripts/analyze-git.js +1 -1
- package/dist/scripts/analyze-orders.d.ts.map +1 -1
- package/dist/scripts/analyze-orders.js +61 -18
- package/dist/scripts/analyze-orders.js.map +1 -1
- package/dist/scripts/diagnose-pool-history.js +1 -1
- package/dist/scripts/divergence-calc.d.ts +1 -1
- package/dist/scripts/divergence-calc.js +3 -3
- package/dist/scripts/native_release_gates.js +4 -2
- package/dist/scripts/native_release_gates.js.map +1 -1
- package/dist/scripts/print_grid.d.ts +1 -1
- package/dist/scripts/print_grid.js +1 -1
- package/dist/scripts/run-tests.js +38 -19
- package/dist/scripts/run-tests.js.map +1 -1
- package/dist/scripts/runner.d.ts +3 -5
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +3 -5
- package/dist/scripts/runner.js.map +1 -1
- package/dist/scripts/sync-version.d.ts +2 -2
- package/dist/scripts/sync-version.js +7 -4
- package/dist/scripts/sync-version.js.map +1 -1
- package/dist/scripts/update.d.ts +1 -1
- package/dist/scripts/update.js +1 -1
- package/dist/scripts/validate_bots.d.ts +1 -1
- package/dist/scripts/validate_bots.js +1 -1
- package/dist/scripts/verify-browser-bundle.d.ts +1 -1
- package/dist/scripts/verify-browser-bundle.js +1 -1
- package/dist/unlock.js +4 -4
- package/dist/unlock.js.map +1 -1
- package/docs/BITSHARES_ONBOARDING.md +15 -10
- package/docs/COPY_ON_WRITE_MASTER_PLAN.md +9 -9
- package/docs/DEXBOT_COMPARISON.md +19 -19
- package/docs/EVOLUTION.md +18 -44
- package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +1 -1
- package/docs/GRID_RECALCULATION.md +1 -1
- package/docs/README.md +3 -3
- package/docs/architecture.md +5 -5
- package/docs/developer_guide.md +6 -6
- package/market_adapter/README.md +13 -8
- package/package.json +22 -14
- package/scripts/README.md +33 -7
- package/scripts/clean-dist.js +10 -2
- package/tests/README.md +4 -3
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
|
|
2
3
|
import fs from 'node:fs';
|
|
3
4
|
import { MARKET_ADAPTER } from '../../modules/constants.js';
|
|
4
|
-
import { escapeHtml, serializeJsonForScript } from '../chart_utils.js';
|
|
5
|
+
import { escapeHtml, serializeJsonForScript, UPLOT_SHARED_SCRIPT } from '../chart_utils.js';
|
|
6
|
+
import { cursorCSS, uplotBgCSS } from '../chart_css.js';
|
|
7
|
+
import { zoomResetScript } from '../chart_ui.js';
|
|
5
8
|
import { normalizeCandle } from '../math_utils.js';
|
|
6
9
|
import { PATHS } from '../../modules/paths.js';
|
|
7
10
|
import { getStorage } from '../../modules/storage/index.js';
|
|
8
11
|
const { readJSON } = getStorage();
|
|
9
12
|
import { getErrorMessage } from '../../modules/utils/errors.js';
|
|
10
|
-
'use strict';
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
function inferBaseIntervalSeconds(candles: any[], fallback: any = 3600) {
|
|
@@ -393,10 +395,8 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
393
395
|
.legend-value { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: #eef4fb; font-weight: 700; }
|
|
394
396
|
.status { display: inline-flex; align-items: center; gap: 8px; font-size: 10px; color: #8290a2; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
395
397
|
.pill { border: 1px solid rgba(255,255,255,0.06); border-radius: 999px; padding: 4px 8px; background: rgba(255,255,255,0.03); }
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
.u-cursor-y { border-top: 1px dashed rgba(255,255,255,0.3) !important; display: none; }
|
|
399
|
-
.is-hovered .u-cursor-y { display: block; }
|
|
398
|
+
${uplotBgCSS('#0b0f14')}
|
|
399
|
+
${cursorCSS()}
|
|
400
400
|
@media (max-width: 980px) {
|
|
401
401
|
#topbar { flex-direction: column; align-items: flex-start; }
|
|
402
402
|
#toolbar { justify-content: flex-start; }
|
|
@@ -497,7 +497,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
497
497
|
<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>
|
|
498
498
|
</div>
|
|
499
499
|
</div>
|
|
500
|
-
<div id="price-chart"></div>
|
|
500
|
+
<div id="price-chart" title="Wheel: zoom time (ulos = tyhjaa tilaa datan ymparilla) · Drag: siirra aika- ja hintanakymaa · Wheel/drag hinta-akselilla: zoomaa hintaa · Double-click hinta-akselia: autofit"></div>
|
|
501
501
|
<div id="volume-chart"></div>
|
|
502
502
|
</div>
|
|
503
503
|
</div>
|
|
@@ -556,8 +556,12 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
556
556
|
let lastRenderedPriceScale = null;
|
|
557
557
|
let charts = [];
|
|
558
558
|
let chartEventsBound = false;
|
|
559
|
+
let manualYRange = null;
|
|
560
|
+
let lastCandleKey = null;
|
|
559
561
|
let pendingRange = null;
|
|
560
562
|
let pendingRangeRaf = 0;
|
|
563
|
+
let xMin = 0;
|
|
564
|
+
let xMax = 0;
|
|
561
565
|
let smaWorker = null;
|
|
562
566
|
let smaWorkerJob = null;
|
|
563
567
|
let smaWorkerStartRaf = 0;
|
|
@@ -569,22 +573,122 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
569
573
|
const vwapCache = new Map();
|
|
570
574
|
const seriesCache = new Map();
|
|
571
575
|
|
|
576
|
+
${UPLOT_SHARED_SCRIPT}
|
|
577
|
+
|
|
578
|
+
// TradingView-exporter interaction overrides (PR #3 / #11 feature):
|
|
579
|
+
// redeclare after UPLOT_SHARED_SCRIPT so these hoisted declarations win
|
|
580
|
+
// for this page only, without mutating the shared stack used by other charts.
|
|
581
|
+
function clampXRange(min, max) {
|
|
582
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min) return { min: xMin, max: xMax };
|
|
583
|
+
// Salli tyhjaa tilaa datan molemmin puolin (TradingView-tyyli):
|
|
584
|
+
// enintaan 75 % datan pituudesta reunapuskurina kummallekin puolelle.
|
|
585
|
+
const dataSpan = Math.max(1, xMax - xMin);
|
|
586
|
+
const maxPad = dataSpan * 0.75;
|
|
587
|
+
let lo = Math.max(xMin - maxPad, min);
|
|
588
|
+
let hi = Math.min(xMax + maxPad, max);
|
|
589
|
+
if (lo < xMin && hi <= lo) lo = xMin;
|
|
590
|
+
if (hi > xMax + maxPad) hi = xMax + maxPad;
|
|
591
|
+
if (hi <= lo) return { min: xMin, max: xMax };
|
|
592
|
+
return { min: lo, max: hi };
|
|
593
|
+
}
|
|
594
|
+
function bindWheelZoom(chart) {
|
|
595
|
+
chart.root.addEventListener('wheel', (e) => {
|
|
596
|
+
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
597
|
+
e.preventDefault();
|
|
598
|
+
const rect = chart.root.getBoundingClientRect();
|
|
599
|
+
if (chart === priceChart && inYAxisZone(chart, e.clientX)) {
|
|
600
|
+
const centerY = chart.posToVal(e.clientY - rect.top, 'y');
|
|
601
|
+
zoomYAt(chart, centerY, e.deltaY < 0 ? 0.91 : 1.10);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
e.stopPropagation();
|
|
605
|
+
const left = e.clientX - rect.left - (chart.bbox.left / (chart.pxRatio || 1));
|
|
606
|
+
const center = chart.posToVal(left, 'x');
|
|
607
|
+
const s = chart.scales.x || {};
|
|
608
|
+
const currMin = Number.isFinite(s.min) ? s.min : xMin;
|
|
609
|
+
const currMax = Number.isFinite(s.max) ? s.max : xMax;
|
|
610
|
+
const span = currMax - currMin;
|
|
611
|
+
if (!Number.isFinite(span) || span <= 0) return;
|
|
612
|
+
const factor = e.deltaY < 0 ? 0.85 : 1.15;
|
|
613
|
+
// Uloszoomaus datan reunojen yli: kokonaisnakyyma enintaan 2.5x datan pituus
|
|
614
|
+
const fullSpan = Math.max(1, xMax - xMin);
|
|
615
|
+
const nextSpan = Math.max(1, Math.min(fullSpan * 2.5, span * factor));
|
|
616
|
+
const ratio = (center - currMin) / span;
|
|
617
|
+
syncXRange(center - nextSpan * ratio, center - nextSpan * ratio + nextSpan);
|
|
618
|
+
}, { passive: false });
|
|
619
|
+
}
|
|
572
620
|
function clamp(v, lo, hi) { return Math.max(lo, Math.min(hi, v)); }
|
|
621
|
+
// Significant-digit price formatting (5 "active" digits), matching the
|
|
622
|
+
// DEXBot order-price style (formatCurrency) but with one extra digit.
|
|
623
|
+
// Very small values get SI micro-suffixes (m/µ/n/p/...); large values
|
|
624
|
+
// get comma grouping. Examples: 34.935 -> "34.935", 119.975 -> "119.98",
|
|
625
|
+
// 3014.9 -> "3,014.9", 0.00567 -> "5.67m".
|
|
573
626
|
function fmtPrice(v) {
|
|
574
627
|
if (v == null || !Number.isFinite(v)) return '-';
|
|
575
|
-
const
|
|
576
|
-
if (
|
|
577
|
-
|
|
578
|
-
if (abs
|
|
579
|
-
|
|
628
|
+
const num = Number(v);
|
|
629
|
+
if (num === 0) return '0';
|
|
630
|
+
const abs = Math.abs(num);
|
|
631
|
+
if (abs < 0.1) {
|
|
632
|
+
if (abs >= 0.001) return fmtPrice(num * 1000) + 'm';
|
|
633
|
+
if (abs >= 0.000001) return fmtPrice(num * 1e6) + 'µ';
|
|
634
|
+
if (abs >= 1e-9) return fmtPrice(num * 1e9) + 'n';
|
|
635
|
+
if (abs >= 1e-12) return fmtPrice(num * 1e12) + 'p';
|
|
636
|
+
if (abs >= 1e-15) return fmtPrice(num * 1e15) + 'f';
|
|
637
|
+
if (abs >= 1e-18) return fmtPrice(num * 1e18) + 'a';
|
|
638
|
+
return num.toFixed(6);
|
|
639
|
+
}
|
|
640
|
+
const digits = 4;
|
|
641
|
+
let intDigits = Math.floor(Math.log10(abs)) + 1;
|
|
642
|
+
if (abs < 1) intDigits = 1;
|
|
643
|
+
const formatted = intDigits >= digits ? String(Math.round(num)) : num.toFixed(digits - intDigits);
|
|
644
|
+
return intDigits >= 4 ? formatted.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : formatted;
|
|
645
|
+
}
|
|
646
|
+
function fmtPriceAxis(vals) {
|
|
647
|
+
if (!Array.isArray(vals) || vals.length === 0) return [];
|
|
648
|
+
return vals.map((v) => (v == null || !Number.isFinite(v)) ? '' : fmtPrice(v));
|
|
649
|
+
}
|
|
650
|
+
function fmtPriceLabel(v) {
|
|
651
|
+
if (v == null || !Number.isFinite(v)) return '-';
|
|
652
|
+
return fmtPrice(v);
|
|
653
|
+
}
|
|
654
|
+
function logAxisSplits(self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) {
|
|
655
|
+
if (!Number.isFinite(scaleMin) || !Number.isFinite(scaleMax) || scaleMin <= 0 || scaleMax <= 0) return [];
|
|
656
|
+
let h = 600;
|
|
657
|
+
if (self && self.bbox && Number.isFinite(self.bbox.height)) h = self.bbox.height / (self.pxRatio || 1);
|
|
658
|
+
else if (self && self.over && self.over.clientHeight) h = self.over.clientHeight;
|
|
659
|
+
const target = Math.max(8, Math.min(16, Math.floor(h / 30)));
|
|
660
|
+
const lmin = Math.log10(scaleMin);
|
|
661
|
+
const lmax = Math.log10(scaleMax);
|
|
662
|
+
const out = [];
|
|
663
|
+
for (let i = 0; i <= target; i++) {
|
|
664
|
+
out.push(Math.pow(10, lmin + (lmax - lmin) * (i / target)));
|
|
665
|
+
}
|
|
666
|
+
return out;
|
|
580
667
|
}
|
|
668
|
+
// Significant-digit volume formatting (4 "active" digits) with K/M/B/T
|
|
669
|
+
// suffixes, matching the price-axis style. Examples: 1234567 -> "1235K",
|
|
670
|
+
// 1234567890 -> "1.235B".
|
|
581
671
|
function fmtVolume(v) {
|
|
582
672
|
if (v == null || !Number.isFinite(v)) return '-';
|
|
583
|
-
const
|
|
584
|
-
if (
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
673
|
+
const num = Number(v);
|
|
674
|
+
if (num === 0) return '0';
|
|
675
|
+
const abs = Math.abs(num);
|
|
676
|
+
const units = [[1e12, 'T'], [1e9, 'B'], [1e6, 'M'], [1e3, 'K']];
|
|
677
|
+
for (const [factor, suffix] of units) {
|
|
678
|
+
if (abs >= factor) {
|
|
679
|
+
const scaled = num / factor;
|
|
680
|
+
const a = Math.abs(scaled);
|
|
681
|
+
let intDigits = Math.floor(Math.log10(a)) + 1;
|
|
682
|
+
if (a < 1) intDigits = 1;
|
|
683
|
+
const digits = 4;
|
|
684
|
+
const formatted = intDigits >= digits ? String(Math.round(scaled)) : scaled.toFixed(digits - intDigits);
|
|
685
|
+
return formatted + suffix;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
let intDigits = Math.floor(Math.log10(abs)) + 1;
|
|
689
|
+
if (abs < 1) intDigits = 1;
|
|
690
|
+
const digits = 4;
|
|
691
|
+
return intDigits >= digits ? String(Math.round(num)) : num.toFixed(digits - intDigits);
|
|
588
692
|
}
|
|
589
693
|
function candleDirection(open, close) {
|
|
590
694
|
if (close > open) return 'up';
|
|
@@ -1007,8 +1111,9 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1007
1111
|
if (Number.isFinite(v)) { if (v < min) min = v; if (v > max) max = v; }
|
|
1008
1112
|
}
|
|
1009
1113
|
if (!Number.isFinite(min) || !Number.isFinite(max) || min <= 0 || max <= 0) return null;
|
|
1010
|
-
if (min === max) return [min * 0.
|
|
1011
|
-
|
|
1114
|
+
if (min === max) return [min * 0.96, max * 1.04];
|
|
1115
|
+
// ~7 % hengitystilaa yla- ja alapuolelle (TradingView-tyyli)
|
|
1116
|
+
return [min * 0.93, max * 1.07];
|
|
1012
1117
|
}
|
|
1013
1118
|
function visibleVolumeRange(u) {
|
|
1014
1119
|
if (!currentCandles.length) return null;
|
|
@@ -1264,6 +1369,10 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1264
1369
|
currentSeriesCloseValues = currentSeriesState.closeValues;
|
|
1265
1370
|
const aggregated = aggregateCandles(currentSeriesCandles, tf?.seconds || 3600);
|
|
1266
1371
|
currentCandles = aggregated.candles;
|
|
1372
|
+
if (currentCandles.length) {
|
|
1373
|
+
xMin = currentCandles[0].time;
|
|
1374
|
+
xMax = currentCandles[currentCandles.length - 1].time;
|
|
1375
|
+
}
|
|
1267
1376
|
currentDisplayCandles = deriveDisplayCandles(currentCandles);
|
|
1268
1377
|
currentOpen = currentDisplayCandles.map((c) => c.open);
|
|
1269
1378
|
currentHigh = currentCandles.map((c) => c.high);
|
|
@@ -1342,6 +1451,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1342
1451
|
distr: isLogScale ? 3 : 1,
|
|
1343
1452
|
log: isLogScale ? 10 : undefined,
|
|
1344
1453
|
range: (u, min, max) => {
|
|
1454
|
+
if (manualYRange) return [manualYRange.min, manualYRange.max];
|
|
1345
1455
|
const vis = visiblePriceRange(u);
|
|
1346
1456
|
if (vis) return vis;
|
|
1347
1457
|
if (isLogScale) {
|
|
@@ -1368,8 +1478,24 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1368
1478
|
],
|
|
1369
1479
|
axes: [
|
|
1370
1480
|
makeTimeAxis(false),
|
|
1371
|
-
{
|
|
1481
|
+
{
|
|
1482
|
+
scale: 'y',
|
|
1483
|
+
side: 1,
|
|
1484
|
+
size: 84,
|
|
1485
|
+
space: isLogScale ? 1 : 45,
|
|
1486
|
+
stroke: '#ffffff',
|
|
1487
|
+
grid: { stroke: '#272f3a' },
|
|
1488
|
+
ticks: { stroke: '#414b57', width: 1 },
|
|
1489
|
+
font: '600 13px Segoe UI, sans-serif',
|
|
1490
|
+
splits: isLogScale ? logAxisSplits : undefined,
|
|
1491
|
+
values: (u, vals) => isLogScale
|
|
1492
|
+
? vals.map((v) => (Number.isFinite(v) ? fmtPrice(v) : ''))
|
|
1493
|
+
: fmtPriceAxis(vals),
|
|
1494
|
+
},
|
|
1372
1495
|
],
|
|
1496
|
+
hooks: {
|
|
1497
|
+
draw: [(u) => positionPriceMarker(u)],
|
|
1498
|
+
},
|
|
1373
1499
|
};
|
|
1374
1500
|
|
|
1375
1501
|
const plugin = candlePlugin();
|
|
@@ -1403,7 +1529,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1403
1529
|
],
|
|
1404
1530
|
axes: [
|
|
1405
1531
|
makeTimeAxis(true),
|
|
1406
|
-
{ scale: 'y', size:
|
|
1532
|
+
{ scale: 'y', side: 1, size: 84, space: 22, stroke: '#ffffff', grid: { stroke: '#1c2128' }, ticks: { stroke: '#30363d', width: 1 }, font: '600 12px Segoe UI, sans-serif', values: (u, vals) => vals.map((v) => (v == null ? '' : fmtVolume(v))) },
|
|
1407
1533
|
],
|
|
1408
1534
|
};
|
|
1409
1535
|
|
|
@@ -1417,83 +1543,212 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1417
1543
|
lastRenderedPriceScale = currentPriceScale;
|
|
1418
1544
|
return priceChart;
|
|
1419
1545
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
if (
|
|
1428
|
-
|
|
1429
|
-
if (
|
|
1430
|
-
|
|
1431
|
-
|
|
1546
|
+
// True when clientX sits over the price-axis region. The chart canvas
|
|
1547
|
+
// (plot + axis gutters) can be wider than the viewport and the right
|
|
1548
|
+
// gutter clipped off-screen, so we key the price zone off the ON-SCREEN
|
|
1549
|
+
// chart container width (always reachable) rather than the far-right gutter.
|
|
1550
|
+
// The rightmost ~120px of the container zooms price; the rest pans time.
|
|
1551
|
+
function inYAxisZone(chart, clientX) {
|
|
1552
|
+
const rootRect = chart.root.getBoundingClientRect();
|
|
1553
|
+
if (!rootRect || rootRect.width <= 0) return false;
|
|
1554
|
+
const x = clientX - rootRect.left;
|
|
1555
|
+
if (chart === priceChart) {
|
|
1556
|
+
return x > rootRect.width - 120;
|
|
1557
|
+
}
|
|
1558
|
+
return false;
|
|
1432
1559
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1560
|
+
let priceMarkerLabel = null;
|
|
1561
|
+
let priceMarkerLine = null;
|
|
1562
|
+
function ensurePriceMarker(u) {
|
|
1563
|
+
if (priceMarkerLabel && priceMarkerLabel.parentNode === u.root) return;
|
|
1564
|
+
if (priceMarkerLabel && priceMarkerLabel.parentNode) priceMarkerLabel.parentNode.removeChild(priceMarkerLabel);
|
|
1565
|
+
if (priceMarkerLine && priceMarkerLine.parentNode) priceMarkerLine.parentNode.removeChild(priceMarkerLine);
|
|
1566
|
+
try { if (getComputedStyle(u.root).position === 'static') u.root.style.position = 'relative'; } catch (e) {}
|
|
1567
|
+
priceMarkerLabel = document.createElement('div');
|
|
1568
|
+
priceMarkerLabel.style.cssText = 'position:absolute;z-index:30;pointer-events:none;font:600 12px Segoe UI, sans-serif;line-height:19px;height:19px;padding:0 7px;border-radius:3px;color:#ffffff;white-space:nowrap;box-sizing:border-box;text-align:center;overflow:hidden;';
|
|
1569
|
+
priceMarkerLine = document.createElement('div');
|
|
1570
|
+
priceMarkerLine.style.cssText = 'position:absolute;z-index:1;pointer-events:none;height:0;border-top:1px dashed currentColor;opacity:0.6;';
|
|
1571
|
+
u.root.appendChild(priceMarkerLine);
|
|
1572
|
+
u.root.appendChild(priceMarkerLabel);
|
|
1573
|
+
}
|
|
1574
|
+
function positionPriceMarker(u) {
|
|
1575
|
+
if (!u || !u.over || !currentCandles.length) return;
|
|
1576
|
+
ensurePriceMarker(u);
|
|
1577
|
+
const last = currentCandles[currentCandles.length - 1];
|
|
1578
|
+
const prev = currentCandles.length > 1 ? currentCandles[currentCandles.length - 2] : last;
|
|
1579
|
+
const price = last.close;
|
|
1580
|
+
if (!Number.isFinite(price)) {
|
|
1581
|
+
priceMarkerLabel.style.display = 'none';
|
|
1582
|
+
priceMarkerLine.style.display = 'none';
|
|
1583
|
+
return;
|
|
1584
|
+
}
|
|
1585
|
+
const up = price >= (Number.isFinite(prev.close) ? prev.close : price);
|
|
1586
|
+
const color = up ? '#26a69a' : '#ef5350';
|
|
1587
|
+
const s = u.scales.y || {};
|
|
1588
|
+
const sMin = Number.isFinite(s.min) ? s.min : null;
|
|
1589
|
+
const sMax = Number.isFinite(s.max) ? s.max : null;
|
|
1590
|
+
if (sMin == null || sMax == null || sMax <= sMin) {
|
|
1591
|
+
priceMarkerLabel.style.display = 'none';
|
|
1592
|
+
priceMarkerLine.style.display = 'none';
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1595
|
+
let frac;
|
|
1596
|
+
if (currentPriceScale === 'log') {
|
|
1597
|
+
const lmin = Math.log10(sMin);
|
|
1598
|
+
const lmax = Math.log10(sMax);
|
|
1599
|
+
const lp = Math.log10(Math.max(price, 1e-12));
|
|
1600
|
+
frac = (lp - lmin) / (lmax - lmin);
|
|
1601
|
+
} else {
|
|
1602
|
+
frac = (price - sMin) / (sMax - sMin);
|
|
1603
|
+
}
|
|
1604
|
+
const rootRect = u.root.getBoundingClientRect();
|
|
1605
|
+
const overRect = u.over.getBoundingClientRect();
|
|
1606
|
+
if (!overRect || overRect.height <= 0) return;
|
|
1607
|
+
const plotTop = overRect.top - rootRect.top;
|
|
1608
|
+
const yRel = (1 - frac) * overRect.height;
|
|
1609
|
+
const inRange = frac >= 0 && frac <= 1;
|
|
1610
|
+
priceMarkerLabel.style.display = 'block';
|
|
1611
|
+
priceMarkerLabel.textContent = fmtPriceLabel(price);
|
|
1612
|
+
priceMarkerLabel.style.background = color;
|
|
1613
|
+
priceMarkerLabel.style.top = (plotTop + Math.max(0, Math.min(overRect.height, yRel)) - 10) + 'px';
|
|
1614
|
+
const leftAxisW = overRect.left - rootRect.left;
|
|
1615
|
+
const rightAxisW = rootRect.right - overRect.right;
|
|
1616
|
+
if (leftAxisW >= rightAxisW) {
|
|
1617
|
+
priceMarkerLabel.style.left = '0px';
|
|
1618
|
+
priceMarkerLabel.style.right = '';
|
|
1619
|
+
priceMarkerLabel.style.width = Math.max(40, leftAxisW - 4) + 'px';
|
|
1620
|
+
} else {
|
|
1621
|
+
priceMarkerLabel.style.left = '';
|
|
1622
|
+
priceMarkerLabel.style.right = '0px';
|
|
1623
|
+
priceMarkerLabel.style.width = Math.max(40, rightAxisW - 4) + 'px';
|
|
1624
|
+
}
|
|
1625
|
+
if (inRange) {
|
|
1626
|
+
priceMarkerLine.style.display = 'block';
|
|
1627
|
+
priceMarkerLine.style.color = color;
|
|
1628
|
+
priceMarkerLine.style.top = (plotTop + yRel) + 'px';
|
|
1629
|
+
priceMarkerLine.style.left = (overRect.left - rootRect.left) + 'px';
|
|
1630
|
+
priceMarkerLine.style.width = overRect.width + 'px';
|
|
1631
|
+
} else {
|
|
1632
|
+
priceMarkerLine.style.display = 'none';
|
|
1633
|
+
}
|
|
1443
1634
|
}
|
|
1444
|
-
function
|
|
1445
|
-
chart.
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
const
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
const first = currentCandles[0]?.time;
|
|
1455
|
-
const last = currentCandles[currentCandles.length - 1]?.time;
|
|
1456
|
-
const fullSpan = Number.isFinite(first) && Number.isFinite(last) ? Math.max(1, last - first) : span;
|
|
1457
|
-
if (!Number.isFinite(span) || span <= 0) return;
|
|
1458
|
-
const factor = e.deltaY < 0 ? 0.85 : 1.15;
|
|
1459
|
-
const nextSpan = Math.max(1, Math.min(fullSpan, span * factor));
|
|
1460
|
-
const ratio = (center - currMin) / span;
|
|
1461
|
-
syncXRange(center - nextSpan * ratio, center - nextSpan * ratio + nextSpan);
|
|
1462
|
-
}, { passive: false });
|
|
1635
|
+
function currentYRange(chart) {
|
|
1636
|
+
const s = chart.scales.y || {};
|
|
1637
|
+
let min = Number.isFinite(s.min) ? s.min : null;
|
|
1638
|
+
let max = Number.isFinite(s.max) ? s.max : null;
|
|
1639
|
+
if (min == null || max == null) {
|
|
1640
|
+
const vis = visiblePriceRange(chart);
|
|
1641
|
+
if (vis) { min = vis[0]; max = vis[1]; }
|
|
1642
|
+
}
|
|
1643
|
+
if (min == null || max == null || !Number.isFinite(min) || !Number.isFinite(max) || max <= min) return null;
|
|
1644
|
+
return { min: min, max: max };
|
|
1463
1645
|
}
|
|
1464
|
-
|
|
1646
|
+
let priceBounds = null;
|
|
1647
|
+
function computePriceBounds() {
|
|
1648
|
+
let min = Infinity;
|
|
1649
|
+
let max = -Infinity;
|
|
1650
|
+
for (let i = 0; i < currentCandles.length; i++) {
|
|
1651
|
+
const lo = currentLow[i];
|
|
1652
|
+
const hi = currentHigh[i];
|
|
1653
|
+
if (Number.isFinite(lo) && lo > 0 && lo < min) min = lo;
|
|
1654
|
+
if (Number.isFinite(hi) && hi > max) max = hi;
|
|
1655
|
+
}
|
|
1656
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || min <= 0 || max <= min) {
|
|
1657
|
+
priceBounds = null;
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
const range = max - min;
|
|
1661
|
+
// Uloszoomauksen rajat: alin naytettava hinta voi painua viimeistaan
|
|
1662
|
+
// ~35 % datan minimin alapuolelle, ylin ~1.6x datan maksimin, ja
|
|
1663
|
+
// kokonaisvali saa olla enintaan ~1.6x datan hintahaarukasta —
|
|
1664
|
+
// ei siis paase "lipsahtamaan" candleita nakyvasta kadottaen.
|
|
1665
|
+
priceBounds = { min: min, max: max, floor: min * 0.35, ceil: max * 1.6, maxSpan: range * 1.6 };
|
|
1666
|
+
}
|
|
1667
|
+
function applyYRange(chart, min, max) {
|
|
1668
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min) return false;
|
|
1669
|
+
const ref = Math.max(Math.abs(min), Math.abs(max), 1e-12);
|
|
1670
|
+
if (max - min < ref * 1e-9) return false;
|
|
1671
|
+
if (currentPriceScale === 'log' && min <= 0) {
|
|
1672
|
+
min = max > 0 ? max * 1e-6 : 1e-6;
|
|
1673
|
+
if (max <= min) return false;
|
|
1674
|
+
}
|
|
1675
|
+
if (priceBounds) {
|
|
1676
|
+
let nMin = Math.max(min, priceBounds.floor);
|
|
1677
|
+
let nMax = Math.min(max, priceBounds.ceil);
|
|
1678
|
+
if (nMax - nMin > priceBounds.maxSpan) {
|
|
1679
|
+
const c = (nMin + nMax) / 2;
|
|
1680
|
+
nMin = c - priceBounds.maxSpan / 2;
|
|
1681
|
+
nMax = c + priceBounds.maxSpan / 2;
|
|
1682
|
+
nMin = Math.max(nMin, priceBounds.floor);
|
|
1683
|
+
nMax = Math.min(nMax, priceBounds.ceil);
|
|
1684
|
+
}
|
|
1685
|
+
if (nMax <= nMin) return false;
|
|
1686
|
+
min = nMin;
|
|
1687
|
+
max = nMax;
|
|
1688
|
+
}
|
|
1689
|
+
manualYRange = { min: min, max: max };
|
|
1690
|
+
chart.setScale('y', { min: min, max: max });
|
|
1691
|
+
return true;
|
|
1692
|
+
}
|
|
1693
|
+
function zoomYAt(chart, centerY, factor) {
|
|
1694
|
+
const r = currentYRange(chart);
|
|
1695
|
+
if (!r) return;
|
|
1696
|
+
const span = r.max - r.min;
|
|
1697
|
+
let ratio = (centerY - r.min) / span;
|
|
1698
|
+
if (!Number.isFinite(ratio)) ratio = 0.5;
|
|
1699
|
+
ratio = Math.max(0.05, Math.min(0.95, ratio));
|
|
1700
|
+
const nextSpan = span * factor;
|
|
1701
|
+
const nextMin = centerY - nextSpan * ratio;
|
|
1702
|
+
applyYRange(chart, nextMin, nextMin + nextSpan);
|
|
1703
|
+
}
|
|
1704
|
+
function bindYAxisDrag(chart) {
|
|
1465
1705
|
let dragging = false;
|
|
1466
|
-
let
|
|
1467
|
-
let
|
|
1468
|
-
let startMax = 0;
|
|
1706
|
+
let startClientY = 0;
|
|
1707
|
+
let startRange = null;
|
|
1469
1708
|
const onMove = (e) => {
|
|
1470
|
-
if (!dragging) return;
|
|
1709
|
+
if (!dragging || !startRange) return;
|
|
1471
1710
|
e.preventDefault();
|
|
1472
|
-
|
|
1473
|
-
const
|
|
1474
|
-
|
|
1711
|
+
chart.root.style.cursor = 'ns-resize';
|
|
1712
|
+
const deltaPx = e.clientY - startClientY;
|
|
1713
|
+
if (!Number.isFinite(deltaPx) || deltaPx === 0) return;
|
|
1714
|
+
const factor = Math.exp(deltaPx / 350);
|
|
1715
|
+
const span = startRange.max - startRange.min;
|
|
1716
|
+
const center = (startRange.min + startRange.max) / 2;
|
|
1717
|
+
const nextSpan = span * factor;
|
|
1718
|
+
applyYRange(chart, center - nextSpan / 2, center + nextSpan / 2);
|
|
1475
1719
|
};
|
|
1476
1720
|
const endDrag = () => {
|
|
1477
1721
|
if (!dragging) return;
|
|
1478
1722
|
dragging = false;
|
|
1479
|
-
|
|
1723
|
+
startRange = null;
|
|
1724
|
+
chart.root.style.cursor = '';
|
|
1480
1725
|
window.removeEventListener('mousemove', onMove);
|
|
1481
1726
|
window.removeEventListener('mouseup', endDrag);
|
|
1482
1727
|
};
|
|
1483
1728
|
chart.root.addEventListener('mousedown', (e) => {
|
|
1484
1729
|
if (!e || e.button !== 0 || e.ctrlKey || e.metaKey || e.altKey) return;
|
|
1730
|
+
// capture phase so we pre-empt uPlot's own plot drag when in the y-zone
|
|
1485
1731
|
const rect = chart.root.getBoundingClientRect();
|
|
1486
1732
|
if (e.clientX < rect.left || e.clientX > rect.right || e.clientY < rect.top || e.clientY > rect.bottom) return;
|
|
1733
|
+
if (chart !== priceChart || !inYAxisZone(chart, e.clientX)) return;
|
|
1734
|
+
const range = currentYRange(chart);
|
|
1735
|
+
if (!range) return;
|
|
1487
1736
|
e.preventDefault();
|
|
1488
1737
|
e.stopPropagation();
|
|
1489
1738
|
dragging = true;
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
startMax = Number.isFinite(s.max) ? s.max : currentCandles[currentCandles.length - 1].time;
|
|
1494
|
-
document.body.style.cursor = 'grabbing';
|
|
1739
|
+
startClientY = e.clientY;
|
|
1740
|
+
startRange = range;
|
|
1741
|
+
chart.root.style.cursor = 'ns-resize';
|
|
1495
1742
|
window.addEventListener('mousemove', onMove);
|
|
1496
1743
|
window.addEventListener('mouseup', endDrag, { once: true });
|
|
1744
|
+
}, true);
|
|
1745
|
+
}
|
|
1746
|
+
function bindYAxisReset(chart) {
|
|
1747
|
+
chart.root.addEventListener('dblclick', (e) => {
|
|
1748
|
+
if (chart !== priceChart) return;
|
|
1749
|
+
manualYRange = null;
|
|
1750
|
+
const vis = visiblePriceRange(chart);
|
|
1751
|
+
if (vis) chart.setScale('y', { min: vis[0], max: vis[1] });
|
|
1497
1752
|
});
|
|
1498
1753
|
}
|
|
1499
1754
|
function refreshLegend() {
|
|
@@ -1521,6 +1776,9 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1521
1776
|
const oldRange = keepRange && priceChart ? priceChart.scales.x : null;
|
|
1522
1777
|
const needsRebuild = !priceChart || !volumeChart || lastRenderedPriceScale !== currentPriceScale;
|
|
1523
1778
|
if (needsRebuild) {
|
|
1779
|
+
manualYRange = null;
|
|
1780
|
+
priceMarkerLabel = null;
|
|
1781
|
+
priceMarkerLine = null;
|
|
1524
1782
|
if (priceEl) priceEl.innerHTML = '';
|
|
1525
1783
|
if (volumeEl) volumeEl.innerHTML = '';
|
|
1526
1784
|
priceChart = null;
|
|
@@ -1529,6 +1787,16 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1529
1787
|
chartEventsBound = false;
|
|
1530
1788
|
}
|
|
1531
1789
|
const data = buildData();
|
|
1790
|
+
// Dataset changed (timeframe switch, fresh candles): drop any manual
|
|
1791
|
+
// price scale so auto-fit takes over again for the new data shape.
|
|
1792
|
+
const candleKey = currentCandles.length
|
|
1793
|
+
? currentCandles[0].time + ':' + currentCandles[currentCandles.length - 1].time + ':' + currentCandles.length
|
|
1794
|
+
: '';
|
|
1795
|
+
if (candleKey !== lastCandleKey) {
|
|
1796
|
+
lastCandleKey = candleKey;
|
|
1797
|
+
manualYRange = null;
|
|
1798
|
+
}
|
|
1799
|
+
computePriceBounds();
|
|
1532
1800
|
if (needsRebuild) {
|
|
1533
1801
|
makeChart();
|
|
1534
1802
|
} else {
|
|
@@ -1541,17 +1809,24 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1541
1809
|
charts.forEach((chart) => {
|
|
1542
1810
|
bindWheelZoom(chart);
|
|
1543
1811
|
bindPan(chart);
|
|
1544
|
-
chart
|
|
1812
|
+
if (chart === priceChart) {
|
|
1813
|
+
bindYAxisDrag(chart);
|
|
1814
|
+
bindYAxisReset(chart);
|
|
1815
|
+
chart.root.addEventListener('mousemove', (e) => {
|
|
1816
|
+
chart.root.style.cursor = inYAxisZone(chart, e.clientX) ? 'ns-resize' : '';
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1819
|
+
chart.root.addEventListener('mousemove', () => {
|
|
1545
1820
|
if (chart.cursor.idx != null) updateLegend(chart.cursor.idx);
|
|
1546
1821
|
});
|
|
1547
|
-
chart.
|
|
1822
|
+
chart.root.addEventListener('mouseleave', refreshLegend);
|
|
1548
1823
|
chart.root.addEventListener('mouseenter', () => chart.root.classList.add('is-hovered'));
|
|
1549
1824
|
chart.root.addEventListener('mouseleave', () => chart.root.classList.remove('is-hovered'));
|
|
1550
1825
|
});
|
|
1551
1826
|
chartEventsBound = true;
|
|
1552
1827
|
}
|
|
1553
1828
|
if (oldRange && Number.isFinite(oldRange.min) && Number.isFinite(oldRange.max)) {
|
|
1554
|
-
const next =
|
|
1829
|
+
const next = clampXRange(oldRange.min, oldRange.max);
|
|
1555
1830
|
if (next) charts.forEach((chart) => chart.batch(() => chart.setScale('x', next)));
|
|
1556
1831
|
}
|
|
1557
1832
|
refreshLegend();
|
|
@@ -1584,6 +1859,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1584
1859
|
if (pairToggle) {
|
|
1585
1860
|
pairToggle.addEventListener('click', () => {
|
|
1586
1861
|
currentPairMode = currentPairMode === 'inverse' ? 'normal' : 'inverse';
|
|
1862
|
+
manualYRange = null;
|
|
1587
1863
|
setControls();
|
|
1588
1864
|
rerender(true);
|
|
1589
1865
|
});
|
|
@@ -1701,13 +1977,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1701
1977
|
});
|
|
1702
1978
|
});
|
|
1703
1979
|
|
|
1704
|
-
|
|
1705
|
-
if ((e.ctrlKey || e.metaKey) && e.key === '0' && charts.length) {
|
|
1706
|
-
const first = currentCandles[0]?.time;
|
|
1707
|
-
const last = currentCandles[currentCandles.length - 1]?.time;
|
|
1708
|
-
if (Number.isFinite(first) && Number.isFinite(last)) syncXRange(first, last);
|
|
1709
|
-
}
|
|
1710
|
-
});
|
|
1980
|
+
${zoomResetScript()}
|
|
1711
1981
|
})();
|
|
1712
1982
|
</script>
|
|
1713
1983
|
</body>
|
|
@@ -159,7 +159,7 @@ All panels share aligned vertical time grid lines, and the bottom output panel s
|
|
|
159
159
|
|------|-------|---------|---------|
|
|
160
160
|
| **nz%** | 0–1 | 0.00 | Neutral zone: dead-band below which offset is forced to 0 |
|
|
161
161
|
| **lb** | 1–32 | 9 | Logarithmic. Lookback bars for AMA slope calculation |
|
|
162
|
-
| **amaS%** | 0.
|
|
162
|
+
| **amaS%** | 0.06–0.12 | 0.09 | Logarithmic. Gear ratio for average per-bar AMA slope saturation |
|
|
163
163
|
| **kalS%** | 0.5–1.5 | 1.0 | Logarithmic. Gear ratio for Kalman composite saturation |
|
|
164
164
|
| **clip%** | 0–55 | 10 | Percentile clip: filters extreme inputs (0 = off) |
|
|
165
165
|
|