dexbot 1.6.4 → 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +12 -12
  3. package/analysis/README.md +8 -1
  4. package/analysis/ama_fitting/package.json +1 -1
  5. package/analysis/analyze_dynamic_weight.ts +9 -3
  6. package/analysis/tradingview/analyze_tradingview.ts +5 -0
  7. package/analysis/tradingview/tradingview_uplot_chart_generator.ts +2 -2
  8. package/analysis/trend_detection/DYNAMIC_WEIGHT_RESEARCH.md +35 -2
  9. package/analysis/trend_detection/dynamic_weight_chart_generator.ts +82 -10
  10. package/analysis/trend_detection/package.json +1 -1
  11. package/claw/modules/dexbot_profiles.ts +4 -3
  12. package/claw/package.json +1 -1
  13. package/claw/runtimes/openclaw-plugin/openclaw.plugin.json +1 -1
  14. package/claw/runtimes/openclaw-plugin/package.json +1 -1
  15. package/claw/tests/test_claw_mcp_transport.ts +2 -2
  16. package/claw/tests/test_dexbot_profiles.ts +18 -1
  17. package/dist/analysis/analyze_dynamic_weight.js +9 -3
  18. package/dist/analysis/analyze_dynamic_weight.js.map +1 -1
  19. package/dist/analysis/tradingview/analyze_tradingview.d.ts.map +1 -1
  20. package/dist/analysis/tradingview/analyze_tradingview.js +5 -0
  21. package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -1
  22. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +2 -2
  23. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +1 -1
  24. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +82 -10
  25. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +1 -1
  26. package/dist/dexbot.d.ts.map +1 -1
  27. package/dist/dexbot.js +27 -68
  28. package/dist/dexbot.js.map +1 -1
  29. package/dist/market_adapter/core/asymmetric_bounds.d.ts +2 -2
  30. package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -1
  31. package/dist/market_adapter/core/asymmetric_bounds.js +15 -12
  32. package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -1
  33. package/dist/market_adapter/interval_utils.d.ts +1 -1
  34. package/dist/market_adapter/interval_utils.js +1 -1
  35. package/dist/modules/account_bots.d.ts +55 -5
  36. package/dist/modules/account_bots.d.ts.map +1 -1
  37. package/dist/modules/account_bots.js +258 -117
  38. package/dist/modules/account_bots.js.map +1 -1
  39. package/dist/modules/bot_defaults.d.ts +98 -0
  40. package/dist/modules/bot_defaults.d.ts.map +1 -0
  41. package/dist/modules/bot_defaults.js +169 -0
  42. package/dist/modules/bot_defaults.js.map +1 -0
  43. package/dist/modules/bot_settings.d.ts.map +1 -1
  44. package/dist/modules/bot_settings.js +4 -1
  45. package/dist/modules/bot_settings.js.map +1 -1
  46. package/dist/modules/config.d.ts +1 -0
  47. package/dist/modules/config.d.ts.map +1 -1
  48. package/dist/modules/config.js +1 -0
  49. package/dist/modules/config.js.map +1 -1
  50. package/dist/modules/constants.d.ts +11 -2
  51. package/dist/modules/constants.d.ts.map +1 -1
  52. package/dist/modules/constants.js +40 -27
  53. package/dist/modules/constants.js.map +1 -1
  54. package/dist/modules/dexbot_maintenance_runtime.d.ts +1 -1
  55. package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
  56. package/dist/modules/dexbot_maintenance_runtime.js +9 -4
  57. package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
  58. package/dist/modules/launcher/adapter_requirement.js +1 -1
  59. package/dist/modules/launcher/launch_modes.d.ts +17 -1
  60. package/dist/modules/launcher/launch_modes.d.ts.map +1 -1
  61. package/dist/modules/launcher/launch_modes.js +18 -1
  62. package/dist/modules/launcher/launch_modes.js.map +1 -1
  63. package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
  64. package/dist/modules/launcher/monolithic_runtime.js +8 -1
  65. package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
  66. package/dist/modules/market_adapter_whitelist.d.ts +40 -1
  67. package/dist/modules/market_adapter_whitelist.d.ts.map +1 -1
  68. package/dist/modules/market_adapter_whitelist.js +161 -11
  69. package/dist/modules/market_adapter_whitelist.js.map +1 -1
  70. package/dist/modules/order/grid.d.ts +9 -0
  71. package/dist/modules/order/grid.d.ts.map +1 -1
  72. package/dist/modules/order/grid.js +23 -5
  73. package/dist/modules/order/grid.js.map +1 -1
  74. package/dist/modules/order/manager.js +3 -2
  75. package/dist/modules/order/manager.js.map +1 -1
  76. package/dist/modules/order/utils/system.d.ts +5 -1
  77. package/dist/modules/order/utils/system.d.ts.map +1 -1
  78. package/dist/modules/order/utils/system.js +5 -2
  79. package/dist/modules/order/utils/system.js.map +1 -1
  80. package/dist/modules/settings_merge.d.ts +10 -1
  81. package/dist/modules/settings_merge.d.ts.map +1 -1
  82. package/dist/modules/settings_merge.js +27 -17
  83. package/dist/modules/settings_merge.js.map +1 -1
  84. package/dist/modules/validate_profiles.d.ts.map +1 -1
  85. package/dist/modules/validate_profiles.js +4 -3
  86. package/dist/modules/validate_profiles.js.map +1 -1
  87. package/dist/scripts/chart_command.d.ts +48 -0
  88. package/dist/scripts/chart_command.d.ts.map +1 -0
  89. package/dist/scripts/chart_command.js +504 -0
  90. package/dist/scripts/chart_command.js.map +1 -0
  91. package/dist/scripts/dw.d.ts +3 -0
  92. package/dist/scripts/dw.d.ts.map +1 -0
  93. package/dist/scripts/dw.js +30 -0
  94. package/dist/scripts/dw.js.map +1 -0
  95. package/dist/scripts/tv.d.ts +1 -31
  96. package/dist/scripts/tv.d.ts.map +1 -1
  97. package/dist/scripts/tv.js +10 -463
  98. package/dist/scripts/tv.js.map +1 -1
  99. package/dist/scripts/update.js +99 -62
  100. package/dist/scripts/update.js.map +1 -1
  101. package/dist/scripts/update_dist_freshness.d.ts +46 -0
  102. package/dist/scripts/update_dist_freshness.d.ts.map +1 -0
  103. package/dist/scripts/update_dist_freshness.js +115 -0
  104. package/dist/scripts/update_dist_freshness.js.map +1 -0
  105. package/dist/unlock.js +1 -1
  106. package/dist/unlock.js.map +1 -1
  107. package/docs/BITSHARES_ONBOARDING.md +10 -7
  108. package/docs/DEXBOT_COMPARISON.md +3 -3
  109. package/docs/EVOLUTION.md +8 -7
  110. package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +4 -4
  111. package/docs/GRID_RECALCULATION.md +20 -24
  112. package/docs/GRID_RECONCILE.md +2 -2
  113. package/docs/LOGGING.md +1 -0
  114. package/docs/README.md +16 -16
  115. package/docs/WORKFLOW.md +1 -2
  116. package/docs/architecture.md +2 -2
  117. package/docs/developer_guide.md +1 -0
  118. package/market_adapter/README.md +36 -60
  119. package/modules/README.md +2 -1
  120. package/package.json +1 -2
  121. package/scripts/README.md +18 -25
  122. package/scripts/reset-settings.sh +1 -1
  123. package/dist/scripts/generate_market_adapter_whitelist.d.ts +0 -15
  124. package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +0 -1
  125. package/dist/scripts/generate_market_adapter_whitelist.js +0 -191
  126. package/dist/scripts/generate_market_adapter_whitelist.js.map +0 -1
