@tony01/astroneum 0.4.1-beta.2

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 (59) hide show
  1. package/CHANGELOG.md +237 -0
  2. package/LICENSE +21 -0
  3. package/README.md +198 -0
  4. package/dist/Indicator-BBI3L_lx.d.ts +1181 -0
  5. package/dist/ar-SA-AEPUSRMF.js +2 -0
  6. package/dist/astroneum.css +1 -0
  7. package/dist/chunk-2SN3RH42.js +2 -0
  8. package/dist/chunk-2YYGUSVX.js +3 -0
  9. package/dist/chunk-3GJSZFLM.js +2 -0
  10. package/dist/chunk-4YOLQ5DC.js +2 -0
  11. package/dist/chunk-I4YQBP2M.js +3 -0
  12. package/dist/chunk-OOMZRONH.js +35 -0
  13. package/dist/chunk-PV2GAINM.js +2 -0
  14. package/dist/chunk-SDXH2WAI.js +3 -0
  15. package/dist/chunk-YFPXTHZX.js +2 -0
  16. package/dist/chunk-YW3STIPY.js +653 -0
  17. package/dist/de-DE-4PR3NRQ7.js +2 -0
  18. package/dist/entries/alerts.d.ts +93 -0
  19. package/dist/entries/alerts.js +2 -0
  20. package/dist/entries/datafeeds/crypto.d.ts +65 -0
  21. package/dist/entries/datafeeds/crypto.js +2 -0
  22. package/dist/entries/datafeeds/polygon.d.ts +113 -0
  23. package/dist/entries/datafeeds/polygon.js +2 -0
  24. package/dist/entries/multichart.d.ts +96 -0
  25. package/dist/entries/multichart.js +2 -0
  26. package/dist/entries/portfolio.d.ts +55 -0
  27. package/dist/entries/portfolio.js +2 -0
  28. package/dist/entries/replay.d.ts +141 -0
  29. package/dist/entries/replay.js +2 -0
  30. package/dist/entries/script.d.ts +68 -0
  31. package/dist/entries/script.js +2 -0
  32. package/dist/entries/watchlist.d.ts +43 -0
  33. package/dist/entries/watchlist.js +2 -0
  34. package/dist/es-ES-HNDVPSLW.js +2 -0
  35. package/dist/fr-FR-Y7XWRGF2.js +2 -0
  36. package/dist/hi-IN-KEGIKIMV.js +2 -0
  37. package/dist/id-ID-QXDIUQUZ.js +2 -0
  38. package/dist/index.d.ts +1434 -0
  39. package/dist/index.js +2 -0
  40. package/dist/it-IT-UDTDFSRB.js +2 -0
  41. package/dist/ja-JP-NIODTBW3.js +2 -0
  42. package/dist/ko-KR-DQHPXKBA.js +2 -0
  43. package/dist/nl-NL-BB3ZHCXS.js +2 -0
  44. package/dist/pl-PL-I5MZDLFD.js +2 -0
  45. package/dist/pt-BR-MAMRTOYR.js +2 -0
  46. package/dist/ru-RU-F43D6B7G.js +2 -0
  47. package/dist/th-TH-KTFIUAD6.js +2 -0
  48. package/dist/tr-TR-WFTKJ22Y.js +2 -0
  49. package/dist/vi-VN-CD3WI2FQ.js +2 -0
  50. package/dist/zh-CN-Y2C6RSOI.js +3 -0
  51. package/docs/STRUCTURE.md +231 -0
  52. package/docs/TODO-DESIGN.md +261 -0
  53. package/docs/TODO.md +222 -0
  54. package/docs/api.md +528 -0
  55. package/docs/datafeed-guide.md +311 -0
  56. package/docs/design-astroneum.md +479 -0
  57. package/docs/plugin-development.md +565 -0
  58. package/docs/tv-functions-skill.md +706 -0
  59. package/package.json +147 -0
