dexbot 1.5.2 → 1.6.0
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 +79 -0
- package/README.md +4 -3
- package/analysis/README.md +1 -2
- package/analysis/ama_fitting/fetch_lp_candles.ts +1 -9
- package/analysis/ama_fitting/package.json +1 -1
- package/analysis/analyze_derivatives.ts +1 -1
- package/analysis/bot_usage/discover_bot_accounts.ts +12 -6
- package/analysis/resolve_source.ts +11 -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/tradingview/README.md +32 -10
- package/analysis/tradingview/analyze_tradingview.ts +118 -3
- 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 +1392 -125
- package/analysis/trend_detection/package.json +1 -1
- package/claw/docs/DEXBOT2_TUNING_CHEAT_SHEET.md +1 -1
- package/claw/modules/dexbot_profiles.ts +22 -2
- package/claw/package.json +1 -1
- 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 +1 -1
- package/claw/tests/test_claw_mcp_transport.ts +2 -2
- package/claw/tests/test_dexbot_profiles.ts +65 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.js +1 -9
- package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +1 -1
- package/dist/analysis/analyze_derivatives.js +1 -1
- package/dist/analysis/bot_usage/discover_bot_accounts.js +11 -6
- package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +2 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -1
- package/dist/analysis/resolve_source.d.ts +1 -0
- package/dist/analysis/resolve_source.d.ts.map +1 -1
- package/dist/analysis/resolve_source.js +8 -1
- package/dist/analysis/resolve_source.js.map +1 -1
- package/dist/analysis/tradingview/analyze_tradingview.d.ts +8 -0
- package/dist/analysis/tradingview/analyze_tradingview.d.ts.map +1 -1
- package/dist/analysis/tradingview/analyze_tradingview.js +137 -3
- package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +5 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +1387 -125
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -1
- package/dist/bot.js +1 -1
- package/dist/bot.js.map +1 -1
- package/dist/dexbot.js +3 -3
- package/dist/dexbot.js.map +1 -1
- package/dist/market_adapter/ama_signal_runner.js +2 -2
- package/dist/market_adapter/candle_utils.d.ts +6 -0
- package/dist/market_adapter/candle_utils.d.ts.map +1 -1
- package/dist/market_adapter/candle_utils.js +6 -0
- package/dist/market_adapter/candle_utils.js.map +1 -1
- package/dist/market_adapter/core/asymmetric_bounds.d.ts +33 -1
- package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -1
- package/dist/market_adapter/core/asymmetric_bounds.js +38 -1
- package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -1
- package/dist/market_adapter/core/kibana_candles.d.ts +17 -1
- package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -1
- package/dist/market_adapter/core/kibana_candles.js +101 -19
- package/dist/market_adapter/core/kibana_candles.js.map +1 -1
- package/dist/market_adapter/core/kibana_client.d.ts +2 -0
- package/dist/market_adapter/core/kibana_client.d.ts.map +1 -1
- package/dist/market_adapter/core/kibana_client.js +31 -4
- package/dist/market_adapter/core/kibana_client.js.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.js +0 -6
- package/dist/market_adapter/core/market_adapter_service.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_book_data.d.ts +14 -0
- package/dist/market_adapter/inputs/fetch_book_data.d.ts.map +1 -0
- package/dist/market_adapter/inputs/fetch_book_data.js +138 -0
- package/dist/market_adapter/inputs/fetch_book_data.js.map +1 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts +16 -2
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.js +109 -281
- package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
- package/dist/market_adapter/inputs/kibana_feed_source.d.ts +87 -0
- package/dist/market_adapter/inputs/kibana_feed_source.d.ts.map +1 -0
- package/dist/market_adapter/inputs/kibana_feed_source.js +570 -0
- package/dist/market_adapter/inputs/kibana_feed_source.js.map +1 -0
- package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -1
- package/dist/market_adapter/inputs/kibana_source.js +10 -5
- package/dist/market_adapter/inputs/kibana_source.js.map +1 -1
- package/dist/market_adapter/inputs/window_cache.d.ts +166 -0
- package/dist/market_adapter/inputs/window_cache.d.ts.map +1 -0
- package/dist/market_adapter/inputs/window_cache.js +500 -0
- package/dist/market_adapter/inputs/window_cache.js.map +1 -0
- package/dist/market_adapter/interval_utils.d.ts +8 -1
- package/dist/market_adapter/interval_utils.d.ts.map +1 -1
- package/dist/market_adapter/interval_utils.js +14 -1
- package/dist/market_adapter/interval_utils.js.map +1 -1
- package/dist/modules/account_bots.d.ts +1 -0
- package/dist/modules/account_bots.d.ts.map +1 -1
- package/dist/modules/account_bots.js +21 -5
- package/dist/modules/account_bots.js.map +1 -1
- package/dist/modules/account_orders.d.ts +25 -4
- package/dist/modules/account_orders.d.ts.map +1 -1
- package/dist/modules/account_orders.js +67 -4
- package/dist/modules/account_orders.js.map +1 -1
- package/dist/modules/bitshares-native/chain_client.d.ts +2 -0
- package/dist/modules/bitshares-native/chain_client.d.ts.map +1 -1
- package/dist/modules/bitshares-native/chain_client.js +3 -1
- package/dist/modules/bitshares-native/chain_client.js.map +1 -1
- package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -1
- package/dist/modules/bitshares-native/subscriptions.js +13 -3
- package/dist/modules/bitshares-native/subscriptions.js.map +1 -1
- package/dist/modules/bitshares-native/transport.d.ts +2 -0
- package/dist/modules/bitshares-native/transport.d.ts.map +1 -1
- package/dist/modules/bitshares-native/transport.js +122 -28
- package/dist/modules/bitshares-native/transport.js.map +1 -1
- package/dist/modules/bitshares_client.d.ts.map +1 -1
- package/dist/modules/bitshares_client.js +59 -8
- 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 -0
- package/dist/modules/bot_settings.js.map +1 -1
- package/dist/modules/constants.d.ts +13 -0
- package/dist/modules/constants.d.ts.map +1 -1
- package/dist/modules/constants.js +68 -4
- package/dist/modules/constants.js.map +1 -1
- package/dist/modules/dexbot_class.d.ts +10 -18
- package/dist/modules/dexbot_class.d.ts.map +1 -1
- package/dist/modules/dexbot_class.js +57 -2
- package/dist/modules/dexbot_class.js.map +1 -1
- package/dist/modules/dexbot_cow_runtime.d.ts +62 -37
- package/dist/modules/dexbot_cow_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_cow_runtime.js +797 -569
- package/dist/modules/dexbot_cow_runtime.js.map +1 -1
- package/dist/modules/dexbot_fill_runtime.d.ts +41 -1
- package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_fill_runtime.js +135 -5
- package/dist/modules/dexbot_fill_runtime.js.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.d.ts +79 -12
- package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.js +585 -97
- 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 +13 -0
- package/dist/modules/dexbot_startup_runtime.js.map +1 -1
- package/dist/modules/dexbot_state_recovery.d.ts +15 -1
- package/dist/modules/dexbot_state_recovery.d.ts.map +1 -1
- package/dist/modules/dexbot_state_recovery.js +36 -7
- package/dist/modules/dexbot_state_recovery.js.map +1 -1
- package/dist/modules/fund_registry.d.ts +1 -1
- package/dist/modules/fund_registry.js +1 -1
- package/dist/modules/node_connect_policy.d.ts +52 -0
- package/dist/modules/node_connect_policy.d.ts.map +1 -0
- package/dist/modules/node_connect_policy.js +35 -0
- package/dist/modules/node_connect_policy.js.map +1 -0
- package/dist/modules/node_manager.d.ts +32 -0
- package/dist/modules/node_manager.d.ts.map +1 -1
- package/dist/modules/node_manager.js +76 -9
- package/dist/modules/node_manager.js.map +1 -1
- package/dist/modules/order/accounting.d.ts +30 -0
- package/dist/modules/order/accounting.d.ts.map +1 -1
- package/dist/modules/order/accounting.js +176 -3
- package/dist/modules/order/accounting.js.map +1 -1
- package/dist/modules/order/export.d.ts.map +1 -1
- package/dist/modules/order/export.js +1 -0
- package/dist/modules/order/export.js.map +1 -1
- package/dist/modules/order/grid.d.ts.map +1 -1
- package/dist/modules/order/grid.js +170 -51
- package/dist/modules/order/grid.js.map +1 -1
- package/dist/modules/order/grid_reconcile.d.ts.map +1 -1
- package/dist/modules/order/grid_reconcile.js +5 -3
- package/dist/modules/order/grid_reconcile.js.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.d.ts.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.js +182 -6
- package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
- package/dist/modules/order/manager.d.ts +66 -3
- package/dist/modules/order/manager.d.ts.map +1 -1
- package/dist/modules/order/manager.js +238 -12
- package/dist/modules/order/manager.js.map +1 -1
- package/dist/modules/order/strategy.d.ts +3 -0
- package/dist/modules/order/strategy.d.ts.map +1 -1
- package/dist/modules/order/strategy.js +79 -7
- package/dist/modules/order/strategy.js.map +1 -1
- package/dist/modules/order/sync_engine.d.ts.map +1 -1
- package/dist/modules/order/sync_engine.js +90 -1
- package/dist/modules/order/sync_engine.js.map +1 -1
- package/dist/modules/order/utils/math.d.ts +20 -12
- package/dist/modules/order/utils/math.d.ts.map +1 -1
- package/dist/modules/order/utils/math.js +33 -12
- package/dist/modules/order/utils/math.js.map +1 -1
- package/dist/modules/order/utils/order.d.ts +308 -28
- package/dist/modules/order/utils/order.d.ts.map +1 -1
- package/dist/modules/order/utils/order.js +862 -38
- package/dist/modules/order/utils/order.js.map +1 -1
- package/dist/modules/order/utils/system.d.ts +37 -30
- package/dist/modules/order/utils/system.d.ts.map +1 -1
- package/dist/modules/order/utils/system.js +130 -101
- package/dist/modules/order/utils/system.js.map +1 -1
- package/dist/modules/order/utils/validate.d.ts +3 -2
- package/dist/modules/order/utils/validate.d.ts.map +1 -1
- package/dist/modules/order/utils/validate.js +11 -3
- package/dist/modules/order/utils/validate.js.map +1 -1
- package/dist/modules/paths.d.ts +2 -0
- package/dist/modules/paths.d.ts.map +1 -1
- package/dist/modules/paths.js +1 -0
- package/dist/modules/paths.js.map +1 -1
- package/dist/modules/runtime_settings.d.ts +13 -0
- package/dist/modules/runtime_settings.d.ts.map +1 -1
- package/dist/modules/runtime_settings.js +20 -0
- package/dist/modules/runtime_settings.js.map +1 -1
- package/dist/modules/utils/errors.d.ts +16 -0
- package/dist/modules/utils/errors.d.ts.map +1 -1
- package/dist/modules/utils/errors.js +31 -0
- package/dist/modules/utils/errors.js.map +1 -1
- package/dist/pm2.js +7 -7
- package/dist/scripts/analyze-credit.d.ts.map +1 -1
- package/dist/scripts/analyze-credit.js +13 -3
- package/dist/scripts/analyze-credit.js.map +1 -1
- package/dist/scripts/analyze-orders.js +2 -2
- package/dist/scripts/analyze-orders.js.map +1 -1
- package/dist/scripts/diagnose-kibana-candles.d.ts.map +1 -1
- package/dist/scripts/diagnose-kibana-candles.js +0 -1
- package/dist/scripts/diagnose-kibana-candles.js.map +1 -1
- package/dist/scripts/test-credit-renewal.js +1 -1
- package/dist/scripts/test-credit-renewal.js.map +1 -1
- package/dist/scripts/tv.d.ts +24 -2
- package/dist/scripts/tv.d.ts.map +1 -1
- package/dist/scripts/tv.js +190 -65
- package/dist/scripts/tv.js.map +1 -1
- package/docs/BITSHARES_ONBOARDING.md +9 -2
- package/docs/COW_INVARIANTS.md +18 -1
- package/docs/DEXBOT_COMPARISON.md +3 -3
- package/docs/EVOLUTION.md +9 -7
- package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +21 -9
- package/docs/GRID_RECALCULATION.md +5 -6
- package/docs/GRID_RECONCILE.md +12 -2
- package/docs/MPA_CREDIT_USAGE.md +2 -2
- package/docs/README.md +5 -6
- package/docs/architecture.md +0 -58
- package/docs/developer_guide.md +2 -1
- package/docs/docker.md +1 -1
- package/market_adapter/README.md +4 -0
- package/modules/README.md +1 -1
- package/package.json +1 -1
- package/scripts/README.md +5 -3
- package/tests/README.md +2 -2
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"generatedAt": "2026-08-26T15:40:53.423Z",
|
|
4
|
+
"dataPath": "market_adapter/data/lp/1_3_5537_1_3_0/lp_pool_133_1h.json",
|
|
5
|
+
"resultsPath": "analysis/ama_fitting/optimization_results_lp_pool_133_1h.json",
|
|
6
|
+
"candles": 26281,
|
|
7
|
+
"activeOrders": "all",
|
|
8
|
+
"feeRoundtripPct": 0.2,
|
|
9
|
+
"btsCreateFee": 0.4826,
|
|
10
|
+
"btsCancelFee": 0.00482,
|
|
11
|
+
"makerCreateFactor": 0.1,
|
|
12
|
+
"txFeePrice": 1,
|
|
13
|
+
"btsFeeCapital": 10000,
|
|
14
|
+
"search": {
|
|
15
|
+
"spreadValues": [
|
|
16
|
+
2,
|
|
17
|
+
4
|
|
18
|
+
],
|
|
19
|
+
"incrementValues": [
|
|
20
|
+
0.5,
|
|
21
|
+
1
|
|
22
|
+
],
|
|
23
|
+
"ratioValues": [
|
|
24
|
+
2,
|
|
25
|
+
3
|
|
26
|
+
],
|
|
27
|
+
"minSpreadFactor": 2.1,
|
|
28
|
+
"repositionPct": 1,
|
|
29
|
+
"asymmetricBounds": false,
|
|
30
|
+
"combosPerAma": 8
|
|
31
|
+
},
|
|
32
|
+
"scoring": {
|
|
33
|
+
"baseScore": "totalNetCaptureAfterFeesPct * (fillEfficiency / 100)",
|
|
34
|
+
"gridModel": "persistent fixed chain prices (createOrderGrid port): master rail at sqrt(1±inc) offsets bounded by [center/ratio, center*ratio], gapSlots spread zone centered on center; prices never follow AMA after placement",
|
|
35
|
+
"spreadParam": "targetSpreadPercent for calculateGapSlots (floored at increment * MIN_SPREAD_FACTOR)",
|
|
36
|
+
"resetTriggers": "(A) AMA drift >= 1% from recorded center (ratchet) (trigger B gated off — asymmetricBounds whitelist)",
|
|
37
|
+
"gridPriceOffset": "disabled (asymmetricBounds whitelist)",
|
|
38
|
+
"repositionAccounting": "unfilled orders canceled + counted (incl armed refills/rebids); bought-and-held base carries across resets in a weighted-average-entry inventory pool (resync never market-sells); end-of-run inventory mark is informational and excluded from scoring",
|
|
39
|
+
"cycleEconomics": "slot rotation: filled buy re-offers one rail step up; that refill selling books ~increment% minus round-trip fee and the freed quote re-bids one step down; unlinked initial-grid sells only execute against held inventory at weighted-average entry (no shorting)",
|
|
40
|
+
"totalGrossCapturePct": "sum of realized per-rotation gross from actual fixed prices (linked rotations + inventory sales)",
|
|
41
|
+
"totalNetCapturePct": "realized gross - roundtrip fee per completed disposition; excludes the end-of-run inventory mark",
|
|
42
|
+
"btsFees": "every order placement (initial grid + armed refills/rebids) pays maker create (0.4826*0.1 BTS), every reset cancel pays 0.00482 BTS; btsFeePts = total BTS * txFeePrice / btsFeeCapital * 100 deducted from net before scoring",
|
|
43
|
+
"warmup": "getAmaWarmupBars(er, slow, 0, fast)",
|
|
44
|
+
"riskPenalty": "avgOpenDurationBars*1 + peakOpenOrders*2 + avgImbalance*1.2 + canceledOnReposition*0.15",
|
|
45
|
+
"finalScore": "baseScore - riskPenalty"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"results": [
|
|
49
|
+
{
|
|
50
|
+
"strategy": {
|
|
51
|
+
"id": "AMA1",
|
|
52
|
+
"name": "AMA1",
|
|
53
|
+
"er": 500,
|
|
54
|
+
"fast": 2,
|
|
55
|
+
"slow": 50
|
|
56
|
+
},
|
|
57
|
+
"best": {
|
|
58
|
+
"spreadPct": 4,
|
|
59
|
+
"incrementPct": 0.01,
|
|
60
|
+
"maxMinRatio": 2,
|
|
61
|
+
"touchedOrders": 17118,
|
|
62
|
+
"matchedPairs": 4463,
|
|
63
|
+
"cyclesTotal": 4463,
|
|
64
|
+
"rotationCount": 1911,
|
|
65
|
+
"inventorySaleCount": 2552,
|
|
66
|
+
"avgCyclesPerSlot": 32.81617647058823,
|
|
67
|
+
"fillEfficiency": 26.071971024652413,
|
|
68
|
+
"totalGrossCapturePct": 74380.64032509834,
|
|
69
|
+
"totalNetCapturePct": 73488.04032508115,
|
|
70
|
+
"btsFeePts": 73.45986739997919,
|
|
71
|
+
"btsFeesBts": 7345.986739997918,
|
|
72
|
+
"totalNetCaptureAfterFeesPct": 73414.58045768116,
|
|
73
|
+
"avgNetPerPair": 16.46606325903678,
|
|
74
|
+
"canceledOnReposition": 129640,
|
|
75
|
+
"repositionCount": 972,
|
|
76
|
+
"driftTriggerCount": 972,
|
|
77
|
+
"slopeTriggerCount": 0,
|
|
78
|
+
"inventoryUnits": 567,
|
|
79
|
+
"inventoryAvgEntry": 1480.717680275907,
|
|
80
|
+
"inventoryNetPts": -8250.559317877065,
|
|
81
|
+
"offsetAppliedCount": 0,
|
|
82
|
+
"avgOpenDurationBars": 7.108843537414966,
|
|
83
|
+
"peakOpenOrders": 136,
|
|
84
|
+
"avgImbalance": 4.6666405484818805,
|
|
85
|
+
"riskPenalty": 19730.708812195593,
|
|
86
|
+
"baseScore": 19140.628144796767,
|
|
87
|
+
"utilization": 67.06103580662854,
|
|
88
|
+
"score": -590.0806673988263
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"strategy": {
|
|
93
|
+
"id": "AMA2",
|
|
94
|
+
"name": "AMA2",
|
|
95
|
+
"er": 500,
|
|
96
|
+
"fast": 2,
|
|
97
|
+
"slow": 50
|
|
98
|
+
},
|
|
99
|
+
"best": {
|
|
100
|
+
"spreadPct": 4,
|
|
101
|
+
"incrementPct": 0.01,
|
|
102
|
+
"maxMinRatio": 2,
|
|
103
|
+
"touchedOrders": 17118,
|
|
104
|
+
"matchedPairs": 4463,
|
|
105
|
+
"cyclesTotal": 4463,
|
|
106
|
+
"rotationCount": 1911,
|
|
107
|
+
"inventorySaleCount": 2552,
|
|
108
|
+
"avgCyclesPerSlot": 32.81617647058823,
|
|
109
|
+
"fillEfficiency": 26.071971024652413,
|
|
110
|
+
"totalGrossCapturePct": 74380.64032509834,
|
|
111
|
+
"totalNetCapturePct": 73488.04032508115,
|
|
112
|
+
"btsFeePts": 73.45986739997919,
|
|
113
|
+
"btsFeesBts": 7345.986739997918,
|
|
114
|
+
"totalNetCaptureAfterFeesPct": 73414.58045768116,
|
|
115
|
+
"avgNetPerPair": 16.46606325903678,
|
|
116
|
+
"canceledOnReposition": 129640,
|
|
117
|
+
"repositionCount": 972,
|
|
118
|
+
"driftTriggerCount": 972,
|
|
119
|
+
"slopeTriggerCount": 0,
|
|
120
|
+
"inventoryUnits": 567,
|
|
121
|
+
"inventoryAvgEntry": 1480.717680275907,
|
|
122
|
+
"inventoryNetPts": -8250.559317877065,
|
|
123
|
+
"offsetAppliedCount": 0,
|
|
124
|
+
"avgOpenDurationBars": 7.108843537414966,
|
|
125
|
+
"peakOpenOrders": 136,
|
|
126
|
+
"avgImbalance": 4.6666405484818805,
|
|
127
|
+
"riskPenalty": 19730.708812195593,
|
|
128
|
+
"baseScore": 19140.628144796767,
|
|
129
|
+
"utilization": 67.06103580662854,
|
|
130
|
+
"score": -590.0806673988263
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"strategy": {
|
|
135
|
+
"id": "AMA3",
|
|
136
|
+
"name": "AMA3",
|
|
137
|
+
"er": 500,
|
|
138
|
+
"fast": 2,
|
|
139
|
+
"slow": 50
|
|
140
|
+
},
|
|
141
|
+
"best": {
|
|
142
|
+
"spreadPct": 4,
|
|
143
|
+
"incrementPct": 0.01,
|
|
144
|
+
"maxMinRatio": 2,
|
|
145
|
+
"touchedOrders": 17118,
|
|
146
|
+
"matchedPairs": 4463,
|
|
147
|
+
"cyclesTotal": 4463,
|
|
148
|
+
"rotationCount": 1911,
|
|
149
|
+
"inventorySaleCount": 2552,
|
|
150
|
+
"avgCyclesPerSlot": 32.81617647058823,
|
|
151
|
+
"fillEfficiency": 26.071971024652413,
|
|
152
|
+
"totalGrossCapturePct": 74380.64032509834,
|
|
153
|
+
"totalNetCapturePct": 73488.04032508115,
|
|
154
|
+
"btsFeePts": 73.45986739997919,
|
|
155
|
+
"btsFeesBts": 7345.986739997918,
|
|
156
|
+
"totalNetCaptureAfterFeesPct": 73414.58045768116,
|
|
157
|
+
"avgNetPerPair": 16.46606325903678,
|
|
158
|
+
"canceledOnReposition": 129640,
|
|
159
|
+
"repositionCount": 972,
|
|
160
|
+
"driftTriggerCount": 972,
|
|
161
|
+
"slopeTriggerCount": 0,
|
|
162
|
+
"inventoryUnits": 567,
|
|
163
|
+
"inventoryAvgEntry": 1480.717680275907,
|
|
164
|
+
"inventoryNetPts": -8250.559317877065,
|
|
165
|
+
"offsetAppliedCount": 0,
|
|
166
|
+
"avgOpenDurationBars": 7.108843537414966,
|
|
167
|
+
"peakOpenOrders": 136,
|
|
168
|
+
"avgImbalance": 4.6666405484818805,
|
|
169
|
+
"riskPenalty": 19730.708812195593,
|
|
170
|
+
"baseScore": 19140.628144796767,
|
|
171
|
+
"utilization": 67.06103580662854,
|
|
172
|
+
"score": -590.0806673988263
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"strategy": {
|
|
177
|
+
"id": "AMA4",
|
|
178
|
+
"name": "AMA4",
|
|
179
|
+
"er": 500,
|
|
180
|
+
"fast": 2,
|
|
181
|
+
"slow": 50
|
|
182
|
+
},
|
|
183
|
+
"best": {
|
|
184
|
+
"spreadPct": 4,
|
|
185
|
+
"incrementPct": 0.01,
|
|
186
|
+
"maxMinRatio": 2,
|
|
187
|
+
"touchedOrders": 17118,
|
|
188
|
+
"matchedPairs": 4463,
|
|
189
|
+
"cyclesTotal": 4463,
|
|
190
|
+
"rotationCount": 1911,
|
|
191
|
+
"inventorySaleCount": 2552,
|
|
192
|
+
"avgCyclesPerSlot": 32.81617647058823,
|
|
193
|
+
"fillEfficiency": 26.071971024652413,
|
|
194
|
+
"totalGrossCapturePct": 74380.64032509834,
|
|
195
|
+
"totalNetCapturePct": 73488.04032508115,
|
|
196
|
+
"btsFeePts": 73.45986739997919,
|
|
197
|
+
"btsFeesBts": 7345.986739997918,
|
|
198
|
+
"totalNetCaptureAfterFeesPct": 73414.58045768116,
|
|
199
|
+
"avgNetPerPair": 16.46606325903678,
|
|
200
|
+
"canceledOnReposition": 129640,
|
|
201
|
+
"repositionCount": 972,
|
|
202
|
+
"driftTriggerCount": 972,
|
|
203
|
+
"slopeTriggerCount": 0,
|
|
204
|
+
"inventoryUnits": 567,
|
|
205
|
+
"inventoryAvgEntry": 1480.717680275907,
|
|
206
|
+
"inventoryNetPts": -8250.559317877065,
|
|
207
|
+
"offsetAppliedCount": 0,
|
|
208
|
+
"avgOpenDurationBars": 7.108843537414966,
|
|
209
|
+
"peakOpenOrders": 136,
|
|
210
|
+
"avgImbalance": 4.6666405484818805,
|
|
211
|
+
"riskPenalty": 19730.708812195593,
|
|
212
|
+
"baseScore": 19140.628144796767,
|
|
213
|
+
"utilization": 67.06103580662854,
|
|
214
|
+
"score": -590.0806673988263
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
}
|
|
@@ -4,7 +4,7 @@ This exporter generates a standalone HTML chart in the `analysis/charts/` folder
|
|
|
4
4
|
|
|
5
5
|
## Recommended: `dexbot tv` (One Step)
|
|
6
6
|
|
|
7
|
-
`dexbot tv` fetches the candles itself (chunked Kibana scans
|
|
7
|
+
`dexbot tv` fetches the candles itself (chunked Kibana scans: pools with order-book fallback for pairs) and then renders through this exporter — no manual fetch/export steps needed:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
# Bot chart with AMA overlay (bot key from profiles/bots.json, default: 3 months)
|
|
@@ -17,10 +17,14 @@ dexbot tv 1.19.133
|
|
|
17
17
|
# Any pair (pool-first, order-book fallback)
|
|
18
18
|
dexbot tv TOKENA/TOKENB
|
|
19
19
|
|
|
20
|
+
# MPA price-feed history instead of market candles (opt-in; MPA/MPA pairs
|
|
21
|
+
# cross both feeds into one quote, e.g. HONEST.USD/HONEST.EUR)
|
|
22
|
+
dexbot tv BTS/HONEST.USD --feed
|
|
23
|
+
|
|
20
24
|
# Options
|
|
21
25
|
dexbot tv <bot> --month 6 # months of 1h candles (default: 3)
|
|
22
26
|
dexbot tv <bot> --chart analysis/charts/custom.html
|
|
23
|
-
dexbot tv
|
|
27
|
+
dexbot tv BTS/HONEST.USD --book # override: order-book fills instead of the pool
|
|
24
28
|
```
|
|
25
29
|
|
|
26
30
|
Output: `analysis/charts/tv_<bot|pool_<id>|<a>_<b>>_1h_<N>m.html`, with a clickable `file://` link printed on completion. Unknown targets fail fast with the list of known bot keys.
|
|
@@ -33,9 +37,15 @@ The sections below cover manual usage (explicit candle files, direct runner flag
|
|
|
33
37
|
- Candle timeframe buttons: `1h`, `4h`, `1d`, `1w`
|
|
34
38
|
- Pair-orientation switcher for `A/B` and `B/A`
|
|
35
39
|
- SMA overlay
|
|
36
|
-
- AMA
|
|
40
|
+
- AMA preset buttons `1–4` (one-click AMA1–4, active preset highlighted); numeric inputs kept
|
|
41
|
+
- Bot-grid range highlight, off by default (the bot's min/max around AMA with live asymmetric tilt; red above AMA, green below)
|
|
42
|
+
- Range-scale switch: fit the price axis to the range band
|
|
37
43
|
- VWMA overlay
|
|
38
|
-
-
|
|
44
|
+
- Order overlay for bot charts (active grid buys/sells as dashed levels, reserve line at the lowest grid buy, ceiling line at the highest grid sell, spread label; pair-aware, toggle in-chart)
|
|
45
|
+
- Market panel (top-right): `SELL` / `Market` / `BUY` rows with distance-to-market %
|
|
46
|
+
- Range panel (bottom-right, smaller type): visible-window candle High/Low (red/green, mirroring the SELL/BUY badge)
|
|
47
|
+
- Volume badge (bottom-right of the volume chart, same small type): visible-window max volume, always with the currency suffix (`1.2M BTS`); click the badge, the legend `Vol` value, or the toolbar unit button to switch base/quote units (quote ≈ base × close, persisted per chart like the AMA settings; feed charts show publish counts and disable the switch)
|
|
48
|
+
- Bottom volume panel with `Volume` toggle and per-bar hover tooltip
|
|
39
49
|
- Crosshair legend with current candle values
|
|
40
50
|
|
|
41
51
|
## Quick Start
|
|
@@ -153,7 +163,7 @@ market_adapter/data/lp/<pair>/lp_pool_<id>_<interval>.json
|
|
|
153
163
|
|
|
154
164
|
| Flag | Description |
|
|
155
165
|
|------|-------------|
|
|
156
|
-
| `--bot <
|
|
166
|
+
| `--bot <bot>` | Bot name from `profiles/bots.json` (auto-resolves pool) |
|
|
157
167
|
| `--pool <id>` | Manual mode, no blockchain needed (requires `--precA/--precB`) |
|
|
158
168
|
| `--interval <1m\|5m\|15m\|30m\|1h\|2h\|4h\|6h\|12h\|1d\|1w>` | Candle bucket size (bare numbers = seconds, e.g. `1800` = 30m) |
|
|
159
169
|
| `--lookback <N>h` | Hours back from now |
|
|
@@ -171,16 +181,24 @@ market_adapter/data/lp/<pair>/lp_pool_<id>_<interval>.json
|
|
|
171
181
|
| `--bot-key <key>` | Bot key for `market_adapter` source | — |
|
|
172
182
|
| `--chart <path>` | Output HTML file | `analysis/charts/tradingview_chart.html` |
|
|
173
183
|
| `--title <text>` | Chart title | auto-generated from meta |
|
|
184
|
+
| `--price-scale <log\|linear>` | Price-axis scale | `log` |
|
|
174
185
|
| `--sma-period <n>` | SMA period | `500` |
|
|
175
186
|
| `--ama-er-period <n>` | AMA ER period | `781` |
|
|
176
187
|
| `--ama-fast-period <n>` | AMA fast period | `5.2` |
|
|
177
188
|
| `--ama-slow-period <n>` | AMA slow period | `83.6` |
|
|
178
|
-
| `--price-scale <log\|linear>` | Price axis scale | `log` |
|
|
179
|
-
| `--scale <log\|linear>` | Alias for `--price-scale` | `log` |
|
|
180
189
|
| `--vwap-bars <n>` | Rolling VWMA window | `500` |
|
|
181
190
|
| `--no-sma` | Disable SMA | — |
|
|
182
191
|
| `--no-ama` | Disable AMA | — |
|
|
183
192
|
| `--no-vwap` | Disable VWMA | — |
|
|
193
|
+
| `--range` | Enable range highlight (off by default; toggle in-chart) | off |
|
|
194
|
+
| `--no-range` | Disable range highlight | — |
|
|
195
|
+
| `--range-scale` | Range Scaling: size the band by AMA slope like the grid build + fit price axis to it | — |
|
|
196
|
+
| `--range-span <mult>` | x-range around AMA, 1.2–2 (default: bot grid setting) | bot grid |
|
|
197
|
+
| `--orders-file <path>` | Order-grid JSON override for the overlay (default: `profiles/orders/<botKey>.json`) | bot orders |
|
|
198
|
+
| `--no-orders` | Disable the order overlay (levels, reserve/ceiling lines, spread label) | — |
|
|
199
|
+
| `--update-marker-ts <sec>` | Draw an "updated from here" line at the given unix timestamp | — |
|
|
200
|
+
| `--update-marker-bars <n>` | Bar count shown in the update-marker tag (e.g. `(+12)`) | — |
|
|
201
|
+
| `--no-update-marker` | Suppress the update marker even when the candle file has stamped meta | — |
|
|
184
202
|
| `--quiet` | Suppress progress logs | — |
|
|
185
203
|
|
|
186
204
|
## Notes
|
|
@@ -192,9 +210,13 @@ market_adapter/data/lp/<pair>/lp_pool_<id>_<interval>.json
|
|
|
192
210
|
- VWMA is disabled by default.
|
|
193
211
|
- AMA is auto-enabled when the bot has `gridPrice: "ama"` (or ama1-4), otherwise disabled by default.
|
|
194
212
|
- The AMA controls start with the bot-specific AMA, then pair-specific entry from `profiles/market_profiles.json` when available, falling back to AMA3 values from `modules/constants.ts`.
|
|
195
|
-
- The AMA `
|
|
196
|
-
- The pair switcher inverts the candles client-side, so you can inspect both `A/B` and `B/A` views from one export.
|
|
197
|
-
-
|
|
213
|
+
- The AMA preset buttons `1–4` select the AMA1–4 defaults (active preset highlighted); numeric inputs remain for fine-tuning.
|
|
214
|
+
- The pair switcher inverts the candles client-side, so you can inspect both `A/B` and `B/A` views from one export. The order overlay inverts with it (same levels in display units, side colors preserved).
|
|
215
|
+
- The order overlay resolves from `profiles/orders/<botKey>.json` (same files `scripts/analyze-orders.ts` reads): active/partial grid orders only. Pool/pair charts without a bot key render without it, silently. `--no-orders` removes the whole overlay (levels, reserve/ceiling lines, spread label); the in-chart `Orders` checkbox does the same when orders are present. Grid bounds span the full grid, never calculated: the reserve line sits on the lowest grid buy, the ceiling line on the highest grid sell — live (active/partial) and planned (virtual) slots alike; a missing side hides its line instead of drawing an invented level. Bounds render even when no live levels exist yet (levels, spread, and panel BUY/SELL rows need live orders).
|
|
216
|
+
- The update marker falls back to `prevUpdateLastCandleSec` / `prevUpdateNewBars` stamped in the candle-file `meta` when the flags are absent; those fields are written by external incremental-fetch tooling, not by anything in this repo.
|
|
217
|
+
- `Ctrl+0` (or `Cmd+0`) resets the time-axis zoom to the full dataset.
|
|
218
|
+
- Mouse: drag the candles to pan time + price (price drag sets a manual range); wheel zooms time, except over the price axis where it zooms price. Shift+wheel zooms price anywhere over the price pane (cursor-anchored). Dragging the price-axis gutter scales price, dragging the time-axis gutter scales the timeframe; double-click the price axis to return to autofit. While the price range is manual, timeframe moves no longer refit it.
|
|
219
|
+
- Indicator, timeframe, scale, and overlay-visibility changes are persisted in browser `localStorage` per pool/pair chart (`dexbot2-tradingview-uplot-v3:<pool>:<A>_<B>:<baseSecs|base>`); cursor sync between the price/volume panes uses a separate constant key.
|
|
198
220
|
- The price axis defaults to log base `10`, with a toolbar switch for `Log` / `Linear`.
|
|
199
221
|
- If you regenerate the HTML and then open it later, no CDN access is needed — `uPlot` is loaded from the vendored local copy at `analysis/uplot/`.
|
|
200
222
|
|
|
@@ -35,6 +35,14 @@ function parseArgs() {
|
|
|
35
35
|
amaEnabled: boolean;
|
|
36
36
|
vwapEnabled: boolean;
|
|
37
37
|
vwapBars: number;
|
|
38
|
+
rangeEnabled: boolean;
|
|
39
|
+
rangeScaleEnabled: boolean;
|
|
40
|
+
rangeSpan: number | undefined;
|
|
41
|
+
ordersFile: string | null;
|
|
42
|
+
noOrders: boolean;
|
|
43
|
+
noUpdateMarker: boolean;
|
|
44
|
+
updateMarkerTsSec: number | null;
|
|
45
|
+
updateMarkerNewBars: number | null;
|
|
38
46
|
quiet: boolean;
|
|
39
47
|
listBots: boolean;
|
|
40
48
|
} = {
|
|
@@ -50,6 +58,14 @@ function parseArgs() {
|
|
|
50
58
|
amaEnabled: true,
|
|
51
59
|
vwapEnabled: false,
|
|
52
60
|
vwapBars: 500,
|
|
61
|
+
rangeEnabled: false,
|
|
62
|
+
rangeScaleEnabled: false,
|
|
63
|
+
rangeSpan: undefined,
|
|
64
|
+
ordersFile: null,
|
|
65
|
+
noOrders: false,
|
|
66
|
+
noUpdateMarker: false,
|
|
67
|
+
updateMarkerTsSec: null,
|
|
68
|
+
updateMarkerNewBars: null,
|
|
53
69
|
quiet: false,
|
|
54
70
|
listBots: false,
|
|
55
71
|
};
|
|
@@ -72,7 +88,16 @@ function parseArgs() {
|
|
|
72
88
|
else if (arg === '--no-sma') config.smaEnabled = false;
|
|
73
89
|
else if (arg === '--no-ama') config.amaEnabled = false;
|
|
74
90
|
else if (arg === '--no-vwap') config.vwapEnabled = false;
|
|
75
|
-
else if (arg === '--vwap-bars') config.vwapBars = Math.max(
|
|
91
|
+
else if (arg === '--vwap-bars') config.vwapBars = Math.max(5, parseInt(args[++i], 10) || 500);
|
|
92
|
+
else if (arg === '--range') config.rangeEnabled = true;
|
|
93
|
+
else if (arg === '--no-range') config.rangeEnabled = false;
|
|
94
|
+
else if (arg === '--range-scale') config.rangeScaleEnabled = true;
|
|
95
|
+
else if (arg === '--range-span') config.rangeSpan = parseFloat(args[++i]);
|
|
96
|
+
else if (arg === '--orders-file') config.ordersFile = String(args[++i] || '');
|
|
97
|
+
else if (arg === '--no-orders') config.noOrders = true;
|
|
98
|
+
else if (arg === '--no-update-marker') config.noUpdateMarker = true;
|
|
99
|
+
else if (arg === '--update-marker-ts') config.updateMarkerTsSec = Math.max(0, parseInt(args[++i], 10) || 0) || null;
|
|
100
|
+
else if (arg === '--update-marker-bars') config.updateMarkerNewBars = Math.max(0, parseInt(args[++i], 10) || 0) || null;
|
|
76
101
|
else if (arg === '--list-bots') config.listBots = true;
|
|
77
102
|
else if (arg === '--quiet') config.quiet = true;
|
|
78
103
|
}
|
|
@@ -85,6 +110,61 @@ function loadJsonMeta(filePath: any) {
|
|
|
85
110
|
return loadCandleFile(filePath);
|
|
86
111
|
}
|
|
87
112
|
|
|
113
|
+
// ── Order overlay: live grid levels (buys/sells) + full-grid bounds ──
|
|
114
|
+
// Canonical source is profiles/orders/<botKey>.json (same files
|
|
115
|
+
// scripts/analyze-orders.ts reads); --orders-file overrides, --no-orders
|
|
116
|
+
// disables. Pool/pair charts without a bot key render without overlay,
|
|
117
|
+
// silently — no hardcoded personal paths.
|
|
118
|
+
function resolveOrdersFile(botKey: string | null | undefined, explicit: string | null | undefined, disabled: boolean): string | null {
|
|
119
|
+
if (disabled) return null;
|
|
120
|
+
if (explicit) {
|
|
121
|
+
try { if (fs.existsSync(explicit)) return explicit; } catch { /* fall through to warning */ }
|
|
122
|
+
console.warn(`[TradingView] --orders-file not found: ${explicit} (rendering without order overlay)`);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
if (!botKey) return null;
|
|
126
|
+
try {
|
|
127
|
+
const ordersDir = (PATHS as any).ORDERS_DIR || path.join(path.dirname(PATHS.PROFILES.BOTS_JSON), 'orders');
|
|
128
|
+
const direct = path.join(ordersDir, `${botKey}.json`);
|
|
129
|
+
if (fs.existsSync(direct)) return direct;
|
|
130
|
+
} catch { /* silent when absent */ }
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Single-pass read of the order grid, like the runtime sees it: live
|
|
135
|
+
// (active/partial) levels for the overlay plus full-grid bounds (live +
|
|
136
|
+
// planned/virtual slots). Virtual slots carry the same slot geometry
|
|
137
|
+
// without an on-chain order, so excluding them would shrink the shown
|
|
138
|
+
// grid to the live extremes. Spread-type slots are neither buys nor
|
|
139
|
+
// sells and stay out of both.
|
|
140
|
+
function loadOrdersData(filePath: string | null): { buys: number[]; sells: number[]; low: number | null; high: number | null } {
|
|
141
|
+
if (!filePath) return { buys: [], sells: [], low: null, high: null };
|
|
142
|
+
try {
|
|
143
|
+
const od = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
144
|
+
const grid = Array.isArray(od?.grid) ? od.grid : (Array.isArray(od?.orders) ? od.orders : []);
|
|
145
|
+
const buys: number[] = [];
|
|
146
|
+
const sells: number[] = [];
|
|
147
|
+
let low: number | null = null;
|
|
148
|
+
let high: number | null = null;
|
|
149
|
+
for (const s of grid) {
|
|
150
|
+
const price = Number((s as any)?.price);
|
|
151
|
+
if (!Number.isFinite(price) || price <= 0) continue;
|
|
152
|
+
const st = (s as any)?.state;
|
|
153
|
+
if (st !== 'active' && st !== 'partial' && st !== 'virtual') continue;
|
|
154
|
+
if ((s as any)?.type === 'buy') {
|
|
155
|
+
if (low == null || price < low) low = price;
|
|
156
|
+
if (st !== 'virtual') buys.push(price);
|
|
157
|
+
} else if ((s as any)?.type === 'sell') {
|
|
158
|
+
if (high == null || price > high) high = price;
|
|
159
|
+
if (st !== 'virtual') sells.push(price);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
buys.sort((a, b) => a - b);
|
|
163
|
+
sells.sort((a, b) => a - b);
|
|
164
|
+
return { buys, sells, low, high };
|
|
165
|
+
} catch { return { buys: [], sells: [], low: null, high: null }; }
|
|
166
|
+
}
|
|
167
|
+
|
|
88
168
|
function inferTitle(meta: any, fallback: string) {
|
|
89
169
|
const pool = meta?.pool ? `Pool ${String(meta.pool).replace(/^1\.19\./, '')}` : null;
|
|
90
170
|
const a = meta?.assetA?.symbol || meta?.assetA?.id || null;
|
|
@@ -104,7 +184,7 @@ async function main() {
|
|
|
104
184
|
return;
|
|
105
185
|
}
|
|
106
186
|
|
|
107
|
-
const { source, botKey, amaConfig } = resolveSource({ ...config.source.config, type: config.source.type }, { quiet: config.quiet });
|
|
187
|
+
const { source, botKey, amaConfig, meta: sourceMeta } = resolveSource({ ...config.source.config, type: config.source.type }, { quiet: config.quiet });
|
|
108
188
|
if (!config.quiet) console.log(`[TradingView] Loading candles from ${source.name}...`);
|
|
109
189
|
|
|
110
190
|
const candles = await source.fetchCandles();
|
|
@@ -116,7 +196,9 @@ async function main() {
|
|
|
116
196
|
const filePath = config.source.config.filePath;
|
|
117
197
|
const rawJson = isJsonSource ? loadJsonMeta(filePath) : { meta: null, candles: null };
|
|
118
198
|
const botMeta = botKey ? loadBotMeta(botKey) : null;
|
|
119
|
-
|
|
199
|
+
// Prefer meta from the actual candle file (has pool + asset ids) over
|
|
200
|
+
// the bots.json fallback, which only knows the asset symbols.
|
|
201
|
+
const jsonMeta = rawJson.meta || sourceMeta || (botMeta ? {
|
|
120
202
|
assetA: { symbol: botMeta.assetA },
|
|
121
203
|
assetB: { symbol: botMeta.assetB },
|
|
122
204
|
intervalSeconds: 3600,
|
|
@@ -125,6 +207,27 @@ async function main() {
|
|
|
125
207
|
const hasAmaGridPrice = AMA_KEYWORDS.has(String(botMeta?.gridPrice || '').trim().toLowerCase());
|
|
126
208
|
const amaEnabled = hasAmaGridPrice ? config.amaEnabled : false;
|
|
127
209
|
|
|
210
|
+
// Bot grid bounds for the range highlight: mirrors the runtime grid
|
|
211
|
+
// (center = AMA, min "Nx" = center/N, max "Nx" = center*N) with the
|
|
212
|
+
// live asymmetric tilt. Null when no bot key (width% fallback in-page).
|
|
213
|
+
const grid = botMeta?.minPrice != null && botMeta?.maxPrice != null ? {
|
|
214
|
+
minPrice: botMeta.minPrice,
|
|
215
|
+
maxPrice: botMeta.maxPrice,
|
|
216
|
+
incrementPercent: Number(botMeta.incrementPercent) > 0 ? Number(botMeta.incrementPercent) : null,
|
|
217
|
+
maxAsymmetryFactor: Number.isFinite(Number(botMeta?.asymmetricBounds?.maxAsymmetryFactor))
|
|
218
|
+
? Number(botMeta.asymmetricBounds.maxAsymmetryFactor)
|
|
219
|
+
: null,
|
|
220
|
+
minScaleSlots: Number.isFinite(Number(botMeta?.asymmetricBounds?.minScaleSlots))
|
|
221
|
+
? Number(botMeta.asymmetricBounds.minScaleSlots)
|
|
222
|
+
: null,
|
|
223
|
+
} : null;
|
|
224
|
+
// Order overlay (canonical profiles/orders/<botKey>.json; silent when absent)
|
|
225
|
+
const ordersFile = resolveOrdersFile(botKey, config.ordersFile, config.noOrders);
|
|
226
|
+
const ordersData = loadOrdersData(ordersFile);
|
|
227
|
+
const orderBuys = ordersData.buys;
|
|
228
|
+
const orderSells = ordersData.sells;
|
|
229
|
+
const gridBounds = { low: ordersData.low, high: ordersData.high };
|
|
230
|
+
if (!config.quiet && ordersFile) console.log(`[TradingView] Order overlay: ${orderBuys.length} buys + ${orderSells.length} sells from ${ordersFile}`);
|
|
128
231
|
const html = generateHTML({
|
|
129
232
|
candles,
|
|
130
233
|
meta: jsonMeta || {
|
|
@@ -141,9 +244,21 @@ async function main() {
|
|
|
141
244
|
amaEnabled,
|
|
142
245
|
vwapEnabled: config.vwapEnabled,
|
|
143
246
|
vwapBars: config.vwapBars,
|
|
247
|
+
rangeEnabled: config.rangeEnabled,
|
|
248
|
+
rangeScaleEnabled: config.rangeScaleEnabled,
|
|
249
|
+
rangeSpan: config.rangeSpan,
|
|
250
|
+
grid,
|
|
144
251
|
priceScale: config.priceScale === 'linear' ? 'linear' : 'log',
|
|
145
252
|
defaultTimeframe: '1h',
|
|
146
253
|
marketAdapter: MARKET_ADAPTER,
|
|
254
|
+
orders: { buys: orderBuys, sells: orderSells },
|
|
255
|
+
gridBounds,
|
|
256
|
+
// Update marker ("updated from here" line): explicit CLI flags win,
|
|
257
|
+
// otherwise fall back to stamped data-file meta when present.
|
|
258
|
+
updateMarkerTsSec: config.noUpdateMarker ? null : (config.updateMarkerTsSec
|
|
259
|
+
?? (Number((jsonMeta as any)?.prevUpdateLastCandleSec) > 0 ? Number((jsonMeta as any).prevUpdateLastCandleSec) : null)),
|
|
260
|
+
updateMarkerNewBars: config.noUpdateMarker ? null : (config.updateMarkerNewBars
|
|
261
|
+
?? (Number((jsonMeta as any)?.prevUpdateNewBars) || null)),
|
|
147
262
|
}, title);
|
|
148
263
|
|
|
149
264
|
writeChartFile(config.chartFile, html);
|