@@ -21,13 +21,13 @@ The live signal layer for AMA-priced bots. It reads candles, computes the AMA ce
21
21
 
22
22
  | If you want to… | Read this | Key command |
23
23
  |-----------------|-----------|-------------|
24
- | Enable AMA pricing for a bot | [Quick Start](#quick-start) | `dexbot white` |
24
+ | Enable AMA pricing for a bot | [Quick Start](#quick-start) | `dexbot bot` → `6) Adapter` |
25
25
  | Change how often the grid rebuilds | [Trigger Threshold](#trigger-threshold) | edit `AMA_DELTA_THRESHOLD_PERCENT` |
26
- | Tune buy/sell weight bias | [Asymmetric Weight Shift](#asymmetric-weight-shift) | whitelist `dynamicWeight: true` |
27
- | Widen/tighten grid bounds by trend | [Grid Range Scaling](#grid-range-scaling) | whitelist `asymmetricBounds: true` |
26
+ | Tune buy/sell weight bias | [Asymmetric Weight Shift](#asymmetric-weight-shift) | `6) Adapter` → Weight |
27
+ | Widen/tighten grid bounds by trend | [Grid Range Scaling](#grid-range-scaling) | `6) Adapter` → Range |
28
28
  | Override settings for one pair or bot | [Settings and Overrides](#settings-and-overrides) | edit `profiles/market_adapter_settings.json` |
29
29
  | Run the adapter standalone or test dry-run | [Live Writes and Dry-Run](#live-writes-and-dry-run) | `node dist/market_adapter/market_adapter.js --dryRun` |
30
- | Debug a bot not being processed | [Troubleshooting](#troubleshooting) | `dexbot white` |
30
+ | Debug a bot not being processed | [Troubleshooting](#troubleshooting) | `6) Adapter` flags |
31
31
  | Understand the signal pipeline or module layout | [Technical Reference](#technical-reference) | — |
32
32
 
33
33
  ## Big Picture
@@ -64,47 +64,23 @@ default preset.
64
64
 
65
65
  When fetching candles (`pool` or `book`), the adapter requires a full historical window. The oldest `erPeriod` candles are used for an initial SMA (Simple Moving Average) warmup phase to seed the AMA and establish the first Efficiency Ratio (ER) calculation. See [AMA Warmup Window](#ama-warmup-window--why-candle-length-matters) for technical details.
66
66
 
67
- ### 2. Whitelist Live Writes
67
+ ### 2. Enable Live Writes
68
68
 
69
- Generate the whitelist from AMA-enabled bots. Without a whitelist entry, the
70
- adapter still computes state, but live grid snapshots and recalc triggers stay
71
- in dry-run mode.
69
+ Open the bot editor — `dexbot bot` → `2) Modify bot` → pick the bot →
70
+ `6) Adapter` — and set the three per-bot flags:
72
71
 
73
- ```bash
74
- dexbot white
75
- ```
76
-
77
- This writes `profiles/market_adapter_whitelist.json`, where each bot's AMA,
78
- dynamic-weight, and range-scaling flags can be inspected or adjusted.
79
-
80
- By default, newly generated entries whitelist AMA pricing only, keeping both
81
- dynamic weights and range scaling (asymmetric bounds) disabled. To opt newly
82
- generated entries into dynamic weights:
83
-
84
- ```bash
85
- dexbot white --dynamic-weight
86
- ```
87
-
88
- To opt newly generated entries into range scaling:
72
+ | Flag | Whitelist key | Effect |
73
+ |------|---------------|--------|
74
+ | **Price** | `ama` | Allows live `dynamicgrid.json` and recalc-trigger writes. Without it the adapter still computes state, but live output stays in dry-run. |
75
+ | **Weight** | `dynamicWeight` | Opt-in dynamic buy/sell weights. |
76
+ | **Range** | `asymmetricBounds` | Opt-in AMA-slope range scaling. |
89
77
 
90
- ```bash
91
- dexbot white --asymmetric-bounds
92
- ```
93
-
94
- To overwrite an existing entry (existing entries are otherwise preserved):
95
-
96
- ```bash
97
- dexbot white --dynamic-weight --bot <botKey>
98
- dexbot white --asymmetric-bounds --bot <botKey>
99
- ```
100
-
101
- `--bot` implies overwrite for that key only; without it, `dexbot white` only adds missing bots.
102
-
103
- Remove stale whitelist entries (bots no longer in `bots.json`):
104
-
105
- ```bash
106
- dexbot white --prune
107
- ```
78
+ The flags are stored per bot in `profiles/market_adapter_whitelist.json`;
79
+ re-open the section any time to inspect or change them. Boolean prompts
80
+ accept `y`/`yes`/`true` and `n`/`no`/`false`; Enter keeps the current value.
81
+ Renaming a bot carries its flags to the new key, deleting a bot removes its
82
+ entry, and all-off flags are saved as an explicit `false` entry so the flags
83
+ never silently fall back to defaults.
108
84
 
109
85
  ### 3. Start DEXBot2
110
86
 
@@ -156,10 +132,8 @@ whitelist gate:
156
132
 
157
133
  This is separate from dynamic buy/sell weighting. Both grid-range effects are
158
134
  enabled only when `asymmetricBounds: true` is set in
159
- `profiles/market_adapter_whitelist.json`. Range scaling is opt-in: `dexbot white`
160
- generates AMA-only entries by default, so enable it with
161
- `dexbot white --asymmetric-bounds` (new bots) or
162
- `dexbot white --asymmetric-bounds --bot <botKey>` (existing entry).
135
+ `profiles/market_adapter_whitelist.json`. Range scaling is opt-in: enable it
136
+ per bot with `dexbot bot` → `2) Modify bot` → `6) Adapter` → **Range**.
163
137
 
164
138
  Technical formula and tuning details are in
165
139
  [Grid Range Scaling Model](#grid-range-scaling-model).
@@ -334,11 +308,8 @@ Dry-run log lines include `[DRY RUN]` or `[suppressed, dry-run]`.
334
308
 
335
309
  | Task | Command |
336
310
  |------|---------|
337
- | Generate whitelist | `dexbot white` |
338
- | Opt new whitelist entries into dynamic weights | `dexbot white --dynamic-weight` |
339
- | Opt new whitelist entries into range scaling | `dexbot white --asymmetric-bounds` |
340
- | Overwrite existing entry for a specific bot | `dexbot white --dynamic-weight --bot <botKey>` \| `dexbot white --asymmetric-bounds --bot <botKey>` |
341
- | Prune stale whitelist entries (bots removed from bots.json) | `dexbot white --prune` |
311
+ | Enable/inspect Price, Weight, Range for a bot | `dexbot bot` → `2) Modify bot` → `6) Adapter` |
312
+ | Remove a deleted bot's entry | Automatic — `dexbot bot` → `3) Delete` also drops its whitelist key |
342
313
  | Probe public CEX availability | `node dist/market_adapter/inputs/fetch_cex_synthetic_data.js --exchange auto --check-only` |
343
314
  | Seed synthetic cross candles | `node dist/market_adapter/inputs/fetch_cex_synthetic_data.js --exchange auto --bot-key <bot-key>` |
344
315
  | Run one adapter cycle | `node dist/market_adapter/market_adapter.js --once` |
@@ -368,7 +339,7 @@ match the bot's eventual `botKey`.
368
339
  ### Bot is not processed
369
340
 
370
341
  - Confirm `gridPrice` is `ama`, `ama1`, `ama2`, `ama3`, or `ama4`.
371
- - Regenerate the whitelist with `dexbot white`.
342
+ - Open `dexbot bot` → `2) Modify bot` → `6) Adapter` and confirm **Price** is `true`.
372
343
  - Confirm the expected `botKey` exists in `profiles/market_adapter_whitelist.json`.
373
344
  - If `startPrice` is numeric, the adapter will not fetch pool/book candles for that bot. Use `startPrice` only for a fixed anchor in that case; `gridPrice` remains a separate grid setting.
374
345
 
@@ -377,7 +348,7 @@ match the bot's eventual `botKey`.
377
348
  - Check `lastDeltaPercent` vs `thresholdPercent`.
378
349
  - Check `staleData` and `staleAgeHours`.
379
350
  - **Confirm the bot is whitelisted.** Non-whitelisted bots only log and do not write triggers.
380
- - Confirm the bot's whitelist entry has `"ama": true`.
351
+ - Confirm the bot's whitelist entry has `"ama": true` (`dexbot bot` → `6) Adapter` shows it as **Price**).
381
352
  - Run `node dist/market_adapter/market_adapter.js --once --deltaPercent <lower-value>` for a one-cycle threshold test.
382
353
 
383
354
  ### Trigger fires too often
@@ -632,7 +603,9 @@ market_adapter/
632
603
 
633
604
  ### Whitelist Semantics
634
605
 
635
- `profiles/market_adapter_whitelist.json` controls live writes:
606
+ `profiles/market_adapter_whitelist.json` controls live writes. It is edited
607
+ per bot in the bot editor (`dexbot bot` → `6) Adapter`), which reads and
608
+ writes this same file:
636
609
 
637
610
  ```json
638
611
  {
@@ -667,8 +640,11 @@ AMA slope -> live market/start-price offset, capped at half spread
667
640
 
668
641
  During a grid rebuild, the bot loads the latest dynamic grid snapshot and uses
669
642
  the AMA slope diagnostics to tilt the configured `minPrice` and `maxPrice`
670
- around the AMA center. An uptrend widens the upper bound and tightens the lower
671
- bound; a downtrend widens the lower bound and tightens the upper bound.
643
+ around the AMA center. A reciprocal (log-symmetric) tilt scales both bounds by
644
+ the same factor: an uptrend shifts the whole band up by `1 + asymmetry`, a
645
+ downtrend shifts it down by `1 / (1 + asymmetry)`. The trend side therefore
646
+ extends while the opposite side tightens toward the center, while total log
647
+ width (and slot count) is preserved.
672
648
 
673
649
  The same `asymmetricBounds` whitelist also enables `gridPriceOffsetPct`: a
674
650
  slope-ratio offset applied only to the live `startPrice` used for initial
@@ -686,15 +662,15 @@ slopeOffset = slope normalized to the configured dynamic-weight slope cap
686
662
  asymmetry = min(|slopeOffset| / maxSlopeOffset, 1) × maxAsymmetryFactor
687
663
 
688
664
  Downtrend: minPrice = center / (M × (1 + asymmetry))
689
- maxPrice = center × (M × (1 - asymmetry))
665
+ maxPrice = (center × M) / (1 + asymmetry)
690
666
 
691
667
  Uptrend: maxPrice = center × (M × (1 + asymmetry))
692
- minPrice = center / (M × (1 - asymmetry))
668
+ minPrice = (center / M) × (1 + asymmetry)
693
669
 
694
670
  Neutral: symmetric bounds (asymmetry = 0)
695
671
  ```
696
672
 
697
- `ASYMMETRIC_BOUNDS_MAX_ASYMMETRY_FACTOR` defaults to `0.35`; `0` disables the
673
+ `ASYMMETRIC_BOUNDS_MAX_ASYMMETRY_FACTOR` defaults to `0.333`; `0` disables the
698
674
  tilt. `ASYMMETRIC_BOUNDS_MIN_SCALE_SLOTS` defaults to `10` and sets the minimum
699
675
  number of price levels the *tightened* side of a range-scaled grid must keep
700
676
  between the grid center and its bound (measured in `incrementPercent` steps);
@@ -710,7 +686,7 @@ Both are configurable per bot or per market via
710
686
  {
711
687
  "globals": {
712
688
  "asymmetricBounds": {
713
- "maxAsymmetryFactor": 0.35,
689
+ "maxAsymmetryFactor": 0.333,
714
690
  "minScaleSlots": 10
715
691
  }
716
692
  },
package/modules/README.md CHANGED
@@ -8,7 +8,7 @@ Everything below covers bot lifecycle, order management, blockchain connectivity
8
8
 
9
9
  If you're new to the codebase, read these files in order (~20 minutes):
10
10
 
11
- 1. **`constants.ts`** — all tuning parameters and defaults live here; gives you a map of the system's knobs
11
+ 1. **`constants.ts`** — all tuning parameters and defaults live here; gives you a map of the system's knobs, and `buildDefaultGeneralSettings()` builds the canonical default `general.settings.json` document (first-run, editor fallback, local-overrides merge all share it)
12
12
  2. **`dexbot_class.ts`** — the top-level orchestrator; shows how bot startup, fill processing, and maintenance connect
13
13
  3. **`order/manager.ts`** — the central controller for the grid; read the constructor and `_applySafeRebalanceCOW()`
14
14
  4. **`order/grid.ts`** — how the geometric grid is generated and sized
@@ -36,6 +36,7 @@ modules/
36
36
  ├── credential_policy.ts signing policy validation
37
37
  ├── credential_session_cache.ts encrypted session cache
38
38
  ├── constants.ts central config and tuning params
39
+ ├── bot_defaults.ts bot defaults seeder (draft/entry/runtime-config modes)
39
40
  ├── config.ts load-time process.env snapshot
40
41
  ├── env.ts isBrowser/hasProcess detection
41
42
  ├── runtime.ts process abstraction singleton
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dexbot",
3
- "version": "1.6.4",
3
+ "version": "1.6.5",
4
4
  "description": "The first open source trading bot with zero runtime dependencies and a fully adaptive market making strategy.",
5
5
  "main": "dist/modules/dexbot_class.js",
6
6
  "exports": {
@@ -83,7 +83,6 @@
83
83
  "pdev": "bash scripts/pdev.sh",
84
84
  "ptest": "bash scripts/ptest.sh",
85
85
  "lp:chart": "npm run build && node dist/scripts/generate_lp_chart.js",
86
- "market-adapter:whitelist": "npm run build && node dist/scripts/generate_market_adapter_whitelist.js",
87
86
  "market-adapter:fetch-cex-synthetic": "npm run build && node dist/market_adapter/inputs/fetch_cex_synthetic_data.js",
88
87
  "analysis:tradingview": "npm run build && node dist/analysis/tradingview/analyze_tradingview.js",
89
88
  "ama:chart:lp-local": "npm run build && node dist/analysis/ama_fitting/generate_unified_comparison_chart.js",
package/scripts/README.md CHANGED
@@ -93,29 +93,6 @@ bash scripts/reset-settings.sh
93
93
  node dist/scripts/validate_bots.js
94
94
  ```
95
95
 
96
- ### Market Adapter Whitelist Generation
97
- **File:** `generate_market_adapter_whitelist.ts`
98
- **Purpose:** Generate `profiles/market_adapter_whitelist.json` from bots whose `gridPrice` uses AMA mode.
99
- ```bash
100
- # Add missing AMA bots from profiles/bots.json to profiles/market_adapter_whitelist.json.
101
- # Existing entries are preserved; new entries enable AMA only and leave dynamicWeight and range scaling disabled.
102
- dexbot white
103
-
104
- # Add missing AMA bots with dynamicWeight enabled for newly generated entries
105
- dexbot white --dynamic-weight
106
-
107
- # Add missing AMA bots with range scaling (asymmetricBounds) enabled for newly generated entries
108
- dexbot white --asymmetric-bounds
109
-
110
- # Overwrite existing entry for a specific bot (implies overwrite for that key only; other bots unchanged)
111
- dexbot white --dynamic-weight --bot <botKey>
112
- dexbot white --asymmetric-bounds --bot <botKey>
113
-
114
- # Remove whitelist entries for bots no longer in profiles/bots.json
115
- dexbot white --prune
116
-
117
- ```
118
-
119
96
  ### Grid Divergence Audit
120
97
  **File:** `divergence-calc.ts`
121
98
  **Purpose:** Measure the "drift" between in-memory grid and disk state using RMS divergence metric.
@@ -363,7 +340,6 @@ The following scripts allow you to call `dexbot` commands directly from the `scr
363
340
  ### Analysis
364
341
  | Command | Purpose |
365
342
  |:---|:---|
366
- | `npm run market-adapter:whitelist` | Generate/update whitelist from AMA-configured bots |
367
343
  | `npm run market-adapter:fetch-cex-synthetic` | Fetch CEX synthetic data for market adapter |
368
344
  | `npm run analysis:derivatives` | Derivative analysis report |
369
345
  | `npm run analysis:tradingview` | TradingView-style chart export |
@@ -385,8 +361,10 @@ The following scripts allow you to call `dexbot` commands directly from the `scr
385
361
 
386
362
  ## 📈 CHART GENERATION
387
363
 
364
+ `dexbot tv` and `dexbot dw` share ONE fetch pipeline ([`chart_command.ts`](chart_command.ts)): identical target resolution, source routing, cached candle chunks, and temp-file handoff — only the renderer registration (`RENDERERS` table) differs.
365
+
388
366
  ### TradingView (`dexbot tv`)
389
- **File:** `tv.ts`
367
+ **File:** `tv.ts` (thin entry; shared pipeline: `chart_command.ts`)
390
368
  **Purpose:** One-step TradingView-style 1h chart for a bot (with AMA + order overlay), pool, or pair. Fetches candles in monthly Kibana chunks (pool-first with order-book fallback; `--feed` for MPA price-feed history), then renders via `analysis/tradingview/`. Bot charts pick up the order overlay from `profiles/orders/<botKey>.json` automatically.
391
369
  **Output:** `analysis/charts/tv_<bot|pool_<id>|<a>_<b>>_1h_<N>m.html` (`_feed` suffix for feed charts)
392
370
  ```bash
@@ -399,6 +377,21 @@ dexbot tv TOKENA/TOKENB --month 1 --chart analysis/charts/custom.html
399
377
  dexbot tv BTS/HONEST.USD --feed --month 1
400
378
  ```
401
379
 
380
+ ### Dynamic Weight (`dexbot dw`) — advanced
381
+ **File:** `dw.ts` (thin entry; shared pipeline: `chart_command.ts`)
382
+ **Purpose:** Identical one-step pipeline to `dexbot tv` (same targets, `--month`, `--feed/--pool/--book`, same cached monthly candle chunks) — the only difference is the renderer: it writes the dynamic-weight research chart via `analysis/analyze_dynamic_weight.ts` (AMA slope + Kalman blend, Hurst/PE regime gate) instead of a TradingView chart. For weight-tuning research, not general charting.
383
+ **Output:** `analysis/charts/dw_<bot|pool_<id>|<a>_<b>>_1h_<N>m.html` (`_feed` suffix for feed charts)
384
+ ```bash
385
+ # Bot chart (default: 3 months)
386
+ dexbot dw <bot>
387
+ # Pool or pair, custom window
388
+ dexbot dw 133 --month 6
389
+ dexbot dw TOKENA/TOKENB --month 1 --chart analysis/charts/custom.html
390
+ # MPA price-feed history instead of market candles (opt-in)
391
+ dexbot dw BTS/HONEST.USD --feed --month 1
392
+ ```
393
+ Research knobs (`--alpha`, `--gain`, `--dw`, `--lb`, `--clip`) stay on the analyzer itself — call `node dist/analysis/analyze_dynamic_weight.js` directly for parameter sweeps (see `analysis/README.md`).
394
+
402
395
  ### LP Chart
403
396
  **File:** `generate_lp_chart.ts`
404
397
  **Purpose:** Generate the standard uPlot LP chart output.
@@ -108,7 +108,7 @@ if [ "$REMAINING" -eq 0 ]; then
108
108
  log_info ""
109
109
  log_info "Next steps:"
110
110
  log_info "- Re-run \`dexbot bot\` to recreate general settings if needed"
111
- log_info "- Re-run \`npm run market-adapter:whitelist\` if your AMA bot set changed"
111
+ log_info "- Re-open \`dexbot bot\` → 6) Adapter if your AMA bot set changed"
112
112
  log_info "- Re-fit market profiles only if you want custom AMA presets again"
113
113
  else
114
114
  log_warning "Cleanup incomplete. Remaining settings files: $REMAINING"
@@ -1,15 +0,0 @@
1
- declare function isAmaGridPrice(value: any): boolean;
2
- declare function parseOptions(argv: string[]): {
3
- dynamicWeight: boolean;
4
- asymmetricBounds: boolean;
5
- prune: boolean;
6
- botKeys: string[];
7
- };
8
- declare function loadExistingWhitelist(): any;
9
- declare function buildWhitelist(bots: any, existingWhitelist?: any, options?: ReturnType<typeof parseOptions>): {
10
- whitelist: {
11
- [k: string]: any;
12
- };
13
- };
14
- export { isAmaGridPrice, parseOptions, loadExistingWhitelist, buildWhitelist };
15
- //# sourceMappingURL=generate_market_adapter_whitelist.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate_market_adapter_whitelist.d.ts","sourceRoot":"","sources":["../../scripts/generate_market_adapter_whitelist.ts"],"names":[],"mappings":"AAqBA,iBAAS,cAAc,CAAC,KAAK,EAAE,GAAG,WAGjC;AAED,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE;;;;;EAmDnC;AAED,iBAAS,qBAAqB,QAwB7B;AAED,iBAAS,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,iBAAiB,GAAE,GAAQ,EAAE,OAAO,GAAE,UAAU,CAAC,OAAO,YAAY,CAA8B;;;;EA6DpI;AAyBD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,CAAA"}
@@ -1,191 +0,0 @@
1
- import fs from 'node:fs';
2
- import { loadSettingsFile, resolveRawBotEntries, normalizeBotEntries } from '../modules/bot_settings.js';
3
- import { PATHS } from '../modules/paths.js';
4
- import { getStorage } from '../modules/storage/index.js';
5
- const { readJSON } = getStorage();
6
- import { getErrorMessage } from '../modules/utils/errors.js';
7
- import { pathToFileURL } from 'node:url';
8
- 'use strict';
9
- const BOTS_FILE = PATHS.PROFILES.BOTS_JSON;
10
- const WHITELIST_FILE = PATHS.PROFILES.MARKET_ADAPTER_WHITELIST_JSON();
11
- function loadNormalizedBots() {
12
- const { config } = loadSettingsFile(BOTS_FILE);
13
- const raw = resolveRawBotEntries(config);
14
- const normalized = normalizeBotEntries(raw);
15
- return normalized;
16
- }
17
- function isAmaGridPrice(value) {
18
- if (typeof value !== 'string')
19
- return false;
20
- return /^ama(?:[1-4])?$/i.test(value.trim());
21
- }
22
- function parseOptions(argv) {
23
- const dynamicWeightEnabled = argv.includes('--dynamic-weight=true') || argv.includes('--dynamic-weight') || argv.includes('--with-dynamic-weight');
24
- const dynamicWeightDisabled = argv.includes('--dynamic-weight=false') || argv.includes('--no-dynamic-weight');
25
- const asymmetricBoundsEnabled = argv.includes('--asymmetric-bounds=true') || argv.includes('--asymmetric-bounds') || argv.includes('--with-asymmetric-bounds');
26
- const asymmetricBoundsDisabled = argv.includes('--asymmetric-bounds=false') || argv.includes('--no-asymmetric-bounds');
27
- const pruneEnabled = argv.includes('--prune');
28
- const botKeys = [];
29
- for (let i = 0; i < argv.length; i++) {
30
- const arg = argv[i];
31
- let raw = null;
32
- let isBotFlag = false;
33
- if (arg === '--bot' || arg === '--bot-key' || arg === '--botKey') {
34
- isBotFlag = true;
35
- const next = argv[i + 1] ?? null;
36
- if (next && !next.startsWith('--')) {
37
- raw = next;
38
- i++;
39
- }
40
- else {
41
- throw new Error(`--bot requires a value: got '${next ?? ''}' (usage: --bot <botKey> or --bot=a,b)`);
42
- }
43
- }
44
- else if (arg.startsWith('--bot=')) {
45
- isBotFlag = true;
46
- raw = arg.slice('--bot='.length);
47
- if (!raw.trim())
48
- throw new Error(`--bot requires a value: got '${arg}' (usage: --bot=<botKey>)`);
49
- }
50
- else if (arg.startsWith('--bot-key=')) {
51
- isBotFlag = true;
52
- raw = arg.slice('--bot-key='.length);
53
- if (!raw.trim())
54
- throw new Error(`--bot-key requires a value: got '${arg}'`);
55
- }
56
- else if (arg.startsWith('--botKey=')) {
57
- isBotFlag = true;
58
- raw = arg.slice('--botKey='.length);
59
- if (!raw.trim())
60
- throw new Error(`--botKey requires a value: got '${arg}'`);
61
- }
62
- if (isBotFlag && raw !== null) {
63
- const parts = raw.split(',').map(s => s.trim()).filter(Boolean);
64
- if (parts.length === 0)
65
- throw new Error(`--bot requires a non-empty botKey (got '${raw}')`);
66
- // validate each key does not look like a flag
67
- for (const p of parts) {
68
- if (p.startsWith('--'))
69
- throw new Error(`--bot value looks like a flag: '${p}' (missing value for --bot?)`);
70
- }
71
- botKeys.push(...parts);
72
- }
73
- }
74
- return {
75
- dynamicWeight: dynamicWeightEnabled && !dynamicWeightDisabled,
76
- asymmetricBounds: asymmetricBoundsEnabled && !asymmetricBoundsDisabled,
77
- prune: pruneEnabled,
78
- botKeys,
79
- };
80
- }
81
- function loadExistingWhitelist() {
82
- if (!fs.existsSync(WHITELIST_FILE))
83
- return {};
84
- let json;
85
- try {
86
- json = readJSON(WHITELIST_FILE);
87
- }
88
- catch (err) {
89
- process.stderr.write(`Warning: ignoring malformed ${WHITELIST_FILE}: ${getErrorMessage(err)}\n`);
90
- return {};
91
- }
92
- const raw = json?.whitelist;
93
- const entries = {};
94
- if (Array.isArray(raw)) {
95
- for (const botKey of raw) {
96
- if (botKey)
97
- entries[String(botKey)] = { ama: true, dynamicWeight: false, asymmetricBounds: false };
98
- }
99
- }
100
- else if (raw && typeof raw === 'object') {
101
- for (const [botKey, entry] of Object.entries(raw)) {
102
- entries[String(botKey)] = entry;
103
- }
104
- }
105
- return entries;
106
- }
107
- function buildWhitelist(bots, existingWhitelist = {}, options = parseOptions(process.argv)) {
108
- const entries = new Map();
109
- for (const [botKey, entry] of Object.entries(existingWhitelist || {})) {
110
- entries.set(String(botKey), entry);
111
- }
112
- if (options.prune) {
113
- const configuredKeys = new Set();
114
- for (const bot of bots) {
115
- const botKey = bot.botKey;
116
- if (botKey)
117
- configuredKeys.add(String(botKey));
118
- }
119
- for (const key of entries.keys()) {
120
- if (!configuredKeys.has(key)) {
121
- process.stderr.write(`prune: removed stale whitelist entry '${key}'\n`);
122
- entries.delete(key);
123
- }
124
- }
125
- }
126
- for (const bot of bots) {
127
- const botKey = bot.botKey;
128
- if (!botKey || !isAmaGridPrice(bot?.gridPrice))
129
- continue;
130
- const key = String(botKey);
131
- const botKeys = options.botKeys ?? [];
132
- const isTargeted = botKeys.length > 0 && botKeys.includes(key);
133
- const isFilteredOut = botKeys.length > 0 && !isTargeted;
134
- if (isFilteredOut)
135
- continue;
136
- if (!entries.has(key)) {
137
- entries.set(key, {
138
- ama: true,
139
- dynamicWeight: options.dynamicWeight,
140
- asymmetricBounds: options.asymmetricBounds,
141
- });
142
- }
143
- else if (isTargeted) {
144
- // --bot implies overwrite for that key only
145
- const existing = entries.get(key) ?? {};
146
- entries.set(key, {
147
- ...existing,
148
- ama: true,
149
- dynamicWeight: options.dynamicWeight,
150
- asymmetricBounds: options.asymmetricBounds,
151
- });
152
- }
153
- }
154
- if (options.botKeys && options.botKeys.length > 0) {
155
- const configuredKeys = new Set(bots.map((b) => b?.botKey).filter(Boolean).map(String));
156
- for (const target of options.botKeys) {
157
- if (!configuredKeys.has(String(target))) {
158
- process.stderr.write(`Warning: --bot target '${target}' not found in ${BOTS_FILE} (no AMA bot matched; file written unchanged for that key)\n`);
159
- }
160
- else if (!bots.some((b) => String(b?.botKey) === String(target) && isAmaGridPrice(b?.gridPrice))) {
161
- process.stderr.write(`Warning: --bot target '${target}' has non-AMA gridPrice (whitelist unchanged for that key)\n`);
162
- }
163
- }
164
- }
165
- return {
166
- whitelist: Object.fromEntries([...entries.entries()].sort((a, b) => a[0].localeCompare(b[0]))),
167
- };
168
- }
169
- function main() {
170
- let options;
171
- try {
172
- options = parseOptions(process.argv);
173
- }
174
- catch (err) {
175
- process.stderr.write(`whitelist: ${getErrorMessage(err)}\n`);
176
- process.stderr.write(`Usage: dexbot white [--dynamic-weight|--no-dynamic-weight] [--asymmetric-bounds|--no-asymmetric-bounds] [--prune] [--bot <botKey>]\n`);
177
- process.exit(1);
178
- }
179
- const bots = loadNormalizedBots();
180
- const existingWhitelist = loadExistingWhitelist();
181
- const whitelist = buildWhitelist(bots, existingWhitelist, options);
182
- const output = JSON.stringify(whitelist, null, 2) + '\n';
183
- fs.writeFileSync(WHITELIST_FILE, output, 'utf8');
184
- const botCount = Object.keys(whitelist.whitelist).length;
185
- process.stdout.write(`Wrote ${WHITELIST_FILE} with ${botCount} ${botCount === 1 ? 'bot' : 'bots'}\n`);
186
- }
187
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
188
- main();
189
- }
190
- export { isAmaGridPrice, parseOptions, loadExistingWhitelist, buildWhitelist };
191
- //# sourceMappingURL=generate_market_adapter_whitelist.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate_market_adapter_whitelist.js","sourceRoot":"","sources":["../../scripts/generate_market_adapter_whitelist.ts"],"names":[],"mappings":"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"}