dexbot 1.4.21 → 1.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +1 -1
- package/analysis/ama_fitting/analyze_ama_price_changes.ts +7 -3
- package/analysis/ama_fitting/analyze_lambda_vs_slow.ts +3 -3
- 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 +22 -13
- 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/results/ama_sweep_results_lp_pool_133_1h.json +2455 -0
- package/analysis/results/bot_fitting_results_lp_pool_133_1h.json +218 -0
- package/analysis/trade_profitability.ts +61 -28
- package/analysis/tradingview/analyze_tradingview.ts +1 -1
- package/analysis/tradingview/h-bts_tradingview.html +1570 -0
- package/analysis/tradingview/t-bts_tradingview.html +1570 -0
- package/analysis/tradingview/tradingview_uplot_chart_generator.ts +302 -74
- 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 +3 -3
- 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 +21 -13
- 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 +302 -74
- 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 +3 -6
- 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.js +1 -1
- 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 +53 -56
- 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 +23 -24
- 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/order.d.ts.map +1 -1
- package/dist/modules/order/utils/order.js +1 -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 +35 -16
- 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 +2 -2
- 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/COPY_ON_WRITE_MASTER_PLAN.md +9 -9
- package/docs/DEXBOT_COMPARISON.md +4 -4
- package/docs/EVOLUTION.md +16 -43
- package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +1 -1
- package/docs/README.md +1 -1
- package/docs/architecture.md +5 -5
- package/docs/developer_guide.md +6 -6
- 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,6 +573,50 @@ 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)); }
|
|
573
621
|
function fmtPrice(v) {
|
|
574
622
|
if (v == null || !Number.isFinite(v)) return '-';
|
|
@@ -578,6 +626,27 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
578
626
|
if (abs >= 1) return v.toFixed(4);
|
|
579
627
|
return v.toPrecision(6);
|
|
580
628
|
}
|
|
629
|
+
function fmtPriceAxis(vals) {
|
|
630
|
+
if (!Array.isArray(vals) || vals.length === 0) return [];
|
|
631
|
+
let step = Infinity;
|
|
632
|
+
for (let i = 1; i < vals.length; i++) {
|
|
633
|
+
const d = Math.abs(Number(vals[i]) - Number(vals[i - 1]));
|
|
634
|
+
if (Number.isFinite(d) && d > 0 && d < step) step = d;
|
|
635
|
+
}
|
|
636
|
+
let decimals = 4;
|
|
637
|
+
if (Number.isFinite(step) && step > 0) decimals = Math.ceil(-Math.log10(step));
|
|
638
|
+
decimals = Math.max(0, Math.min(10, decimals));
|
|
639
|
+
return vals.map((v) => (v == null || !Number.isFinite(v)) ? '' : Number(v).toFixed(decimals));
|
|
640
|
+
}
|
|
641
|
+
function fmtPriceLabel(v) {
|
|
642
|
+
if (v == null || !Number.isFinite(v)) return '-';
|
|
643
|
+
const abs = Math.abs(v);
|
|
644
|
+
if (abs >= 1000) return v.toFixed(2);
|
|
645
|
+
if (abs >= 1) return v.toFixed(4);
|
|
646
|
+
let s = v.toPrecision(6);
|
|
647
|
+
if (s.indexOf('e') >= 0) s = v.toFixed(10).replace(/0+$/, '').replace(/\.$/, '');
|
|
648
|
+
return s;
|
|
649
|
+
}
|
|
581
650
|
function fmtVolume(v) {
|
|
582
651
|
if (v == null || !Number.isFinite(v)) return '-';
|
|
583
652
|
const abs = Math.abs(v);
|
|
@@ -1007,8 +1076,9 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1007
1076
|
if (Number.isFinite(v)) { if (v < min) min = v; if (v > max) max = v; }
|
|
1008
1077
|
}
|
|
1009
1078
|
if (!Number.isFinite(min) || !Number.isFinite(max) || min <= 0 || max <= 0) return null;
|
|
1010
|
-
if (min === max) return [min * 0.
|
|
1011
|
-
|
|
1079
|
+
if (min === max) return [min * 0.96, max * 1.04];
|
|
1080
|
+
// ~7 % hengitystilaa yla- ja alapuolelle (TradingView-tyyli)
|
|
1081
|
+
return [min * 0.93, max * 1.07];
|
|
1012
1082
|
}
|
|
1013
1083
|
function visibleVolumeRange(u) {
|
|
1014
1084
|
if (!currentCandles.length) return null;
|
|
@@ -1264,6 +1334,10 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1264
1334
|
currentSeriesCloseValues = currentSeriesState.closeValues;
|
|
1265
1335
|
const aggregated = aggregateCandles(currentSeriesCandles, tf?.seconds || 3600);
|
|
1266
1336
|
currentCandles = aggregated.candles;
|
|
1337
|
+
if (currentCandles.length) {
|
|
1338
|
+
xMin = currentCandles[0].time;
|
|
1339
|
+
xMax = currentCandles[currentCandles.length - 1].time;
|
|
1340
|
+
}
|
|
1267
1341
|
currentDisplayCandles = deriveDisplayCandles(currentCandles);
|
|
1268
1342
|
currentOpen = currentDisplayCandles.map((c) => c.open);
|
|
1269
1343
|
currentHigh = currentCandles.map((c) => c.high);
|
|
@@ -1342,6 +1416,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1342
1416
|
distr: isLogScale ? 3 : 1,
|
|
1343
1417
|
log: isLogScale ? 10 : undefined,
|
|
1344
1418
|
range: (u, min, max) => {
|
|
1419
|
+
if (manualYRange) return [manualYRange.min, manualYRange.max];
|
|
1345
1420
|
const vis = visiblePriceRange(u);
|
|
1346
1421
|
if (vis) return vis;
|
|
1347
1422
|
if (isLogScale) {
|
|
@@ -1368,8 +1443,21 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1368
1443
|
],
|
|
1369
1444
|
axes: [
|
|
1370
1445
|
makeTimeAxis(false),
|
|
1371
|
-
{
|
|
1446
|
+
{
|
|
1447
|
+
scale: 'y',
|
|
1448
|
+
side: 1,
|
|
1449
|
+
size: 84,
|
|
1450
|
+
space: 26,
|
|
1451
|
+
stroke: '#ffffff',
|
|
1452
|
+
grid: { stroke: '#272f3a' },
|
|
1453
|
+
ticks: { stroke: '#414b57', width: 1 },
|
|
1454
|
+
font: '600 13px Segoe UI, sans-serif',
|
|
1455
|
+
values: (u, vals) => fmtPriceAxis(vals),
|
|
1456
|
+
},
|
|
1372
1457
|
],
|
|
1458
|
+
hooks: {
|
|
1459
|
+
draw: [(u) => positionPriceMarker(u)],
|
|
1460
|
+
},
|
|
1373
1461
|
};
|
|
1374
1462
|
|
|
1375
1463
|
const plugin = candlePlugin();
|
|
@@ -1403,7 +1491,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1403
1491
|
],
|
|
1404
1492
|
axes: [
|
|
1405
1493
|
makeTimeAxis(true),
|
|
1406
|
-
{ scale: 'y', size:
|
|
1494
|
+
{ 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
1495
|
],
|
|
1408
1496
|
};
|
|
1409
1497
|
|
|
@@ -1417,65 +1505,181 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1417
1505
|
lastRenderedPriceScale = currentPriceScale;
|
|
1418
1506
|
return priceChart;
|
|
1419
1507
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
if (
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
if (
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1508
|
+
// True when clientX sits over the price-axis gutter (outside the plot
|
|
1509
|
+
// proper). uPlot's .u-over spans the full canvas incl. axis gutters,
|
|
1510
|
+
// so hit-testing must use chart.bbox (plot area) rather than the
|
|
1511
|
+
// overlay rect. Tolerance pulls the boundary slightly into the plot.
|
|
1512
|
+
function inYAxisZone(chart, clientX) {
|
|
1513
|
+
const rootRect = chart.root.getBoundingClientRect();
|
|
1514
|
+
if (!rootRect || rootRect.width <= 0 || !chart.bbox) return false;
|
|
1515
|
+
const pr = chart.pxRatio || 1;
|
|
1516
|
+
const plotLeft = chart.bbox.left / pr;
|
|
1517
|
+
const plotRight = chart.bbox.right / pr;
|
|
1518
|
+
return clientX - rootRect.left < plotLeft - 6 || clientX - rootRect.left > plotRight + 6;
|
|
1519
|
+
}
|
|
1520
|
+
let priceMarkerLabel = null;
|
|
1521
|
+
let priceMarkerLine = null;
|
|
1522
|
+
function ensurePriceMarker(u) {
|
|
1523
|
+
if (priceMarkerLabel && priceMarkerLabel.parentNode === u.root) return;
|
|
1524
|
+
if (priceMarkerLabel && priceMarkerLabel.parentNode) priceMarkerLabel.parentNode.removeChild(priceMarkerLabel);
|
|
1525
|
+
if (priceMarkerLine && priceMarkerLine.parentNode) priceMarkerLine.parentNode.removeChild(priceMarkerLine);
|
|
1526
|
+
try { if (getComputedStyle(u.root).position === 'static') u.root.style.position = 'relative'; } catch (e) {}
|
|
1527
|
+
priceMarkerLabel = document.createElement('div');
|
|
1528
|
+
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;';
|
|
1529
|
+
priceMarkerLine = document.createElement('div');
|
|
1530
|
+
priceMarkerLine.style.cssText = 'position:absolute;z-index:1;pointer-events:none;height:0;border-top:1px dashed currentColor;opacity:0.6;';
|
|
1531
|
+
u.root.appendChild(priceMarkerLine);
|
|
1532
|
+
u.root.appendChild(priceMarkerLabel);
|
|
1533
|
+
}
|
|
1534
|
+
function positionPriceMarker(u) {
|
|
1535
|
+
if (!u || !u.over || !currentCandles.length) return;
|
|
1536
|
+
ensurePriceMarker(u);
|
|
1537
|
+
const last = currentCandles[currentCandles.length - 1];
|
|
1538
|
+
const prev = currentCandles.length > 1 ? currentCandles[currentCandles.length - 2] : last;
|
|
1539
|
+
const price = last.close;
|
|
1540
|
+
if (!Number.isFinite(price)) {
|
|
1541
|
+
priceMarkerLabel.style.display = 'none';
|
|
1542
|
+
priceMarkerLine.style.display = 'none';
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
const up = price >= (Number.isFinite(prev.close) ? prev.close : price);
|
|
1546
|
+
const color = up ? '#26a69a' : '#ef5350';
|
|
1547
|
+
const s = u.scales.y || {};
|
|
1548
|
+
const sMin = Number.isFinite(s.min) ? s.min : null;
|
|
1549
|
+
const sMax = Number.isFinite(s.max) ? s.max : null;
|
|
1550
|
+
if (sMin == null || sMax == null || sMax <= sMin) {
|
|
1551
|
+
priceMarkerLabel.style.display = 'none';
|
|
1552
|
+
priceMarkerLine.style.display = 'none';
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
let frac;
|
|
1556
|
+
if (currentPriceScale === 'log') {
|
|
1557
|
+
const lmin = Math.log10(sMin);
|
|
1558
|
+
const lmax = Math.log10(sMax);
|
|
1559
|
+
const lp = Math.log10(Math.max(price, 1e-12));
|
|
1560
|
+
frac = (lp - lmin) / (lmax - lmin);
|
|
1561
|
+
} else {
|
|
1562
|
+
frac = (price - sMin) / (sMax - sMin);
|
|
1563
|
+
}
|
|
1564
|
+
const rootRect = u.root.getBoundingClientRect();
|
|
1565
|
+
const overRect = u.over.getBoundingClientRect();
|
|
1566
|
+
if (!overRect || overRect.height <= 0) return;
|
|
1567
|
+
const plotTop = overRect.top - rootRect.top;
|
|
1568
|
+
const yRel = (1 - frac) * overRect.height;
|
|
1569
|
+
const inRange = frac >= 0 && frac <= 1;
|
|
1570
|
+
priceMarkerLabel.style.display = 'block';
|
|
1571
|
+
priceMarkerLabel.textContent = fmtPriceLabel(price);
|
|
1572
|
+
priceMarkerLabel.style.background = color;
|
|
1573
|
+
priceMarkerLabel.style.top = (plotTop + Math.max(0, Math.min(overRect.height, yRel)) - 10) + 'px';
|
|
1574
|
+
const leftAxisW = overRect.left - rootRect.left;
|
|
1575
|
+
const rightAxisW = rootRect.right - overRect.right;
|
|
1576
|
+
if (leftAxisW >= rightAxisW) {
|
|
1577
|
+
priceMarkerLabel.style.left = '0px';
|
|
1578
|
+
priceMarkerLabel.style.right = '';
|
|
1579
|
+
priceMarkerLabel.style.width = Math.max(40, leftAxisW - 4) + 'px';
|
|
1580
|
+
} else {
|
|
1581
|
+
priceMarkerLabel.style.left = '';
|
|
1582
|
+
priceMarkerLabel.style.right = '0px';
|
|
1583
|
+
priceMarkerLabel.style.width = Math.max(40, rightAxisW - 4) + 'px';
|
|
1584
|
+
}
|
|
1585
|
+
if (inRange) {
|
|
1586
|
+
priceMarkerLine.style.display = 'block';
|
|
1587
|
+
priceMarkerLine.style.color = color;
|
|
1588
|
+
priceMarkerLine.style.top = (plotTop + yRel) + 'px';
|
|
1589
|
+
priceMarkerLine.style.left = (overRect.left - rootRect.left) + 'px';
|
|
1590
|
+
priceMarkerLine.style.width = overRect.width + 'px';
|
|
1591
|
+
} else {
|
|
1592
|
+
priceMarkerLine.style.display = 'none';
|
|
1593
|
+
}
|
|
1443
1594
|
}
|
|
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 });
|
|
1595
|
+
function currentYRange(chart) {
|
|
1596
|
+
const s = chart.scales.y || {};
|
|
1597
|
+
let min = Number.isFinite(s.min) ? s.min : null;
|
|
1598
|
+
let max = Number.isFinite(s.max) ? s.max : null;
|
|
1599
|
+
if (min == null || max == null) {
|
|
1600
|
+
const vis = visiblePriceRange(chart);
|
|
1601
|
+
if (vis) { min = vis[0]; max = vis[1]; }
|
|
1602
|
+
}
|
|
1603
|
+
if (min == null || max == null || !Number.isFinite(min) || !Number.isFinite(max) || max <= min) return null;
|
|
1604
|
+
return { min: min, max: max };
|
|
1463
1605
|
}
|
|
1464
|
-
|
|
1606
|
+
let priceBounds = null;
|
|
1607
|
+
function computePriceBounds() {
|
|
1608
|
+
let min = Infinity;
|
|
1609
|
+
let max = -Infinity;
|
|
1610
|
+
for (let i = 0; i < currentCandles.length; i++) {
|
|
1611
|
+
const lo = currentLow[i];
|
|
1612
|
+
const hi = currentHigh[i];
|
|
1613
|
+
if (Number.isFinite(lo) && lo > 0 && lo < min) min = lo;
|
|
1614
|
+
if (Number.isFinite(hi) && hi > max) max = hi;
|
|
1615
|
+
}
|
|
1616
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || min <= 0 || max <= min) {
|
|
1617
|
+
priceBounds = null;
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
const range = max - min;
|
|
1621
|
+
// Uloszoomauksen rajat: alin naytettava hinta voi painua viimeistaan
|
|
1622
|
+
// ~35 % datan minimin alapuolelle, ylin ~1.6x datan maksimin, ja
|
|
1623
|
+
// kokonaisvali saa olla enintaan ~1.6x datan hintahaarukasta —
|
|
1624
|
+
// ei siis paase "lipsahtamaan" candleita nakyvasta kadottaen.
|
|
1625
|
+
priceBounds = { min: min, max: max, floor: min * 0.35, ceil: max * 1.6, maxSpan: range * 1.6 };
|
|
1626
|
+
}
|
|
1627
|
+
function applyYRange(chart, min, max) {
|
|
1628
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min) return false;
|
|
1629
|
+
const ref = Math.max(Math.abs(min), Math.abs(max), 1e-12);
|
|
1630
|
+
if (max - min < ref * 1e-9) return false;
|
|
1631
|
+
if (currentPriceScale === 'log' && min <= 0) {
|
|
1632
|
+
min = max > 0 ? max * 1e-6 : 1e-6;
|
|
1633
|
+
if (max <= min) return false;
|
|
1634
|
+
}
|
|
1635
|
+
if (priceBounds) {
|
|
1636
|
+
let nMin = Math.max(min, priceBounds.floor);
|
|
1637
|
+
let nMax = Math.min(max, priceBounds.ceil);
|
|
1638
|
+
if (nMax - nMin > priceBounds.maxSpan) {
|
|
1639
|
+
const c = (nMin + nMax) / 2;
|
|
1640
|
+
nMin = c - priceBounds.maxSpan / 2;
|
|
1641
|
+
nMax = c + priceBounds.maxSpan / 2;
|
|
1642
|
+
nMin = Math.max(nMin, priceBounds.floor);
|
|
1643
|
+
nMax = Math.min(nMax, priceBounds.ceil);
|
|
1644
|
+
}
|
|
1645
|
+
if (nMax <= nMin) return false;
|
|
1646
|
+
min = nMin;
|
|
1647
|
+
max = nMax;
|
|
1648
|
+
}
|
|
1649
|
+
manualYRange = { min: min, max: max };
|
|
1650
|
+
chart.setScale('y', { min: min, max: max });
|
|
1651
|
+
return true;
|
|
1652
|
+
}
|
|
1653
|
+
function zoomYAt(chart, centerY, factor) {
|
|
1654
|
+
const r = currentYRange(chart);
|
|
1655
|
+
if (!r) return;
|
|
1656
|
+
const span = r.max - r.min;
|
|
1657
|
+
let ratio = (centerY - r.min) / span;
|
|
1658
|
+
if (!Number.isFinite(ratio)) ratio = 0.5;
|
|
1659
|
+
ratio = Math.max(0.05, Math.min(0.95, ratio));
|
|
1660
|
+
const nextSpan = span * factor;
|
|
1661
|
+
const nextMin = centerY - nextSpan * ratio;
|
|
1662
|
+
applyYRange(chart, nextMin, nextMin + nextSpan);
|
|
1663
|
+
}
|
|
1664
|
+
function bindYAxisDrag(chart) {
|
|
1465
1665
|
let dragging = false;
|
|
1466
|
-
let
|
|
1467
|
-
let
|
|
1468
|
-
let startMax = 0;
|
|
1666
|
+
let startClientY = 0;
|
|
1667
|
+
let startRange = null;
|
|
1469
1668
|
const onMove = (e) => {
|
|
1470
|
-
if (!dragging) return;
|
|
1669
|
+
if (!dragging || !startRange) return;
|
|
1471
1670
|
e.preventDefault();
|
|
1472
|
-
const
|
|
1473
|
-
|
|
1474
|
-
|
|
1671
|
+
const deltaPx = e.clientY - startClientY;
|
|
1672
|
+
if (!Number.isFinite(deltaPx) || deltaPx === 0) return;
|
|
1673
|
+
const factor = Math.exp(deltaPx / 350);
|
|
1674
|
+
const span = startRange.max - startRange.min;
|
|
1675
|
+
const center = (startRange.min + startRange.max) / 2;
|
|
1676
|
+
const nextSpan = span * factor;
|
|
1677
|
+
applyYRange(chart, center - nextSpan / 2, center + nextSpan / 2);
|
|
1475
1678
|
};
|
|
1476
1679
|
const endDrag = () => {
|
|
1477
1680
|
if (!dragging) return;
|
|
1478
1681
|
dragging = false;
|
|
1682
|
+
startRange = null;
|
|
1479
1683
|
document.body.style.cursor = '';
|
|
1480
1684
|
window.removeEventListener('mousemove', onMove);
|
|
1481
1685
|
window.removeEventListener('mouseup', endDrag);
|
|
@@ -1484,18 +1688,27 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1484
1688
|
if (!e || e.button !== 0 || e.ctrlKey || e.metaKey || e.altKey) return;
|
|
1485
1689
|
const rect = chart.root.getBoundingClientRect();
|
|
1486
1690
|
if (e.clientX < rect.left || e.clientX > rect.right || e.clientY < rect.top || e.clientY > rect.bottom) return;
|
|
1691
|
+
if (chart !== priceChart || !inYAxisZone(chart, e.clientX)) return;
|
|
1692
|
+
const range = currentYRange(chart);
|
|
1693
|
+
if (!range) return;
|
|
1487
1694
|
e.preventDefault();
|
|
1488
1695
|
e.stopPropagation();
|
|
1489
1696
|
dragging = true;
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
startMax = Number.isFinite(s.max) ? s.max : currentCandles[currentCandles.length - 1].time;
|
|
1494
|
-
document.body.style.cursor = 'grabbing';
|
|
1697
|
+
startClientY = e.clientY;
|
|
1698
|
+
startRange = range;
|
|
1699
|
+
document.body.style.cursor = 'ns-resize';
|
|
1495
1700
|
window.addEventListener('mousemove', onMove);
|
|
1496
1701
|
window.addEventListener('mouseup', endDrag, { once: true });
|
|
1497
1702
|
});
|
|
1498
1703
|
}
|
|
1704
|
+
function bindYAxisReset(chart) {
|
|
1705
|
+
chart.root.addEventListener('dblclick', (e) => {
|
|
1706
|
+
if (chart !== priceChart || !inYAxisZone(chart, e.clientX)) return;
|
|
1707
|
+
manualYRange = null;
|
|
1708
|
+
const vis = visiblePriceRange(chart);
|
|
1709
|
+
if (vis) chart.setScale('y', { min: vis[0], max: vis[1] });
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1499
1712
|
function refreshLegend() {
|
|
1500
1713
|
updateLegend(Math.max(0, currentCandles.length - 1));
|
|
1501
1714
|
}
|
|
@@ -1521,6 +1734,9 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1521
1734
|
const oldRange = keepRange && priceChart ? priceChart.scales.x : null;
|
|
1522
1735
|
const needsRebuild = !priceChart || !volumeChart || lastRenderedPriceScale !== currentPriceScale;
|
|
1523
1736
|
if (needsRebuild) {
|
|
1737
|
+
manualYRange = null;
|
|
1738
|
+
priceMarkerLabel = null;
|
|
1739
|
+
priceMarkerLine = null;
|
|
1524
1740
|
if (priceEl) priceEl.innerHTML = '';
|
|
1525
1741
|
if (volumeEl) volumeEl.innerHTML = '';
|
|
1526
1742
|
priceChart = null;
|
|
@@ -1529,6 +1745,16 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1529
1745
|
chartEventsBound = false;
|
|
1530
1746
|
}
|
|
1531
1747
|
const data = buildData();
|
|
1748
|
+
// Dataset changed (timeframe switch, fresh candles): drop any manual
|
|
1749
|
+
// price scale so auto-fit takes over again for the new data shape.
|
|
1750
|
+
const candleKey = currentCandles.length
|
|
1751
|
+
? currentCandles[0].time + ':' + currentCandles[currentCandles.length - 1].time + ':' + currentCandles.length
|
|
1752
|
+
: '';
|
|
1753
|
+
if (candleKey !== lastCandleKey) {
|
|
1754
|
+
lastCandleKey = candleKey;
|
|
1755
|
+
manualYRange = null;
|
|
1756
|
+
}
|
|
1757
|
+
computePriceBounds();
|
|
1532
1758
|
if (needsRebuild) {
|
|
1533
1759
|
makeChart();
|
|
1534
1760
|
} else {
|
|
@@ -1541,6 +1767,13 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1541
1767
|
charts.forEach((chart) => {
|
|
1542
1768
|
bindWheelZoom(chart);
|
|
1543
1769
|
bindPan(chart);
|
|
1770
|
+
if (chart === priceChart) {
|
|
1771
|
+
bindYAxisDrag(chart);
|
|
1772
|
+
bindYAxisReset(chart);
|
|
1773
|
+
chart.root.addEventListener('mousemove', (e) => {
|
|
1774
|
+
chart.root.style.cursor = inYAxisZone(chart, e.clientX) ? 'ns-resize' : '';
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1544
1777
|
chart.over.addEventListener('mousemove', () => {
|
|
1545
1778
|
if (chart.cursor.idx != null) updateLegend(chart.cursor.idx);
|
|
1546
1779
|
});
|
|
@@ -1551,7 +1784,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1551
1784
|
chartEventsBound = true;
|
|
1552
1785
|
}
|
|
1553
1786
|
if (oldRange && Number.isFinite(oldRange.min) && Number.isFinite(oldRange.max)) {
|
|
1554
|
-
const next =
|
|
1787
|
+
const next = clampXRange(oldRange.min, oldRange.max);
|
|
1555
1788
|
if (next) charts.forEach((chart) => chart.batch(() => chart.setScale('x', next)));
|
|
1556
1789
|
}
|
|
1557
1790
|
refreshLegend();
|
|
@@ -1584,6 +1817,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1584
1817
|
if (pairToggle) {
|
|
1585
1818
|
pairToggle.addEventListener('click', () => {
|
|
1586
1819
|
currentPairMode = currentPairMode === 'inverse' ? 'normal' : 'inverse';
|
|
1820
|
+
manualYRange = null;
|
|
1587
1821
|
setControls();
|
|
1588
1822
|
rerender(true);
|
|
1589
1823
|
});
|
|
@@ -1701,13 +1935,7 @@ function generateHTML(data: any, title: any = 'TradingView Style Research') {
|
|
|
1701
1935
|
});
|
|
1702
1936
|
});
|
|
1703
1937
|
|
|
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
|
-
});
|
|
1938
|
+
${zoomResetScript()}
|
|
1711
1939
|
})();
|
|
1712
1940
|
</script>
|
|
1713
1941
|
</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
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
|
|
2
3
|
import { roundTo } from '../../modules/order/utils/math.js';
|
|
3
|
-
'use strict';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Derivative Analyzer
|
|
@@ -235,6 +235,10 @@ class DerivativeAnalyzer {
|
|
|
235
235
|
rsiBullThreshold: number;
|
|
236
236
|
rsiBearThreshold: number;
|
|
237
237
|
macdMinHist: number;
|
|
238
|
+
// Resolved threshold for the MACD-line gates: falls back to the historical
|
|
239
|
+
// 0.02 default only when unset/NaN, so an explicit 0 (strict sign test)
|
|
240
|
+
// stays expressible via the API.
|
|
241
|
+
macdLineGateThreshold: number;
|
|
238
242
|
fastSmaCommitmentBars: number;
|
|
239
243
|
trendFilterEnabled: boolean;
|
|
240
244
|
trendFilterMinBars: number;
|
|
@@ -311,6 +315,11 @@ class DerivativeAnalyzer {
|
|
|
311
315
|
this.rsiBullThreshold = config.rsiBullThreshold ?? 55;
|
|
312
316
|
this.rsiBearThreshold = config.rsiBearThreshold ?? 45;
|
|
313
317
|
this.macdMinHist = config.macdMinHist ?? 0;
|
|
318
|
+
// Unset/NaN → historical 0.02 gate default; explicit 0 → strict sign test.
|
|
319
|
+
// (`this.macdMinHist || 0.02` at the gates made explicit 0 unreachable.)
|
|
320
|
+
this.macdLineGateThreshold = config.macdMinHist != null && Number.isFinite(config.macdMinHist)
|
|
321
|
+
? config.macdMinHist
|
|
322
|
+
: 0.02;
|
|
314
323
|
this.fastSmaCommitmentBars = config.fastSmaCommitmentBars ?? 2;
|
|
315
324
|
this.trendFilterEnabled = config.trendFilterEnabled ?? false;
|
|
316
325
|
this.trendFilterMinBars = config.trendFilterMinBars ?? 3;
|
|
@@ -421,7 +430,7 @@ class DerivativeAnalyzer {
|
|
|
421
430
|
// This ignores marginal crossings at ~0 and ensures signals only start when
|
|
422
431
|
// momentum is clearly confirmed.
|
|
423
432
|
if (this.macd && this.currMacd !== null) {
|
|
424
|
-
const threshold = this.
|
|
433
|
+
const threshold = this.macdLineGateThreshold;
|
|
425
434
|
if ((rawInterp === 'BEAR' || rawInterp === 'BEAR_WEAK') && this.currMacd.macd > -threshold)
|
|
426
435
|
rawInterp = 'NEUTRAL';
|
|
427
436
|
if ((rawInterp === 'BULL' || rawInterp === 'BULL_WEAK') && this.currMacd.macd < threshold)
|
|
@@ -744,7 +753,7 @@ class DerivativeAnalyzer {
|
|
|
744
753
|
if (interp !== 'BULL' && interp !== 'BEAR') return false;
|
|
745
754
|
|
|
746
755
|
if (this.macd && this.currMacd !== null) {
|
|
747
|
-
const threshold = this.
|
|
756
|
+
const threshold = this.macdLineGateThreshold;
|
|
748
757
|
if (interp === 'BULL' && this.currMacd.macd < threshold) return true;
|
|
749
758
|
if (interp === 'BEAR' && this.currMacd.macd > -threshold) return true;
|
|
750
759
|
}
|