@@ -0,0 +1,706 @@
1
+ # TradingView Functions → Astroneum Mirror Map
2
+
3
+ > Source of truth for "which TradingView feature maps to what in Astroneum." Consult before building anything in `/astroneum`. Webhook + Pine + strategy-report sections are grounded in the v21 Pine source (`BTC H4 OP v21 WH+ LIVE`, title `CTC BB·SMMA H4 v2.9 + Webhook (Live-Ready)`).
4
+ >
5
+ > **Last verified against:** TradingView Super Chart (Jul 2026) + Pine v5.
6
+ > **Companion docs:** `docs/design-astroneum.md` (UX spec), `docs/webhook-payloads.md` (v14, stale — see §8).
7
+
8
+ ---
9
+
10
+ ## 1. Mirror status taxonomy
11
+
12
+ Every catalog row carries one of these six statuses. The status dictates what to do when the function is touched in `/astroneum`.
13
+
14
+ | Bucket | Meaning | Action |
15
+ |---|---|---|
16
+ | `widget-native` | TV widget provides it; Astroneum just doesn't disable it | Ensure widget config flag is `true`; do not rebuild |
17
+ | `native-chrome` | Astroneum rebuilds it in surrounding chrome | Build per `docs/design-astroneum.md` §5 |
18
+ | `api-bridged` | Existing backend API already mirrors it | Reuse; do not rebuild |
19
+ | `v1-in-scope` | Spec'd for v1 per `design-astroneum.md` §11 | Build now |
20
+ | `v1-deferred` | Explicitly out of scope per `design-astroneum.md` §12 | Do not build; list for v2 |
21
+ | `v2-future` | Not yet spec'd | Note only; no action |
22
+
23
+ ---
24
+
25
+ ## 2. Existing Astroneum API surface
26
+
27
+ Astroneum is a **SEPARATE project** from Trading-Bot-V2 (different repo: `github.com/kowito/astroneum` vs `github.com/Tony1185/trading-bot-v2.git`). The Astroneum demo app (`/opt/astroneum/demo/`, the `astroneum-demo-next` Next.js app) is charting-first and has a minimal API surface. Trading-Bot-V2's webhook/positions/orders APIs are NOT available to Astroneum.
28
+
29
+ ### Astroneum demo app API routes (api-bridged)
30
+
31
+ | Path / file | Role |
32
+ |---|---|
33
+ | `/opt/astroneum/demo/src/app/api/alerts/email/route.ts` | The only API route. Sends alert email notifications. |
34
+
35
+ ### Astroneum library modules (astroneum-native, not API routes)
36
+
37
+ These are client-side library modules from the `astroneum` npm package, not server API routes:
38
+
39
+ | Subpath | Role |
40
+ |---|---|
41
+ | `astroneum/alerts` | `AlertManager` — price alert creation and monitoring (client-side). |
42
+ | `astroneum/portfolio` | `PortfolioTracker` — position tracking and P&L (read-only display; not an execution path). |
43
+ | `astroneum/watchlist` | `WatchlistManager` — symbol watchlist with live prices. |
44
+ | `astroneum/datafeeds/crypto` | `createStandardCryptoDatafeed` + `BinanceAdapter` / `BitgetAdapter` / `OkxAdapter` — real-time crypto data. |
45
+
46
+ ### Trading-Bot-V2 API surface (SEPARATE project — NOT available to Astroneum)
47
+
48
+ The following are in the Trading-Bot-V2 project (`/root/Trading-Bot-V2/` or `/opt/trading-bot-v2/`) and are NOT importable by Astroneum. Listed here for reference only — if Astroneum needs equivalent functionality, build new API routes in `/opt/astroneum/demo/src/app/api/`:
49
+
50
+ | Trading-Bot-V2 path | Role | Astroneum equivalent |
51
+ |---|---|---|
52
+ | `src/app/api/webhooks/tradingview/route.ts` | Ingests TV `alert()` POSTs (5 actions). | None — Astroneum has no webhook ingestion. v21 events are reference-only (see §3.12). |
53
+ | `src/app/api/tv-positions/route.ts` | TV-reported positions. | None — use `astroneum/portfolio` `PortfolioTracker` for read-only display. |
54
+ | `src/app/api/orders/route.ts` | Order creation (PaperTradingEngine + RiskManager). | None — Astroneum is charting-first; build new if trading is needed. |
55
+ | `src/app/api/portfolio/route.ts` | Portfolio summary. | None — use `astroneum/portfolio` `PortfolioTracker`. |
56
+ | `src/app/api/integrations/tradingview/route.ts` | Webhook token management. | None — not applicable to Astroneum. |
57
+
58
+ ---
59
+
60
+ ## 3. TV feature catalog (exhaustive, function-level)
61
+
62
+ Row format: `| Function | TV behavior | Status | Pointer | Notes |`. Pointer = where Astroneum implements or will implement it. `—` = no pointer yet.
63
+
64
+ ### 3.1 Chart types
65
+
66
+ | Function | TV behavior | Status | Pointer | Notes |
67
+ |---|---|---|---|---|
68
+ | Candles | OHLC candle body + wick | `widget-native` | `style:"1"` in widget config | v21 uses candles |
69
+ | Hollow Candles | Body hollow on up | `widget-native` | `style:"9"` | |
70
+ | Heikin Ashi | HA-transformed candles | `widget-native` | `style:"8"` | |
71
+ | Line | Close-price line | `widget-native` | `style:"2"` | |
72
+ | Area | Line + fill | `widget-native` | `style:"3"` | |
73
+ | Baseline | Line vs baseline threshold | `widget-native` | `style:"10"` | |
74
+ | Renko | Price-brick, time-independent | `widget-native` | `style:"4"` | |
75
+ | Kagi | Line-break reversal | `widget-native` | `style:"5"` | |
76
+ | Point & Figure | X/O columns | `widget-native` | `style:"6"` | |
77
+ | Line Break | N-line reversal | `widget-native` | `style:"7"` | |
78
+ | Range | Range-bars | `widget-native` | `style:"12"` | |
79
+ | Chart-type selector | Top-bar dropdown | `native-chrome` | `src/components/astroneum/TopBar.tsx` | Mirrors TV top-bar |
80
+
81
+ ### 3.2 Timeframes
82
+
83
+ | Function | TV behavior | Status | Pointer | Notes |
84
+ |---|---|---|---|---|
85
+ | 1s, 1m, 5m, 15m, 30m, 1h, 4h, 1D, 1W, 1M | Standard resolutions | `widget-native` | `interval` param | v21 runs on `240` (4h) |
86
+ | Range bars | Price-range aggregation | `widget-native` | `interval="R"` | |
87
+ | Custom seconds/minutes | User-defined | `v1-deferred` | — | §12 |
88
+ | Timeframe selector | Top-bar buttons | `native-chrome` | `TopBar.tsx` | Hotkeys `1`-`9` (§8 of design) |
89
+
90
+ ### 3.3 Chart layouts / multi-chart
91
+
92
+ | Function | TV behavior | Status | Pointer | Notes |
93
+ |---|---|---|---|---|
94
+ | Single pane | One chart | `widget-native` | default | v1 ships single only |
95
+ | 2×1, 1×2, 2×2, 3×1, 3×2, 4×4 grids | Multi-pane | `v1-deferred` | — | §12; v2 rebuild |
96
+ | Sync crosshair across panes | Linked | `v1-deferred` | — | |
97
+ | Layout selector | Grid picker | `v1-deferred` | — | |
98
+
99
+ ### 3.4 Scales
100
+
101
+ | Function | TV behavior | Status | Pointer | Notes |
102
+ |---|---|---|---|---|
103
+ | Regular scale | Linear price | `widget-native` | | |
104
+ | Logarithmic | Log price | `widget-native` | | |
105
+ | Percentage | % from baseline | `widget-native` | | |
106
+ | Auto-scale | Fit-to-screen | `widget-native` | | |
107
+
108
+ ### 3.5 Compare / overlay / spread
109
+
110
+ | Function | TV behavior | Status | Pointer | Notes |
111
+ |---|---|---|---|---|
112
+ | Compare symbol | Overlay another ticker | `v1-deferred` | — | §12; widget supports internally |
113
+ | Spread chart | A−B / ratio | `v1-deferred` | — | |
114
+ | Same-scale overlay | Pin to existing axis | `v1-deferred` | — | |
115
+
116
+ ### 3.6 Built-in indicators (~40 key; 100+ total in TV)
117
+
118
+ v21 uses: BB, SMMA (RMA), SAR, ADX/DI, MACD, RSI, ATR, EMA(1D), Choppiness Index (custom), Volume MA. Status `widget-native` for all — added via `studies` array or the indicators menu.
119
+
120
+ | Indicator | TV behavior | Status | Pointer | v21 uses? |
121
+ |---|---|---|---|---|
122
+ | Moving Average (SMA) | `ta.sma` | `widget-native` | studies | no (uses SMMA=RMA) |
123
+ | Moving Average Exponential (EMA) | `ta.ema` | `widget-native` | studies | yes (1D macro filter) |
124
+ | Moving Average Weighted (WMA) | `ta.wma` | `widget-native` | studies | no |
125
+ | Moving Average Smoothed (RMA/SMMA) | `ta.rma` | `widget-native` | studies | yes (fast/slow trend) |
126
+ | Bollinger Bands | `ta.stdev` bands | `widget-native` | studies | yes |
127
+ | Bollinger Bands %B | % of band | `widget-native` | studies | no |
128
+ | Relative Strength Index (RSI) | `ta.rsi` | `widget-native` | studies | yes (mom decay) |
129
+ | MACD | `ta.macd` | `widget-native` | studies | yes (filter + mom) |
130
+ | Average True Range (ATR) | `ta.atr` | `widget-native` | studies | yes (trail SL) |
131
+ | Parabolic SAR | `ta.sar` | `widget-native` | studies | yes |
132
+ | Average Directional Index (ADX/DI) | `ta.dmi` | `widget-native` | studies | yes (decay + entry filter) |
133
+ | Stochastic | %K/%D | `widget-native` | studies | no |
134
+ | Stochastic RSI | Stoch of RSI | `widget-native` | studies | no |
135
+ | Commodity Channel Index (CCI) | `ta.cci` | `widget-native` | studies | no |
136
+ | Williams %R | `ta.wpr` | `widget-native` | studies | no |
137
+ | Money Flow Index (MFI) | `ta.mfi` | `widget-native` | studies | no |
138
+ | On-Balance Volume (OBV) | `ta.obv` | `widget-native` | studies | no |
139
+ | Volume | Volume bars | `widget-native` | studies | yes (vol-spike exit) |
140
+ | Volume MA | SMA of volume | `widget-native` | studies | yes (`ta.sma(volume,...)`) |
141
+ | Volume Profile (VPVR) | Price-volume histogram | `widget-native` | studies | no |
142
+ | VWAP | `ta.vwap` | `widget-native` | studies | no |
143
+ | Ichimoku Cloud | Tenken/Kijun/Span | `widget-native` | studies | no |
144
+ | Hull Moving Average | `ta.hma` | `widget-native` | studies | no |
145
+ | Donchian Channels | `ta.donchian` | `widget-native` | studies | no |
146
+ | Pivot Points High/Low | `ta.pivothigh`/`pivotlow` | `widget-native` | studies | yes (HH/LL detection) |
147
+ | Zig Zag | Swing marker | `widget-native` | studies | no |
148
+ | Elliott Wave | Manual annotation | `widget-native` | studies | no |
149
+ | Gann Box / Fan / Complex | Gann tools | `widget-native` | studies | no |
150
+ | Fibonacci Retracement | Fib levels | `widget-native` | studies | no (drawing tool used instead) |
151
+ | Choppiness Index | `math.log10`-based | `widget-native` | studies | yes (custom impl, regime filter) |
152
+ | Supertrend | ATR band | `widget-native` | studies | no |
153
+ | Keltner Channels | ATR bands | `widget-native` | studies | no |
154
+ | Williams Fractal | Swing highs/lows | `widget-native` | studies | no |
155
+ | Momentum | `ta.mom` | `widget-native` | studies | no |
156
+ | Rate of Change (ROC) | `ta.roc` | `widget-native` | studies | no |
157
+ | Awesome Oscillator | `ta.ao` | `widget-native` | studies | no |
158
+ | Accelerator Oscillator | AO of AO | `widget-native` | studies | no |
159
+ | Cumulative Volume Index | CVI | `widget-native` | studies | no |
160
+ | Advance/Decline Line | A/D | `widget-native` | studies | no |
161
+ | ... 60+ more | see TV indicators dialog | `widget-native` | studies | n/a |
162
+
163
+ ### 3.7 Pine custom indicators
164
+
165
+ | Function | TV behavior | Status | Pointer | Notes |
166
+ |---|---|---|---|---|
167
+ | Load Pine indicator | `Add to chart` from community | `widget-native` | | |
168
+ | Author Pine indicator | Pine Editor | `v1-deferred` | — | §12 (native Pine Editor out of scope) |
169
+
170
+ ### 3.8 Indicator templates
171
+
172
+ | Function | TV behavior | Status | Pointer | Notes |
173
+ |---|---|---|---|---|
174
+ | Save indicator template | Preset of inputs + style | `v1-deferred` | — | |
175
+ | Apply template | One-click | `v1-deferred` | — | |
176
+
177
+ ### 3.9 Indicator settings dialog
178
+
179
+ | Function | TV behavior | Status | Pointer | Notes |
180
+ |---|---|---|---|---|
181
+ | Inputs tab | Length, source, params | `v1-deferred` | — | Widget-provided when studies UI on |
182
+ | Style tab | Color, width, plot visibility | `v1-deferred` | — | |
183
+ | Visibility tab | Per-timeframe show/hide | `v1-deferred` | — | |
184
+
185
+ ### 3.10 Drawing tools (~50)
186
+
187
+ Astroneum ships a left vertical toolbar (`src/components/astroneum/LeftToolbar.tsx`) mirroring TV's drawing-tool dock. Most tools are `widget-native` when TV's side toolbar is shown; Astroneum v1 keeps TV's side toolbar visible (`hide_side_toolbar: false` in widget config — see §5) and re-implements the dock selector as `native-chrome`.
188
+
189
+ | Tool | TV behavior | Status | Pointer |
190
+ |---|---|---|---|
191
+ | Cursor / pointer | Default select | `native-chrome` | `LeftToolbar.tsx` |
192
+ | Trend line | Two-point line | `widget-native` | TV side toolbar |
193
+ | Horizontal line | Price level | `widget-native` | |
194
+ | Vertical line | Time marker | `widget-native` | |
195
+ | Fibonacci retracement | Fib levels | `widget-native` | |
196
+ | Fibonacci extension | Fib projection | `widget-native` | |
197
+ | Fibonacci time zones | Time fib | `widget-native` | |
198
+ | Fibonacci fan / arcs / spiral / channel | Fib variants | `widget-native` | |
199
+ | Gann box / fan / complex / squares | Gann tools | `widget-native` | |
200
+ | Rectangle | Box shape | `widget-native` | |
201
+ | Ellipse | Oval | `widget-native` | |
202
+ | Triangle / polygon / arrow | Shapes | `widget-native` | |
203
+ | Brush / bezier / freehand | Free draw | `widget-native` | |
204
+ | Text / note / label | Annotation | `widget-native` | |
205
+ | Measure | Range + % tool | `widget-native` | |
206
+ | Magnet mode | Snap to OHLC | `widget-native` | |
207
+ | Stay in drawing mode | Persist tool | `widget-native` | |
208
+ | Lock all drawings | Freeze | `widget-native` | |
209
+ | Hide all drawings | Toggle | `widget-native` | |
210
+ | Show/Hide price/coordinate fields | Inputs | `widget-native` | |
211
+ | Object tree | Layers panel | `v1-deferred` | — | §12 |
212
+ | Drawing settings popover | Stroke/color/magnet | `native-chrome` | `LeftToolbar.tsx` (hover popover) | |
213
+
214
+ ### 3.11 Alerts (general)
215
+
216
+ | Function | TV behavior | Status | Pointer | Notes |
217
+ |---|---|---|---|---|
218
+ | Price alert (crossing/greater/less) | Notify at price | `v1-deferred` | — | §12: button only in v1 |
219
+ | Indicator alert | Notify on indicator condition | `v1-deferred` | — | |
220
+ | Webhook alert | POST JSON to URL | `v2-future` | — | Trading-Bot-V2 has `/api/webhooks/tradingview`; Astroneum does NOT (separate project). See §3.12. Build new in `/opt/astroneum/demo/src/app/api/` if needed. |
221
+ | Alert dialog (condition/message/expiration/frequency) | Alert creator | `v1-deferred` | — | |
222
+ | Alert log/history | Past fires | `v1-deferred` | — | |
223
+ | Drag-to-set price line | Visual price alert | `v1-deferred` | — | |
224
+ | Trigger: once / once-per-bar-close / once-per-bar | Frequency modes | `api-bridged` | webhook handler | v21 uses `freq_once_per_bar_close` |
225
+
226
+ ### 3.12 Webhook alerts — grounded in v21 (the 25 events)
227
+
228
+ All 25 `alert()` calls in the v21 source. Action × side × stage × reason. The "Bot handler" column references **Trading-Bot-V2**'s `/api/webhooks/tradingview` route (in `/root/Trading-Bot-V2/`), NOT Astroneum. Astroneum is a separate project and has NO webhook ingestion — the v21 events are reference-only (per the v21 Pine source being a reference for this doc, not a strategy Astroneum runs). If Astroneum needs webhook ingestion in the future, build a new route in `/opt/astroneum/demo/src/app/api/`.
229
+
230
+ | # | Action | Side | Stage | Reason | Bot handler | Status |
231
+ |---|---|---|---|---|---|---|
232
+ | 1 | `OPEN` | `LONG` | `ENTRY` | `entry_long` | `TradeExecutor.executeTrade` (BUY) | `api-bridged` |
233
+ | 2 | `OPEN` | `SHORT` | `ENTRY` | `entry_short` | `TradeExecutor.executeTrade` (SELL) | `api-bridged` |
234
+ | 3 | `UPDATE_SL` | `LONG` | `EARLY_BE` | `early_be_activated` | `handleLegacyUpdateSl` (STOP_MARKET algo) | `api-bridged` |
235
+ | 4 | `UPDATE_SL` | `SHORT` | `EARLY_BE` | `early_be_activated` | `handleLegacyUpdateSl` | `api-bridged` |
236
+ | 5 | `UPDATE_SL` | `LONG` | `RR_UPGRADE` | `rr_upgrade` | `handleLegacyUpdateSl` | `api-bridged` |
237
+ | 6 | `UPDATE_SL` | `SHORT` | `RR_UPGRADE` | `rr_upgrade` | `handleLegacyUpdateSl` | `api-bridged` |
238
+ | 7 | `PARTIAL_CLOSE` | `LONG` | `TP1` | `tp1_hit` | `handleLegacyPartialClose` (MARKET reduceOnly) | `api-bridged` |
239
+ | 8 | `PARTIAL_CLOSE` | `SHORT` | `TP1` | `tp1_hit` | `handleLegacyPartialClose` | `api-bridged` |
240
+ | 9 | `PARTIAL_CLOSE` | `LONG` | `TP2` | `tp2_hit` | `handleLegacyPartialClose` (+ TP2 SL upgrade) | `api-bridged` |
241
+ | 10 | `PARTIAL_CLOSE` | `SHORT` | `TP2` | `tp2_hit` | `handleLegacyPartialClose` | `api-bridged` |
242
+ | 11 | `PARTIAL_CLOSE` | `LONG` | `PARTIAL_TP` | `partial_tp` | `handleLegacyPartialClose` | `api-bridged` |
243
+ | 12 | `PARTIAL_CLOSE` | `SHORT` | `PARTIAL_TP` | `partial_tp` | `handleLegacyPartialClose` | `api-bridged` |
244
+ | 13 | `CLOSE` | `LONG` | `PROFIT_LOCK` | `profit_lock` | `handleClose` (full MARKET close) | `api-bridged` |
245
+ | 14 | `CLOSE` | `SHORT` | `PROFIT_LOCK` | `profit_lock` | `handleClose` | `api-bridged` |
246
+ | 15 | `CLOSE` | `LONG` | `ADX_DECAY` | `adx_decay` | `handleClose` | `api-bridged` |
247
+ | 16 | `CLOSE` | `SHORT` | `ADX_DECAY` | `adx_decay` | `handleClose` | `api-bridged` |
248
+ | 17 | `CLOSE` | `LONG` | `TREND_FADE` | `trend_fade` | `handleClose` | `api-bridged` |
249
+ | 18 | `CLOSE` | `SHORT` | `TREND_FADE` | `trend_fade` | `handleClose` | `api-bridged` |
250
+ | 19 | `CLOSE` | `LONG` | `PRE_SL_PROTECT` | `preSLReasonLong` (dynamic) | `handleClose` | `api-bridged` |
251
+ | 20 | `CLOSE` | `SHORT` | `PRE_SL_PROTECT` | `preSLReasonShort` (dynamic) | `handleClose` | `api-bridged` |
252
+ | 21 | `CLOSE` | `LONG` | `TP_FINAL` | `tp_final_hit` | `handleClose` | `api-bridged` |
253
+ | 22 | `CLOSE` | `SHORT` | `TP_FINAL` | `tp_final_hit` | `handleClose` | `api-bridged` |
254
+ | 23 | `CLOSE` | `LONG` | `TP1_FINAL` | `tp1_final_hit` | `handleClose` | `api-bridged` |
255
+ | 24 | `CLOSE` | `SHORT` | `TP1_FINAL` | `tp1_final_hit` | `handleClose` | `api-bridged` |
256
+ | 25 | `CLOSE` | `LONG`/`SHORT` | `SL_EXIT` | `reasonTag` (dynamic) | `handleClose` (SL hit via `strategy.exit`) | `api-bridged` |
257
+
258
+ **v14 → v21 deltas** (stages new in v21, missing from `docs/webhook-payloads.md`): `RR_UPGRADE`, `PROFIT_LOCK`, `ADX_DECAY`, `TREND_FADE`, `PRE_SL_PROTECT`, `TP1_FINAL`. The v14 doc covers `OPEN`, `UPDATE_SL` (only `EARLY_BE`), `PARTIAL_CLOSE` (`TP1`/`TP2`/`PARTIAL_TP`), `CLOSE` (only `SL_EXIT`/`TP_FINAL`). See §8.
259
+
260
+ ### 3.13 Pine Script editor
261
+
262
+ | Function | TV behavior | Status | Pointer | Notes |
263
+ |---|---|---|---|---|
264
+ | Editor pane | Code editing | `v1-deferred` | — | §12; widget-provided only |
265
+ | Compile / Add to chart | `Cmd-S` | `v1-deferred` | — | |
266
+ | Save / version | Script library | `v1-deferred` | — | |
267
+ | Console | `log.info()` output | `v1-deferred` | — | |
268
+
269
+ ### 3.14 Pine Script functions — function-level reference
270
+
271
+ Signatures + whether v21 uses it. Status: `widget-native` (TV runtime) for all; Astroneum does not host a Pine runtime.
272
+
273
+ #### `strategy.*` (strategy context)
274
+
275
+ | Function | Signature (abbrev.) | v21? | Notes |
276
+ |---|---|---|---|
277
+ | `strategy()` | `strategy(title, shorttitle, overlay, initial_capital, currency, default_qty_type, default_qty_value, commission_type, commission_value, slippage, pyramiding, max_bars_back, calc_on_order_fills, process_orders_on_close, margin_long, margin_short)` | yes | v21: `initial_capital=1000`, `commission=0.05%`, `slippage=3`, `pyramiding=1`, `margin=20` (5x), `process_orders_on_close=true` |
278
+ | `strategy.entry` | `strategy.entry(id, direction, qty, limit, stop, comment, alert_message)` | yes | Entries |
279
+ | `strategy.exit` | `strategy.exit(id, from_id, qty, qty_percent, profit, limit, loss, stop, comment, alert_message)` | yes | SL exits |
280
+ | `strategy.close` | `strategy.close(id, qty, qty_percent, comment, comment_profit, comment_loss, alert_message)` | yes | 15 calls |
281
+ | `strategy.cancel` | `strategy.cancel(id)` | yes | |
282
+ | `strategy.close_all` | `strategy.close_all(comment, alert_message)` | no | |
283
+ | `strategy.entry_price` | `strategy.entry_price` | no | v21 uses `strategy.position_avg_price` |
284
+ | `strategy.position_size` | `strategy.position_size` | yes | |
285
+ | `strategy.position_avg_price` | `strategy.position_avg_price` | yes | |
286
+ | `strategy.equity` | `strategy.equity` | yes | |
287
+ | `strategy.netprofit` | `strategy.netprofit` | yes | |
288
+ | `strategy.grossprofit` | `strategy.grossprofit` | yes | |
289
+ | `strategy.grossloss` | `strategy.grossloss` | yes | |
290
+ | `strategy.initial_capital` | `strategy.initial_capital` | yes | |
291
+ | `strategy.openprofit` | `strategy.openprofit` | no | |
292
+ | `strategy.wintrades` | `strategy.wintrades` | yes | |
293
+ | `strategy.losstrades` | `strategy.losstrades` | no | |
294
+ | `strategy.closedtrades` | `strategy.closedtrades` | yes | |
295
+ | `strategy.closedtrades.profit(n)` | `.profit(index)` | yes | |
296
+ | `strategy.closedtrades.entry_time(n)` | `.entry_time` | no | |
297
+ | `strategy.closedtrades.exit_time(n)` | `.exit_time` | no | |
298
+ | `strategy.closedtrades.entry_price(n)` | `.entry_price` | no | |
299
+ | `strategy.closedtrades.exit_price(n)` | `.exit_price` | no | |
300
+ | `strategy.closedtrades.max_drawdown(n)` | `.max_drawdown` | no | |
301
+ | `strategy.closedtrades.runup(n)` | `.runup` | no | |
302
+ | `strategy.closedtrades.size` | `.size` | no | |
303
+ | `strategy.long` | enum | yes | |
304
+ | `strategy.short` | enum | yes | |
305
+ | `strategy.fixed` | enum (qty type) | yes | |
306
+ | `strategy.cash` | enum | no | |
307
+ | `strategy.commission.percent` | enum | yes | |
308
+ | `strategy.commission.cash_per_contract` | enum | no | |
309
+ | `strategy.commission.cash_per_order` | enum | no | |
310
+ | `strategy.averaging` | enum (position sizing) | no | |
311
+
312
+ #### `ta.*` (technical analysis)
313
+
314
+ | Function | v21? | Notes |
315
+ |---|---|---|
316
+ | `ta.sma(src, len)` | yes | Volume MA |
317
+ | `ta.ema(src, len)` | yes | 1D macro filter |
318
+ | `ta.wma(src, len)` | no | |
319
+ | `ta.rma(src, len)` | yes | SMMA fast/slow |
320
+ | `ta.hma(src, len)` | no | |
321
+ | `ta.vwma(src, len)` | no | |
322
+ | `ta.alma(src, len, off, sig)` | no | |
323
+ | `ta.swma(src)` | no | |
324
+ | `ta.atr(len)` | yes | Trail SL |
325
+ | `ta.tr` | no | |
326
+ | `ta.highest(src, len)` | yes | CI + equity peak |
327
+ | `ta.lowest(src, len)` | yes | CI |
328
+ | `ta.highestbars(src, len)` | no | |
329
+ | `ta.lowestbars(src, len)` | no | |
330
+ | `ta.pivothigh(left, right)` | yes | HH/LL detection |
331
+ | `ta.pivotlow(left, right)` | yes | |
332
+ | `ta.stdev(src, len)` | yes | BB |
333
+ | `ta.dev(src, len)` | no | |
334
+ | `ta.variance(src, len)` | no | |
335
+ | `ta.sar(start, inc, max)` | yes | |
336
+ | `ta.dmi(len, adxlen)` | yes | Decay + entry filter |
337
+ | `ta.macd(src, fast, slow, sig)` | yes | Filter + mom |
338
+ | `ta.rsi(src, len)` | yes | Mom decay |
339
+ | `ta.crossover(a, b)` | yes | |
340
+ | `ta.crossunder(a, b)` | yes | |
341
+ | `ta.cross(a, b)` | no | |
342
+ | `ta.sum(src, len)` | yes | CI ATR sum |
343
+ | `ta.cum(src)` | no | |
344
+ | `ta.mom(src, len)` | no | |
345
+ | `ta.roc(src, len)` | no | |
346
+ | `ta.tsi(src, r, s)` | no | |
347
+ | `ta.cci(src, len)` | no | |
348
+ | `ta.mfi(src, len)` | no | |
349
+ | `ta.wpr(len)` | no | |
350
+ | `ta.obv` | no | |
351
+ | `ta.vwap` | no | |
352
+ | `ta.vwap_custom` | no | |
353
+ | `ta.supertrend(factor, atrlen)` | no | |
354
+ | `ta.kc(mult, len, atrlen)` | no | |
355
+ | `ta.donchian(len)` | no | |
356
+ | `ta.bb(src, len, mult)` | no (v21 builds BB inline) | |
357
+ | `ta.bbw(src, len, mult)` | no | |
358
+ | `ta.ao(src)` | no | |
359
+ | `ta.ac` | no | |
360
+ | `ta.linreg(src, len, offset)` | no | |
361
+ | `ta.median(src, len)` | no | |
362
+ | `ta.mode(src, len)` | no | |
363
+ | `ta.range(src, len)` | no | |
364
+ | `ta.change(src, len)` | no | |
365
+ | `ta.falling(src, len)` | no | |
366
+ | `ta.rising(src, len)` | no | |
367
+ | `ta.barssince(cond)` | no | |
368
+ | `ta.valuewhen(cond, src, occ)` | no | |
369
+ | `ta.max_bars_back(src, len)` | no | |
370
+
371
+ #### `request.*`
372
+
373
+ | Function | v21? | Notes |
374
+ |---|---|---|
375
+ | `request.security(sym, tf, expr, gaps, lookahead)` | yes | 1D EMA, `lookahead_off` (no-bias fix) |
376
+ | `request.security_lower_tf(sym, tf, expr)` | no | |
377
+ | `request.seed(sym, prop)` | no | |
378
+ | `request.quandl(ticker)` | no | |
379
+ | `request.financial(sym, fin_id, period)` | no | |
380
+ | `request.splits(sym)` | no | |
381
+ | `request.dividends(sym)` | no | |
382
+ | `request.bars_count()` | no | |
383
+
384
+ #### `input.*`
385
+
386
+ | Function | v21? | Notes |
387
+ |---|---|---|
388
+ | `input.float(def, title, group, minval, maxval, step, tooltip)` | yes | Many |
389
+ | `input.int(def, title, group, minval, maxval)` | no | |
390
+ | `input.string(def, title, group)` | yes | `i_whAccountId`, `i_whStrategy` |
391
+ | `input.bool(def, title, group, tooltip)` | yes | |
392
+ | `input.color(def, title)` | no | |
393
+ | `input.source(def, title)` | no | |
394
+ | `input.timeframe(def, title)` | no | |
395
+ | `input.symbol(def, title)` | no | |
396
+ | `input.session(def, title)` | no | |
397
+ | `input.text_area(def, title)` | no | |
398
+ | `input.price(def, title)` | no | |
399
+ | `input.time(def, title)` | no | |
400
+ | `input.enum(def, title)` | no | |
401
+
402
+ #### `table.*`
403
+
404
+ | Function | v21? | Notes |
405
+ |---|---|---|
406
+ | `table.new(pos, columns, rows, ...)` | yes | Strategy dashboard |
407
+ | `table.cell(t, col, row, text, ...)` | yes | 38+ rows (§3.16) |
408
+ | `table.merge_cells(t, start_col, start_row, end_col, end_row)` | no | |
409
+ | `table.delete(t)` | no | |
410
+ | `table.clear(t, start_col, start_row, end_col, end_row)` | no | |
411
+
412
+ #### Drawing primitives (`label.*`, `line.*`, `box.*`, `plot.*`, `fill`, `hline`, `bgcolor`, `barcolor`)
413
+
414
+ | Function | v21? | Notes |
415
+ |---|---|---|
416
+ | `plot(src, title, color, linewidth, style, ...)` | no (strategy, not indicator) | |
417
+ | `plotshape`, `plotchar`, `plotcandle`, `plotbar` | no | |
418
+ | `fill(h1, h2, color)` | no | |
419
+ | `hline(price, title, color, linestyle, linewidth)` | no | |
420
+ | `bgcolor(color)` | no | |
421
+ | `barcolor(color)` | no | |
422
+ | `label.new(...)`, `label.set_*`, `label.copy`, `label.delete` | no | v21 uses `table.cell` for all display |
423
+ | `line.new(...)`, `line.set_*` | no | |
424
+ | `box.new(...)`, `box.set_*` | no | |
425
+
426
+ #### `array.*`, `matrix.*`, `map.*`, `log.*`, `math.*`, `str.*`, `color.*`
427
+
428
+ | Function | v21? | Notes |
429
+ |---|---|---|
430
+ | `array.new_*`, `array.push`, `array.get`, `array.pop`, `array.size`, `array.first`, `array.last`, `array.sort`, `array.includes`, `array.slice`, ... | no | |
431
+ | `matrix.new_*`, `matrix.get`, `matrix.set`, ... | no | |
432
+ | `map.new<*>`, `map.put`, `map.get`, `map.remove`, `map.keys`, `map.values` | no | |
433
+ | `log.info`, `log.warning`, `log.error` | no | |
434
+ | `math.sum`, `math.log10`, `math.round`, `math.abs` | yes | CI + dashboard |
435
+ | `math.max`, `math.min`, `math.avg`, `math.pow`, `math.sqrt`, `math.floor`, `math.ceil`, `math.sign`, `math.exp`, `math.log`, `math.sin`, `math.cos`, ... | partial (`math.abs` etc.) | |
436
+ | `str.tostring(val, fmt)`, `str.format(...)`, `str.contains`, `str.split`, `str.replace`, `str.length`, `str.upper`/`lower` | yes (`tostring`, `format`) | Dashboard formatting |
437
+ | `color.new(c, transparency)`, `color.rgb(r,g,b,t)`, `color.from_gradient`, `color.mix` | yes (`color.new`) | Dashboard colors |
438
+
439
+ #### Built-in vars
440
+
441
+ | Var | v21? | Notes |
442
+ |---|---|---|
443
+ | `open`, `high`, `low`, `close`, `volume`, `time`, `time_close`, `bar_index`, `last_bar_index`, `n`, `barstate.*` | yes (`close`, `high`, `low`, `volume`, `time`, `bar_index`) | |
444
+ | `syminfo.ticker`, `syminfo.prefix`, `syminfo.tickerid`, `syminfo.currency`, `syminfo.basecurrency`, `syminfo.pointvalue`, `syminfo.mintick`, `syminfo.type` | yes (`ticker`, `prefix`, `tickerid`) | Payload envelope |
445
+ | `timeframe.period`, `timeframe.isintraday`, `timeframe.isdaily`, `timeframe.isweekly`, `timeframe.ismonthly`, `timeframe.multiplier` | yes (`period`) | Payload envelope |
446
+ | `session.ispremarket`, `session.ismarket`, `session.ispostmarket`, `session.isclose` | no | |
447
+ | `os.*` (now, later, context, fulltime) | no | |
448
+
449
+ ### 3.15 Strategy Tester
450
+
451
+ | Function | TV behavior | Status | Pointer | Notes |
452
+ |---|---|---|---|---|
453
+ | Backtest engine | Replays trades on history | `widget-native` | | v21 is a `strategy()` — runs in tester |
454
+ | Performance summary | Net profit, PF, expected payoff, B&H, drawdown, sharpe, sortino | `v1-deferred` | — | §12; widget-provided |
455
+ | Trade list | Per-trade entry/exit/P&L | `v1-deferred` | — | |
456
+ | Equity curve | Equity over time | `v1-deferred` | — | |
457
+ | Drawdown curve | DD over time | `v1-deferred` | — | |
458
+ | Trade markers on chart | Arrows on entry/exit | `widget-native` | | |
459
+ | Strategy properties | Commission, slippage, capital, sizing | `widget-native` | | v21 sets these in `strategy()` |
460
+ | Currency conversion | Convert to display ccy | `v1-deferred` | — | |
461
+
462
+ ### 3.16 Strategy report — v21 on-chart dashboard (38 rows)
463
+
464
+ The v21 strategy emits a `table.new` overlay with 38 rows. This is the strategy's self-report. Astroneum's Trading Panel tab could surface these natively (post-v1). For v1, the table renders inside the widget.
465
+
466
+ | Row | Label | Source (v21) | Mirror status |
467
+ |---|---|---|---|
468
+ | 0 | Title / ticker | `strategy.title` + `syminfo.ticker` | `widget-native` |
469
+ | 1 | Repaint Check | `sameBarTradeCount` (computed) | `widget-native` |
470
+ | 2 | Net Profit | `strategy.netprofit` / `strategy.initial_capital * 100` | `widget-native` |
471
+ | 3 | Win Rate | `strategy.wintrades` / `strategy.closedtrades * 100` | `widget-native` |
472
+ | 4 | Current DD | `currentDD` (computed from `ta.highest(strategy.equity, 500)`) | `widget-native` |
473
+ | 5 | Slippage Sim | `i_useSlippage` / `i_slippagePct` | `widget-native` |
474
+ | 6 | Kelly Size | `kellySize` (computed, `i_kellyFrac`) | `widget-native` |
475
+ | 7 | Regime (CI) | `ciVal` vs `i_ciThresh` | `widget-native` |
476
+ | 8 | 1D EMA Macro | `ema1D` via `request.security(...,"1D",...)` | `widget-native` |
477
+ | 9 | Final Size | `finalSizeLong`/`Short` | `widget-native` |
478
+ | 10 | Next Qty | `qtyLong`/`qtyShort` | `widget-native` |
479
+ | 11 | Position | `strategy.position_size` sign → LONG/SHORT/FLAT | `widget-native` |
480
+ | 12 | Bars In Trade | `barsInTrade` (computed) | `widget-native` |
481
+ | 13 | Post-Loss CD | `inPostLossCD`/`postLossCDCount` | `widget-native` |
482
+ | 14 | TP Stage 1 | `i_useTP1`/`i_tp1Pct`/`i_tp1Qty` | `widget-native` |
483
+ | 15 | TP Stage 2 | `i_useTP2`/`i_tp2Pct`/`i_tp2Qty` | `widget-native` |
484
+ | 16 | TP Final | `i_useTPFinal`/`i_tpFinalPct` | `widget-native` |
485
+ | 17 | TP1 Status | `tp1LongDone`/`tp1ShortDone` | `widget-native` |
486
+ | 18 | TP2 Status | `tp2LongDone`/`tp2ShortDone` | `widget-native` |
487
+ | 19 | Trail SL | `i_useTrailSL` + `i_trailMult*`/`i_trailATR2` | `widget-native` |
488
+ | 20 | Early BE | `i_useEarlyBE`/`earlyBEActivated` | `widget-native` |
489
+ | 21 | Profit Lock | `i_useProfitLock`/`plActive`/`drawdownFromPeak` | `widget-native` |
490
+ | 22 | SAR | `sarBull` (from `ta.sar`) | `widget-native` |
491
+ | 23 | SMMA Trend | `aboveMA` (close vs `ta.rma` slow) | `widget-native` |
492
+ | 24 | BB Position | close vs `bbUpper`/`bbLower` | `widget-native` |
493
+ | 25 | Profit Factor | `strategy.grossprofit` / `abs(strategy.grossloss)` | `widget-native` |
494
+ | 26 | Avg Trade $ | `strategy.netprofit` / `strategy.closedtrades` | `widget-native` |
495
+ | 27 | Profit / Peak R | `currentProfitR`/`peakProfitR` (R-multiples) | `widget-native` |
496
+ | 28 | SL Distance | `(close - slNow)/close * 100` | `widget-native` |
497
+ | 29 | Entry Gate | `inPause`/`pauseCount` | `widget-native` |
498
+ | 30 | ADX L-Filter | `adxLongOK`/`adxEntry`/`i_minADXLong` | `widget-native` |
499
+ | 31 | ADX S-Filter | `adxShortOK`/`i_minADXShort` | `widget-native` |
500
+ | 32 | MACD L-Filter | `macdLongOK`/`macdHist` | `widget-native` |
501
+ | 33 | MACD S-Filter | `macdShortOK` | `widget-native` |
502
+ | 34 | Pre-SL Protect section | section header | `widget-native` |
503
+ | 35 | MomDecay | `momDecayExitLong/Short`/`momRSI`/`i_momDecayMode` | `widget-native` |
504
+ | 36 | CandleRev | `candleRevExitLong/Short` | `widget-native` |
505
+ | 37 | VolSpike | `volSpikeExitLong/Short`/`volMultDisp` | `widget-native` |
506
+ | 38 | PreSL Status | `preSLExitLong/Short` | `widget-native` |
507
+
508
+ ### 3.17 Watchlists
509
+
510
+ | Function | TV behavior | Status | Pointer | Notes |
511
+ |---|---|---|---|---|
512
+ | Multiple watchlists | Tabs of lists | `native-chrome` | `RightRail.tsx` / `Watchlist.tsx` | |
513
+ | Add/remove symbol | Edit list | `native-chrome` | `Watchlist.tsx` | |
514
+ | Reorder | Drag rows | `native-chrome` | | |
515
+ | Details panel | OHLC + P&L + description | `native-chrome` | `RightRail.tsx` | Uses the demo app's own state (NOT `useTradingStore` — that's Trading-Bot-V2) |
516
+ | Highlight selected | Active row | `native-chrome` | | 2px accent left-edge |
517
+
518
+ ### 3.18 Screener
519
+
520
+ | Function | TV behavior | Status | Pointer | Notes |
521
+ |---|---|---|---|---|
522
+ | Stock screener | Filter stocks | `v1-deferred` | — | §12; separate product |
523
+ | Crypto screener | Filter coins | `v1-deferred` | — | |
524
+ | Forex / ETF screener | Filter | `v1-deferred` | — | |
525
+ | Filter conditions | Metric rules | `v1-deferred` | — | |
526
+ | Presets | Saved filters | `v1-deferred` | — | |
527
+
528
+ ### 3.19 Markets
529
+
530
+ | Function | TV behavior | Status | Pointer | Notes |
531
+ |---|---|---|---|---|
532
+ | Heat maps | Treemap by cap | `v1-deferred` | — | §12 |
533
+ | Top gainers/losers | Movers | `v1-deferred` | — | |
534
+ | Sector performance | Heatmap | `v1-deferred` | — | |
535
+ | Economic calendar | Events | `v1-deferred` | — | |
536
+ | Earnings/dividends/splits calendars | Events | `v1-deferred` | — | |
537
+ | News feed | Headlines | `v1-deferred` | — | |
538
+ | Ideas / social | User content | `v1-deferred` | — | |
539
+
540
+ ### 3.20 Trading panel
541
+
542
+ | Function | TV behavior | Status | Pointer | Notes |
543
+ |---|---|---|---|---|
544
+ | Paper trading | Simulated account | `v1-deferred` | — | §12; Astroneum is charting-first, no trading in v1 |
545
+ | Broker connections | OAuth brokers | `v1-deferred` | — | §12 |
546
+ | Order ticket (market/limit/stop/stop-limit) | Place order | `v1-deferred` | — | Astroneum has no `/api/orders`; build new in `/opt/astroneum/demo/src/app/api/` if needed. Do NOT reuse Trading-Bot-V2's `OrderPanel`. |
547
+ | Positions list | Open positions | `v1-deferred` | — | Use `astroneum/portfolio` `PortfolioTracker` for read-only display. Do NOT reuse Trading-Bot-V2's `OpenPositions` or `/api/tv-positions`. |
548
+ | Orders list | Working orders | `v1-deferred` | — | Astroneum has no orders API; build new if needed. |
549
+ | History | Filled/closed | `v1-deferred` | — | Build new in `/opt/astroneum/demo/src/app/api/` if needed. |
550
+ | DOM / depth of market | L2 ladder | `v1-deferred` | — | §12; library supports it, APP defers surface. |
551
+ | On-chart order dragging | Drag SL/TP | `v1-deferred` | — | §12 |
552
+ | Account summary | Balance/equity/margin | `v1-deferred` | — | Use `astroneum/portfolio` `PortfolioTracker`. Do NOT use Trading-Bot-V2's `/api/portfolio`. |
553
+
554
+ ### 3.21 Replay
555
+
556
+ | Function | TV behavior | Status | Pointer | Notes |
557
+ |---|---|---|---|---|
558
+ | Bar replay | Step back/forward | `widget-native` | | |
559
+ | Autoplay | Auto-step | `widget-native` | | |
560
+ | Speed control | ms delay | `widget-native` | | |
561
+ | Replay from date | Start point | `widget-native` | | |
562
+
563
+ ### 3.22 Layouts & templates
564
+
565
+ | Function | TV behavior | Status | Pointer | Notes |
566
+ |---|---|---|---|---|
567
+ | Save layout | Chart state | `v1-deferred` | — | v2 |
568
+ | Load layout | Restore | `v1-deferred` | — | |
569
+ | Chart templates | Indicator + settings preset | `v1-deferred` | — | |
570
+
571
+ ### 3.23 Search
572
+
573
+ | Function | TV behavior | Status | Pointer | Notes |
574
+ |---|---|---|---|---|
575
+ | Symbol search | Ticker picker | `native-chrome` | `SymbolSearch.tsx` | `/` hotkey, command-palette style |
576
+ | TV search (everything) | Global search | `v1-deferred` | — | |
577
+ | Command palette | App-level actions | `native-chrome` | build in `/opt/astroneum/demo/src/app/_components/` | `Cmd/Ctrl-K`. Do NOT inherit from CryptoBot — separate project. |
578
+
579
+ ---
580
+
581
+ ## 4. Webhook payload schema (`f_buildPayload`)
582
+
583
+ Source: v21 Pine source. Single envelope; one `alert()` call per event. All events use `alert.freq_once_per_bar_close`.
584
+
585
+ ### Fields (always present)
586
+
587
+ | Field | Type | Source | Notes |
588
+ |---|---|---|---|
589
+ | `action` | string | arg | `OPEN` / `UPDATE_SL` / `PARTIAL_CLOSE` / `CLOSE` |
590
+ | `side` | string | arg | `LONG` / `SHORT` |
591
+ | `stage` | string | arg | `ENTRY` / `EARLY_BE` / `RR_UPGRADE` / `TP1` / `TP2` / `PARTIAL_TP` / `PROFIT_LOCK` / `ADX_DECAY` / `TREND_FADE` / `PRE_SL_PROTECT` / `TP_FINAL` / `TP1_FINAL` / `SL_EXIT` |
592
+ | `qty_closed` | number | arg | `#.########` (qty closed in this event) |
593
+ | `qty_pct` | number | arg | `#.##` (percent of remaining) |
594
+ | `remaining_pct` | number | arg | `#.##` (percent of entry remaining after) |
595
+ | `remaining_qty` | number | `wh_remainingQty` | `#.########` |
596
+ | `entry_qty` | number | `wh_entryQty` | `#.########` |
597
+ | `entry_price` | number | `wh_entryPrice` | `#.########` |
598
+ | `price` | number | `close` | `#.########` (current close) |
599
+ | `new_sl` | number | arg or `0.0` | `#.########` (only `UPDATE_SL` sets real value) |
600
+ | `size_pct` | number | `wh_size_pct` | `#.####` |
601
+ | `leverage` | int | `i_maxLeverage` | no formatting |
602
+ | `reason` | string | arg | human-readable trigger |
603
+ | `bar_time` | int | `time` | unix ms |
604
+ | `bar_index` | int | `bar_index` | |
605
+
606
+ ### Fields (conditional on `i_whEnvelope=true`)
607
+
608
+ | Field | Type | Source | Notes |
609
+ |---|---|---|---|
610
+ | `strategy` | string | `i_whStrategy` | default `BTC_H4_v28` |
611
+ | `account` | string | `i_whAccountId` | default `acct_main` |
612
+ | `symbol` | string | `syminfo.ticker` | e.g. `BTCUSD` |
613
+ | `exchange` | string | `syminfo.prefix` | e.g. `INDEX` |
614
+ | `interval` | string | `timeframe.period` | e.g. `240` |
615
+ | `position_id` | string | `wh_positionId` | `L_<barTime>_<barIdx>_<n>` or `S_...` |
616
+
617
+ ### Wire format
618
+
619
+ `POST /api/webhooks/tradingview?token=<webhook.token>` with body = the JSON string produced by `f_buildPayload`. The `{{strategy.order.alert_message}}` placeholder in the TV alert dialog is filled by TV with this string. The bot parses the JSON, normalizes action/symbol (strip `.P`), and dispatches.
620
+
621
+ > **Project separation:** This wire format and the `/api/webhooks/tradingview` route belong to **Trading-Bot-V2** (`/root/Trading-Bot-V2/`), NOT Astroneum. Astroneum (`/opt/astroneum/`) has no webhook ingestion. The schema is documented here as reference for the v21 Pine source; if Astroneum needs webhook ingestion, build a new route in `/opt/astroneum/demo/src/app/api/`.
622
+
623
+ ---
624
+
625
+ ## 5. Widget config flag map
626
+
627
+ Every `TradingView.widget({...})` option that controls whether a TV function is `widget-native` vs `native-chrome`. From `design-astroneum.md` §6. All three "hand-off" flags must be set together.
628
+
629
+ | Flag | Value | Effect | Hands off to Astroneum |
630
+ |---|---|---|---|
631
+ | `hide_top_toolbar` | `true` | Hides TV top bar | `TopBar.tsx` |
632
+ | `hide_legend` | `true` | Hides TV OHLC legend | `OhlcLegend.tsx` (§11) |
633
+ | `disable_native_context_menu` | `true` | Hides TV right-click menu | `ContextMenu.tsx` (§11) |
634
+ | `hide_side_toolbar` | `false` | Keeps TV drawing toolbar visible | — (drawing tools remain `widget-native`) |
635
+ | `allow_symbol_change` | `false` | Blocks in-widget symbol change | `SymbolSearch.tsx` |
636
+ | `allow_popups_and_modify` | `false` | Blocks in-widget popups | — |
637
+ | `withdateranges` | `true` | Shows date-range footer | — (kept `widget-native`) |
638
+ | `theme` | `"dark"` | Locks theme | — (Astroneum is dark-only v1) |
639
+ | `style` | `"1"` | Candles | user-controlled via `TopBar.tsx` |
640
+ | `interval` | route param | Timeframe | user-controlled via `TopBar.tsx` |
641
+ | `symbol` | `mapPairToTvSymbol(pair)` | Symbol | user-controlled via `Watchlist.tsx` |
642
+ | `studies` | user prefs | Active indicators | user-controlled via indicators button |
643
+ | `save_load_adapter` | `undefined` | No save/load | v1-deferred |
644
+ | `details_modifiers` | `undefined` | No details overrides | — |
645
+
646
+ ---
647
+
648
+ ## 6. Cross-reference to `design-astroneum.md`
649
+
650
+ ### §11 In-scope (build in v1)
651
+ - Chart right-click context menu → `ContextMenu.tsx` (this doc §3.10 / design §11)
652
+ - Crosshair OHLC legend → `OhlcLegend.tsx` (this doc §3.16 / design §11)
653
+
654
+ ### §12 Out-of-scope (defer)
655
+ - Multi-chart layouts → §3.3
656
+ - Compare / overlay / spread → §3.5
657
+ - Indicator settings dialog → §3.9
658
+ - Full alerts flow → §3.11
659
+ - Screener / Heatmaps / Calendars / News → §3.18, §3.19
660
+ - Broker / DOM / on-chart order dragging → §3.20
661
+ - Native Pine Editor / Strategy Tester → §3.13, §3.15
662
+ - Light theme → §5 (`theme: "dark"` locked)
663
+ - Mobile/touch → design §4 responsive
664
+ - Object tree → §3.10
665
+ - Logo / brand mark → design §12
666
+
667
+ ---
668
+
669
+ ## 7. Build / verify workflow
670
+
671
+ When working on `/astroneum`:
672
+
673
+ 1. Identify the TV function being mirrored.
674
+ 2. Find it in §3 (catalog).
675
+ 3. Read its status:
676
+ - `widget-native` → ensure the widget flag in §5 is set correctly. Do not rebuild.
677
+ - `api-bridged` → reuse the path in §2. Do not rebuild.
678
+ - `native-chrome` → build per `design-astroneum.md` §5, file in `src/components/astroneum/`.
679
+ - `v1-in-scope` → build now per `design-astroneum.md` §11.
680
+ - `v1-deferred` → do not build; note for v2.
681
+ - `v2-future` → note only.
682
+ 4. If webhook-related → cross-check §3.12 (the 25 events) and §4 (schema). Note: the `/api/webhooks/tradingview` route is in Trading-Bot-V2, NOT Astroneum. If building webhook ingestion in Astroneum, create a new route in `/opt/astroneum/demo/src/app/api/`.
683
+ 5. If Pine-related → cross-check §3.14 for whether v21 uses the function.
684
+ 6. After implementing, update the catalog row's `Pointer` column.
685
+
686
+ ---
687
+
688
+ ## 8. Versioning
689
+
690
+ - **Authoritative source for webhook events:** the v21 Pine source (`BTC H4 OP v21 WH+ LIVE`, title `CTC BB·SMMA H4 v2.9 + Webhook (Live-Ready)`). This doc was generated from it directly.
691
+ - **Stale doc:** `docs/webhook-payloads.md` covers v14 and is missing 6 stages present in v21: `RR_UPGRADE`, `PROFIT_LOCK`, `ADX_DECAY`, `TREND_FADE`, `PRE_SL_PROTECT`, `TP1_FINAL`. A sync pass is needed (out of scope for this doc).
692
+ - **TV version drift:** TradingView ships new indicators/functions quarterly. The `v2-future` bucket catches known-not-yet-mapped items. Re-verify the catalog against TV release notes each quarter.
693
+ - **Pine version:** v5. v6 exists; v21 source does not use v6-only features.
694
+ - **v21 as reference:** the v21 Pine source was used as a reference to ground §3.12, §3.14, §3.16, and §4. It is not a strategy to reproduce inside Astroneum; Astroneum ingests its webhook events and displays its positions, it does not re-host the strategy.
695
+
696
+ ---
697
+
698
+ ## 9. Verification checklist
699
+
700
+ - [ ] Every §3 catalog row has a `Status` and (where applicable) a `Pointer`.
701
+ - [ ] Every §3.12 webhook event maps 1:1 to an `alert()` call in the v21 source.
702
+ - [ ] Every §3.16 dashboard row maps 1:1 to a `table.cell` call in the v21 source.
703
+ - [ ] Every §11/§12 item in `design-astroneum.md` is linked from §6 of this doc.
704
+ - [ ] Every §5 widget flag matches the config block in `design-astroneum.md` §6.
705
+ - [ ] Every `api-bridged` pointer resolves to a file that exists under `src/app/api/` or `src/lib/`.
706
+ - [ ] Every `native-chrome` pointer resolves to a planned file under `src/components/astroneum/` (per `design-astroneum.md` §10).