@invinite-org/chartlang-core 1.0.1
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 +1694 -0
- package/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/alert/alert.d.ts +32 -0
- package/dist/alert/alert.d.ts.map +1 -0
- package/dist/alert/alert.js +19 -0
- package/dist/alert/alert.js.map +1 -0
- package/dist/alert/index.d.ts +2 -0
- package/dist/alert/index.d.ts.map +1 -0
- package/dist/alert/index.js +4 -0
- package/dist/alert/index.js.map +1 -0
- package/dist/color/colorHelpers.d.ts +65 -0
- package/dist/color/colorHelpers.d.ts.map +1 -0
- package/dist/color/colorHelpers.js +137 -0
- package/dist/color/colorHelpers.js.map +1 -0
- package/dist/color/index.d.ts +37 -0
- package/dist/color/index.d.ts.map +1 -0
- package/dist/color/index.js +23 -0
- package/dist/color/index.js.map +1 -0
- package/dist/color/parseColor.d.ts +48 -0
- package/dist/color/parseColor.d.ts.map +1 -0
- package/dist/color/parseColor.js +141 -0
- package/dist/color/parseColor.js.map +1 -0
- package/dist/define/defineAlert.d.ts +43 -0
- package/dist/define/defineAlert.d.ts.map +1 -0
- package/dist/define/defineAlert.js +49 -0
- package/dist/define/defineAlert.js.map +1 -0
- package/dist/define/defineAlertCondition.d.ts +65 -0
- package/dist/define/defineAlertCondition.d.ts.map +1 -0
- package/dist/define/defineAlertCondition.js +64 -0
- package/dist/define/defineAlertCondition.js.map +1 -0
- package/dist/define/defineDrawing.d.ts +62 -0
- package/dist/define/defineDrawing.d.ts.map +1 -0
- package/dist/define/defineDrawing.js +67 -0
- package/dist/define/defineDrawing.js.map +1 -0
- package/dist/define/defineIndicator.d.ts +48 -0
- package/dist/define/defineIndicator.d.ts.map +1 -0
- package/dist/define/defineIndicator.js +54 -0
- package/dist/define/defineIndicator.js.map +1 -0
- package/dist/define/index.d.ts +6 -0
- package/dist/define/index.d.ts.map +1 -0
- package/dist/define/index.js +7 -0
- package/dist/define/index.js.map +1 -0
- package/dist/define/overrides.d.ts +102 -0
- package/dist/define/overrides.d.ts.map +1 -0
- package/dist/define/overrides.js +4 -0
- package/dist/define/overrides.js.map +1 -0
- package/dist/draw/buckets.d.ts +57 -0
- package/dist/draw/buckets.d.ts.map +1 -0
- package/dist/draw/buckets.js +110 -0
- package/dist/draw/buckets.js.map +1 -0
- package/dist/draw/draw.d.ts +128 -0
- package/dist/draw/draw.d.ts.map +1 -0
- package/dist/draw/draw.js +40 -0
- package/dist/draw/draw.js.map +1 -0
- package/dist/draw/drawingKind.d.ts +80 -0
- package/dist/draw/drawingKind.d.ts.map +1 -0
- package/dist/draw/drawingKind.js +177 -0
- package/dist/draw/drawingKind.js.map +1 -0
- package/dist/draw/drawingState.d.ts +1420 -0
- package/dist/draw/drawingState.d.ts.map +1 -0
- package/dist/draw/drawingState.js +4 -0
- package/dist/draw/drawingState.js.map +1 -0
- package/dist/draw/drawingStyle.d.ts +219 -0
- package/dist/draw/drawingStyle.d.ts.map +1 -0
- package/dist/draw/drawingStyle.js +4 -0
- package/dist/draw/drawingStyle.js.map +1 -0
- package/dist/draw/handle.d.ts +32 -0
- package/dist/draw/handle.d.ts.map +1 -0
- package/dist/draw/handle.js +4 -0
- package/dist/draw/handle.js.map +1 -0
- package/dist/draw/index.d.ts +13 -0
- package/dist/draw/index.d.ts.map +1 -0
- package/dist/draw/index.js +7 -0
- package/dist/draw/index.js.map +1 -0
- package/dist/draw/table.d.ts +84 -0
- package/dist/draw/table.d.ts.map +1 -0
- package/dist/draw/table.js +22 -0
- package/dist/draw/table.js.map +1 -0
- package/dist/draw/worldPoint.d.ts +114 -0
- package/dist/draw/worldPoint.d.ts.map +1 -0
- package/dist/draw/worldPoint.js +4 -0
- package/dist/draw/worldPoint.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/input/index.d.ts +3 -0
- package/dist/input/index.d.ts.map +1 -0
- package/dist/input/index.js +4 -0
- package/dist/input/index.js.map +1 -0
- package/dist/input/input.d.ts +174 -0
- package/dist/input/input.d.ts.map +1 -0
- package/dist/input/input.js +174 -0
- package/dist/input/input.js.map +1 -0
- package/dist/input/inputDescriptor.d.ts +204 -0
- package/dist/input/inputDescriptor.d.ts.map +1 -0
- package/dist/input/inputDescriptor.js +4 -0
- package/dist/input/inputDescriptor.js.map +1 -0
- package/dist/interval/intervalToSeconds.d.ts +20 -0
- package/dist/interval/intervalToSeconds.d.ts.map +1 -0
- package/dist/interval/intervalToSeconds.js +50 -0
- package/dist/interval/intervalToSeconds.js.map +1 -0
- package/dist/plot/index.d.ts +2 -0
- package/dist/plot/index.d.ts.map +1 -0
- package/dist/plot/index.js +4 -0
- package/dist/plot/index.js.map +1 -0
- package/dist/plot/plot.d.ts +277 -0
- package/dist/plot/plot.d.ts.map +1 -0
- package/dist/plot/plot.js +37 -0
- package/dist/plot/plot.js.map +1 -0
- package/dist/request/index.d.ts +2 -0
- package/dist/request/index.d.ts.map +1 -0
- package/dist/request/index.js +4 -0
- package/dist/request/index.js.map +1 -0
- package/dist/request/request.d.ts +106 -0
- package/dist/request/request.d.ts.map +1 -0
- package/dist/request/request.js +44 -0
- package/dist/request/request.js.map +1 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/runtime.d.ts +84 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +72 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/state/index.d.ts +5 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +4 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/mutableSlot.d.ts +25 -0
- package/dist/state/mutableSlot.d.ts.map +1 -0
- package/dist/state/mutableSlot.js +4 -0
- package/dist/state/mutableSlot.js.map +1 -0
- package/dist/state/snapshot.d.ts +108 -0
- package/dist/state/snapshot.d.ts.map +1 -0
- package/dist/state/snapshot.js +4 -0
- package/dist/state/snapshot.js.map +1 -0
- package/dist/state/state.d.ts +86 -0
- package/dist/state/state.d.ts.map +1 -0
- package/dist/state/state.js +95 -0
- package/dist/state/state.js.map +1 -0
- package/dist/statefulPrimitives.d.ts +71 -0
- package/dist/statefulPrimitives.d.ts.map +1 -0
- package/dist/statefulPrimitives.js +234 -0
- package/dist/statefulPrimitives.js.map +1 -0
- package/dist/ta/index.d.ts +2 -0
- package/dist/ta/index.d.ts.map +1 -0
- package/dist/ta/index.js +4 -0
- package/dist/ta/index.js.map +1 -0
- package/dist/ta/ta.d.ts +2476 -0
- package/dist/ta/ta.d.ts.map +1 -0
- package/dist/ta/ta.js +312 -0
- package/dist/ta/ta.js.map +1 -0
- package/dist/time/_lib/dateTimeFormatCache.d.ts +11 -0
- package/dist/time/_lib/dateTimeFormatCache.d.ts.map +1 -0
- package/dist/time/_lib/dateTimeFormatCache.js +22 -0
- package/dist/time/_lib/dateTimeFormatCache.js.map +1 -0
- package/dist/time/index.d.ts +7 -0
- package/dist/time/index.d.ts.map +1 -0
- package/dist/time/index.js +8 -0
- package/dist/time/index.js.map +1 -0
- package/dist/time/nyDayKey.d.ts +24 -0
- package/dist/time/nyDayKey.d.ts.map +1 -0
- package/dist/time/nyDayKey.js +49 -0
- package/dist/time/nyDayKey.js.map +1 -0
- package/dist/time/session.d.ts +16 -0
- package/dist/time/session.d.ts.map +1 -0
- package/dist/time/session.js +18 -0
- package/dist/time/session.js.map +1 -0
- package/dist/time/sessionBoundaries.d.ts +40 -0
- package/dist/time/sessionBoundaries.d.ts.map +1 -0
- package/dist/time/sessionBoundaries.js +102 -0
- package/dist/time/sessionBoundaries.js.map +1 -0
- package/dist/time/types.d.ts +34 -0
- package/dist/time/types.d.ts.map +1 -0
- package/dist/time/types.js +4 -0
- package/dist/time/types.js.map +1 -0
- package/dist/time/weekKey.d.ts +11 -0
- package/dist/time/weekKey.d.ts.map +1 -0
- package/dist/time/weekKey.js +25 -0
- package/dist/time/weekKey.js.map +1 -0
- package/dist/time/weekday.d.ts +12 -0
- package/dist/time/weekday.d.ts.map +1 -0
- package/dist/time/weekday.js +22 -0
- package/dist/time/weekday.js.map +1 -0
- package/dist/types.d.ts +464 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/views/barstate.d.ts +40 -0
- package/dist/views/barstate.d.ts.map +1 -0
- package/dist/views/barstate.js +22 -0
- package/dist/views/barstate.js.map +1 -0
- package/dist/views/index.d.ts +4 -0
- package/dist/views/index.d.ts.map +1 -0
- package/dist/views/index.js +4 -0
- package/dist/views/index.js.map +1 -0
- package/dist/views/syminfo.d.ts +46 -0
- package/dist/views/syminfo.d.ts.map +1 -0
- package/dist/views/syminfo.js +25 -0
- package/dist/views/syminfo.js.map +1 -0
- package/dist/views/timeframe.d.ts +40 -0
- package/dist/views/timeframe.d.ts.map +1 -0
- package/dist/views/timeframe.js +21 -0
- package/dist/views/timeframe.js.map +1 -0
- package/package.json +45 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1694 @@
|
|
|
1
|
+
# @invinite-org/chartlang-core
|
|
2
|
+
|
|
3
|
+
## 1.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d1de692: Fix end-user-blocking Node-ESM packaging bug. Every published `dist/index.js` previously failed to load under Node's strict ESM resolver because `tsc` had been configured with `moduleResolution: "Bundler"` and emitted relative specifiers verbatim, so `dist/index.js` carried `from "./api"` (extensionless) and Node rejected the resolution. Workspace consumers never saw this because tsx / vitest / Vite resolve loosely, but `npm install @invinite-org/chartlang-compiler` followed by `import` failed immediately for any Node consumer, and `examples/react-demo/vite.config.ts`'s server-side compile plugin broke at dev-config-load time.
|
|
8
|
+
|
|
9
|
+
This release switches `tsconfig.base.json` to `module: "NodeNext"` / `moduleResolution: "NodeNext"`, and rewrites every relative import / export / dynamic-import / `typeof import("…")` specifier across all packages' source to carry an explicit `.js` (or `/index.js`) suffix. The new resolution mode also surfaces this bug class as a compile error rather than runtime breakage, so it cannot regress.
|
|
10
|
+
|
|
11
|
+
No behavioural change for runtime consumers — the rewritten specifiers resolve to the same TypeScript sources at build time and the same `dist/<path>.js` files at consumer-load time.
|
|
12
|
+
|
|
13
|
+
- 98599b2: Generate primitive reference pages for `plot`, `hline`, `alert`, and `request.lowerTf`: extended the Phase 4 docs generator with entries that source JSDoc from `packages/core/src/{plot,alert,request}/`, and added `@stable` markers to the top-level `plot` / `hline` / `alert` callable holes so the generator emits a stability label. The new pages are wired into the VitePress sidebar under Plot, Alert, and Request.
|
|
14
|
+
|
|
15
|
+
## 1.0.0
|
|
16
|
+
|
|
17
|
+
### Major Changes
|
|
18
|
+
|
|
19
|
+
- chartlang `1.0.0` -- the `apiVersion: 1` standard.
|
|
20
|
+
|
|
21
|
+
- `apiVersion: 1` frozen: compiler accepts only the frozen language
|
|
22
|
+
version; `STATEFUL_PRIMITIVES` locked at 172 entries by exact
|
|
23
|
+
name-set; every shipping export `@stable`; pre-1.0 deprecations
|
|
24
|
+
removed (`PHASE_1_SCENARIOS`).
|
|
25
|
+
- Canonical language spec published (`docs/spec/`): grammar,
|
|
26
|
+
semantics, manifest, emissions, versioning -- self-contained for
|
|
27
|
+
alternate implementations. The `v1.0.0` tag is the frozen spec
|
|
28
|
+
snapshot.
|
|
29
|
+
- Public conformance reports: `pnpm conformance --report` emits
|
|
30
|
+
`CONFORMANCE.md` + `conformance-report.json`; canvas2d reference
|
|
31
|
+
report published and drift-gated.
|
|
32
|
+
- Adapter-author path proven end-to-end: scaffolded adapters ship a
|
|
33
|
+
wired conformance test; full writing-an-adapter tutorial +
|
|
34
|
+
Lightweight Charts porting walkthrough.
|
|
35
|
+
- Pine migration guide finalised with a pattern-coverage matrix
|
|
36
|
+
audited against the top ~50 Pine scripts.
|
|
37
|
+
|
|
38
|
+
### Minor Changes
|
|
39
|
+
|
|
40
|
+
- d14a034: Add phase 5 server alerts, multi-timeframe request handling, runtime persistence, QuickJS hosting, expanded plot and table rendering, color helpers, alert conditions, and volume profile primitives.
|
|
41
|
+
- 3cfff10: Phase 6 closeout for Tier-3 ergonomics and lower-timeframe support.
|
|
42
|
+
- 3cfff10: Add `IntervalDescriptor.intervalSeconds?: number` and `intervalToSeconds`.
|
|
43
|
+
- 3cfff10: Add `request.lowerTf({ interval })` and compiler diagnostics for invalid lower-timeframe intervals.
|
|
44
|
+
- 3cfff10: Add the `@invinite-org/chartlang-core/time` subpath with session and timezone helpers.
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- Freeze `apiVersion: 1`: release-grade compiler diagnostics for version
|
|
49
|
+
mismatches, an exact name-set lock on the 172-entry `STATEFUL_PRIMITIVES`
|
|
50
|
+
registry, and freeze-contract documentation on pinned surfaces. No behavioural
|
|
51
|
+
change: the structural check already enforced `apiVersion: 1`.
|
|
52
|
+
- Pre-1.0 surface cleanup: remove the deprecated `PHASE_1_SCENARIOS`
|
|
53
|
+
alias (use `ALL_SCENARIOS`) and promote every shipping export from
|
|
54
|
+
`@experimental` to `@stable` ahead of the `apiVersion: 1` freeze.
|
|
55
|
+
|
|
56
|
+
## 0.5.0
|
|
57
|
+
|
|
58
|
+
### Phase 5
|
|
59
|
+
|
|
60
|
+
#### Minor Changes
|
|
61
|
+
|
|
62
|
+
- Ship Phase 5 color helpers from PLAN §11.4: `color.fromGradient`, `color.withAlpha`, `color.rgb`, and `color.hsl`.
|
|
63
|
+
- Add canonical StateSnapshot, StreamSnapshot, and StateStoreKey type declarations for PLAN.md §6.1 and §6.9 persistence.
|
|
64
|
+
- Ship Phase 5 `defineAlertCondition`, compiler manifest extraction, runtime `signal()` emissions, adapter validation, and conformance coverage per PLAN §11.2.
|
|
65
|
+
- Add `draw.table` with `TableCell`/`TablePosition` types, runtime emission,
|
|
66
|
+
viewport-anchored canvas2d rendering, and conformance coverage per PLAN §10.2.
|
|
67
|
+
- Add Phase 5 plot kinds, runtime emission dispatch, validation, conformance scenarios, and canvas2d reference renderers.
|
|
68
|
+
- Add the Phase 5 `runtime.log.*` and `runtime.error()` surface, log emissions, runtime halt diagnostics, and conformance coverage.
|
|
69
|
+
- Replace the Phase 4 `request.security` NaN-only path with real
|
|
70
|
+
multi-timeframe secondary stream alignment per PLAN.md §6.8 and §7.2.
|
|
71
|
+
Adapters can route tagged `CandleEvent.streamKey` candles, the worker
|
|
72
|
+
host dispatches them through `ScriptRunner.push`, conformance includes
|
|
73
|
+
MTF scenarios, and the private canvas2d reference adapter now declares
|
|
74
|
+
`multiTimeframe: true`.
|
|
75
|
+
- Port `ta.anchoredVolumeProfile` from invinite commit 3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4, adding the PLAN §9.2 horizontal-histogram volume-profile primitive and PLAN §10.1.1 input-time anchor workflow.
|
|
76
|
+
- Add `ta.fixedRangeVolumeProfile`, completing the Phase 5 volume-profile set
|
|
77
|
+
from PLAN §9.2 and §10.1.1 with fixed `[from, to]` anchors, frozen post-range
|
|
78
|
+
histograms, and `fixed-range-inverted` diagnostics. Ported from invinite
|
|
79
|
+
commit `3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4`.
|
|
80
|
+
- Port `ta.sessionVolumeProfile` from invinite commit 3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4, adding the PLAN §9.2 horizontal-histogram session volume-profile primitive, PLAN §4.8 syminfo-session fallback diagnostics, and compiler/runtime registration.
|
|
81
|
+
- Add `ta.visibleRangeVolumeProfile` per PLAN §9.2, ported from invinite commit `3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4`, with runtime histogram emission, compiler/core type surfaces, conformance coverage, and generated docs.
|
|
82
|
+
|
|
83
|
+
## 0.4.0
|
|
84
|
+
|
|
85
|
+
### Minor Changes
|
|
86
|
+
|
|
87
|
+
- 3f3ce38: Replace the Phase-0 placeholder with the Phase-1 typed surface:
|
|
88
|
+
`defineIndicator` / `defineAlert` constructors, the `ta` / `plot` / `alert`
|
|
89
|
+
callable holes the compiler retargets at the runtime, the frozen
|
|
90
|
+
`STATEFUL_PRIMITIVES` registry, and every §4.3 type. Nothing executes —
|
|
91
|
+
`core` ships types and callable surfaces only; the runtime ships the real
|
|
92
|
+
implementations in Tasks 5-8.
|
|
93
|
+
- 38fb475: Phase 2 — `0.2` full indicator parity.
|
|
94
|
+
|
|
95
|
+
- 81 new `ta.*` primitives (6 cross-functional + 75 §9.2 ports);
|
|
96
|
+
`TA_REGISTRY` cardinality 9 -> 90; `STATEFUL_PRIMITIVES`
|
|
97
|
+
cardinality 12 -> 93.
|
|
98
|
+
- 5 new chained-MA helpers + 5 new stats/volatility helpers in
|
|
99
|
+
`packages/runtime/src/ta/lib/`.
|
|
100
|
+
- 6 new `PlotKind`s (histogram, bars, area, filled-band, label,
|
|
101
|
+
marker) + canvas2d renderers + `validateEmission` arms.
|
|
102
|
+
- `Bar` extended with `hl2` / `hlc3` / `ohlc4` / `hlcc4` derived
|
|
103
|
+
source fields — runtime already pre-computes on `BarView`.
|
|
104
|
+
- `Scenario` extended with `inlineSource?: string` so Phase-2
|
|
105
|
+
scenarios stay self-contained without bloating
|
|
106
|
+
`examples/scripts/`.
|
|
107
|
+
- `STATEFUL_PRIMITIVES` shape widened from `ReadonlySet<string>`
|
|
108
|
+
to `ReadonlySet<{ name: string; slot: boolean }>` to support
|
|
109
|
+
`ta.nz` (the only stateless `ta.*`).
|
|
110
|
+
- Universal `opts.offset` honoured on every `ta.*` primitive
|
|
111
|
+
(Phase-1 backfill in Task 29).
|
|
112
|
+
- `chartlang docs` subcommand generates
|
|
113
|
+
`docs/primitives/ta/<id>.md` per primitive.
|
|
114
|
+
- `PHASE_2_INDICATORS` + `PHASE_5_DEFERRED` inventories exported
|
|
115
|
+
from `@invinite-org/chartlang-conformance` and pinned by
|
|
116
|
+
`phase2Coverage.test.ts` (Task 30).
|
|
117
|
+
- 100% coverage maintained across every published package.
|
|
118
|
+
- `apiVersion: 1` script header unchanged; Phase 2 is additive
|
|
119
|
+
at runtime.
|
|
120
|
+
|
|
121
|
+
- 38fb475: Phase-2 Task 5 — cross-functional `ta.*` primitives + `STATEFUL_PRIMITIVES`
|
|
122
|
+
shape evolution.
|
|
123
|
+
|
|
124
|
+
Ships six new Pine-canonical `ta.*` primitives under
|
|
125
|
+
`packages/runtime/src/ta/`:
|
|
126
|
+
|
|
127
|
+
- `ta.nz(value, replacement?)` — stateless NaN-replacement.
|
|
128
|
+
- `ta.highest(source, length)` — rolling max (monotone deque + window
|
|
129
|
+
recompute).
|
|
130
|
+
- `ta.lowest(source, length)` — rolling min (mirror of `highest`).
|
|
131
|
+
- `ta.change(source, opts)` — first-difference `source[0] − source[length]`.
|
|
132
|
+
- `ta.valuewhen(condition, source, occurrence)` — source value at the
|
|
133
|
+
n-th most recent matching bar.
|
|
134
|
+
- `ta.barssince(condition)` — bars since the last `condition === true`.
|
|
135
|
+
|
|
136
|
+
Each primitive ships the §22.10 set: impl + unit + property + golden +
|
|
137
|
+
bench pair + conformance scenario (using the Phase-2 `inlineSource`
|
|
138
|
+
extension from Task 1) + auto-generated `docs/primitives/ta/<id>.md`.
|
|
139
|
+
|
|
140
|
+
`STATEFUL_PRIMITIVES` widens from `ReadonlySet<string>` to
|
|
141
|
+
`ReadonlySet<{ name: string; slot: boolean }>` so `ta.nz` (the only
|
|
142
|
+
stateless cross-functional primitive) can opt out of compiler slot-id
|
|
143
|
+
injection. Phase-1 entries flip to `slot: true`; `ta.nz` is the only
|
|
144
|
+
`slot: false` entry; the set cardinality grows from 12 → 18. The shape
|
|
145
|
+
update cascades through every compiler consumer
|
|
146
|
+
(`packages/compiler/src/api.ts`, `program.ts`,
|
|
147
|
+
`analysis/statefulCallInLoop.ts`, `transformers/callsiteIdInjection.ts`,
|
|
148
|
+
and their tests). The `statefulCallInLoop` analysis still flags every
|
|
149
|
+
entry inside a loop body — `slot: false` primitives are forbidden in
|
|
150
|
+
loops by Pine-parity convention.
|
|
151
|
+
|
|
152
|
+
`TA_REGISTRY` cardinality grows from 9 → 15. `RuntimeTaNamespace`
|
|
153
|
+
mirrors core's `TaNamespace` 1:1 with the standard `slotId` first-arg
|
|
154
|
+
on every method except `nz` (which carries the script-author signature
|
|
155
|
+
verbatim).
|
|
156
|
+
|
|
157
|
+
Compiler change is `patch`-level — the public API surface is
|
|
158
|
+
unchanged; only the internal `STATEFUL_PRIMITIVES` parameter shape
|
|
159
|
+
widens. Core/runtime/conformance bump `minor` for the new exports and
|
|
160
|
+
the new scenarios.
|
|
161
|
+
|
|
162
|
+
- 38fb475: Phase-2 Task 7 — MA ports (`ta.dema`, `ta.tema`, `ta.kama`, `ta.alma`).
|
|
163
|
+
|
|
164
|
+
Adds four chained / adaptive moving averages on top of the Phase-1
|
|
165
|
+
EMA primitive + the Task-6 MA backbone. DEMA / TEMA compose EMA
|
|
166
|
+
sub-slots through `TA_REGISTRY` (`${slotId}/ema1` / `/ema2` / `/ema3`);
|
|
167
|
+
KAMA is Kaufman's adaptive MA with an efficiency-ratio-driven
|
|
168
|
+
smoothing constant; ALMA is the Arnaud Legoux MA with a precomputed
|
|
169
|
+
Gaussian weight kernel.
|
|
170
|
+
|
|
171
|
+
Each primitive ships the §22.10 set (impl + four test layers +
|
|
172
|
+
conformance scenario + auto-generated docs page). ALMA's `offset`
|
|
173
|
+
opt is the Gaussian-centre position in `[0, 1]` (default `0.85`) —
|
|
174
|
+
distinct from the universal bar-shift, which lives on `opts.barShift`
|
|
175
|
+
for ALMA only.
|
|
176
|
+
|
|
177
|
+
Compiler patch: the ambient shim mirrors the four new
|
|
178
|
+
`TaNamespace` methods + opt bags.
|
|
179
|
+
|
|
180
|
+
- 38fb475: Phase-2 Task 8 — final §9.2 MA ports (`ta.lsma`, `ta.mcginley`, `ta.maRibbon`).
|
|
181
|
+
|
|
182
|
+
Closes out the §9.2 moving-averages list. `ta.lsma` is the linear-
|
|
183
|
+
regression value at the trailing window (reuses Task-4's
|
|
184
|
+
`linearRegression` helper for the property-test reference);
|
|
185
|
+
`ta.mcginley` is the McGinley Dynamic recurrence with NaN-correct
|
|
186
|
+
zero-anchor handling; `ta.maRibbon` is a fan of K MAs at different
|
|
187
|
+
lengths, dispatched per-bar through `TA_REGISTRY`'s registered MA
|
|
188
|
+
primitives (`sma` / `ema` / `wma` / `smma`) via sub-slot ids
|
|
189
|
+
`${slotId}/ma_<length>`.
|
|
190
|
+
|
|
191
|
+
`MaRibbonResult` is a dynamic-keyed record `{ ma_<length>:
|
|
192
|
+
Series<number> }`. The exported `maRibbonOutputKeys(opts)` helper
|
|
193
|
+
returns the ordered keys for stable iteration. `maRibbon` is
|
|
194
|
+
registry-tagged as multi-output via `TA_REGISTRY_METADATA` with its
|
|
195
|
+
default `primarySeriesKey: "ma_50"` + default visible keys
|
|
196
|
+
`["ma_10", "ma_20", "ma_30", "ma_40", "ma_50"]` + `{ kind: "auto" }`
|
|
197
|
+
y-domain — runtime metadata for legend chips and pane axes.
|
|
198
|
+
|
|
199
|
+
Core also adds the `MaTypeNoVolume` string-literal union (parallel to
|
|
200
|
+
the runtime's `lib/maTypes.ts` alias) so script authors can type the
|
|
201
|
+
`maType` opt directly. Each primitive ships the §22.10 set (impl +
|
|
202
|
+
four test layers + conformance scenario + auto-generated docs page).
|
|
203
|
+
|
|
204
|
+
Compiler patch: the ambient shim mirrors the three new `TaNamespace`
|
|
205
|
+
methods + opt bags + `MaTypeNoVolume` alias + `MaRibbonResult` type.
|
|
206
|
+
|
|
207
|
+
- 38fb475: Phase-2 Task 6 — MA ports (`ta.wma`, `ta.vwma`, `ta.hma`, `ta.smma`).
|
|
208
|
+
|
|
209
|
+
Adds four moving-average primitives on top of the Task-3 chained-MA
|
|
210
|
+
helpers. `ta.wma` is a linear-weighted MA over the trailing window;
|
|
211
|
+
`ta.vwma` is the volume-weighted variant; `ta.smma` is Wilder's
|
|
212
|
+
smoothed MA (α = 1/N); `ta.hma` is the Hull MA composed via three WMA
|
|
213
|
+
sub-slots derived from the parent slot id (`${slotId}/half`,
|
|
214
|
+
`${slotId}/full`, `${slotId}/final`).
|
|
215
|
+
|
|
216
|
+
Each primitive ships the §22.10 set (impl + four test layers +
|
|
217
|
+
conformance scenario + auto-generated docs page). The opts bags
|
|
218
|
+
(`WmaOpts`, `VwmaOpts`, `HmaOpts`, `SmmaOpts`) carry the universal
|
|
219
|
+
`offset` + `lineStyle` fields — typed surface only; the runtime
|
|
220
|
+
wiring lands in Task 29's universal-offset backfill.
|
|
221
|
+
|
|
222
|
+
Compiler patch: the ambient shim mirrors the four new
|
|
223
|
+
`TaNamespace` methods + opt bags.
|
|
224
|
+
|
|
225
|
+
- 38fb475: Phase-2 Task 13 — momentum ports (`ta.ao`, `ta.cmo`, `ta.momentum`,
|
|
226
|
+
`ta.roc`).
|
|
227
|
+
|
|
228
|
+
Ships four new momentum primitives under `packages/runtime/src/ta/`:
|
|
229
|
+
|
|
230
|
+
- `ta.ao(opts?)` — Awesome Oscillator. `SMA(hl2, fastLength) − SMA(hl2,
|
|
231
|
+
slowLength)`. Defaults to Pine-canonical `5` / `34`. Composes two
|
|
232
|
+
`ta.sma` sub-slots (`${slotId}/fastSma`, `${slotId}/slowSma`); a fix
|
|
233
|
+
to `sma` flows in for free.
|
|
234
|
+
- `ta.cmo(source, length, opts?)` — Chande Momentum Oscillator. Range
|
|
235
|
+
`[-100, 100]`. Trailing-window of per-bar gain / loss diffs with
|
|
236
|
+
incremental sum maintenance + flat-line (zero-denominator) NaN
|
|
237
|
+
guard.
|
|
238
|
+
- `ta.momentum(source, length, opts?)` — Pine `mom`. First-difference
|
|
239
|
+
`source[0] − source[length]`. Implemented as a thin shim around
|
|
240
|
+
`ta.change` (`${slotId}/change` sub-slot) — no private subtraction
|
|
241
|
+
loop.
|
|
242
|
+
- `ta.roc(source, length, opts?)` — Rate of Change. `100 ×
|
|
243
|
+
(source[0] − source[length]) / source[length]`. Zero lookback →
|
|
244
|
+
NaN.
|
|
245
|
+
|
|
246
|
+
Each primitive ships the §22.10 set: impl + unit + property + golden +
|
|
247
|
+
bench pair + conformance scenario (using the Phase-2 `inlineSource`
|
|
248
|
+
extension from Task 1) + auto-generated `docs/primitives/ta/<id>.md`.
|
|
249
|
+
|
|
250
|
+
`STATEFUL_PRIMITIVES` gains four new `slot: true` entries; `TaNamespace`
|
|
251
|
+
|
|
252
|
+
- `RuntimeTaNamespace` gain four new methods; `TA_REGISTRY` gains four
|
|
253
|
+
new entries. Four new opts types exported from core: `AoOpts`,
|
|
254
|
+
`CmoOpts`, `MomentumOpts`, `RocOpts` (each carries `offset?: number` and
|
|
255
|
+
`lineStyle?: PlotLineStyle` forward-compat fields; `AoOpts` also
|
|
256
|
+
carries `fastLength?: number`, `slowLength?: number`).
|
|
257
|
+
|
|
258
|
+
Provenance: ported from `invinite/src/components/trading-chart/
|
|
259
|
+
indicators/{ao,cmo,momentum,roc}.ts` at commit
|
|
260
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`.
|
|
261
|
+
|
|
262
|
+
- 38fb475: Phase-2 Task 14 — momentum ports (`ta.pmo`, `ta.smi`, `ta.tsi`).
|
|
263
|
+
|
|
264
|
+
Ships three double-smoothed momentum primitives under
|
|
265
|
+
`packages/runtime/src/ta/`:
|
|
266
|
+
|
|
267
|
+
- `ta.pmo(source, opts?)` — Carl Swenlin's Price Momentum Oscillator
|
|
268
|
+
(`{ pmo, signal }`). Three-pass smoothing of the 1-bar ROC, scaled
|
|
269
|
+
to PMO's characteristic ±10 swing range. The two inner stages use
|
|
270
|
+
a non-canonical "Swenlin EMA" factor (`α = 2 / length`) instead of
|
|
271
|
+
the standard `α = 2 / (length + 1)`; the signal-line EMA composes
|
|
272
|
+
the canonical `ta.ema` via a `${slotId}/signal` sub-slot. Defaults
|
|
273
|
+
`(firstSmoothing, secondSmoothing, signalLength) = (35, 20, 10)`
|
|
274
|
+
per TradingView's published formula.
|
|
275
|
+
- `ta.smi(opts?)` — William Blau's Stochastic Momentum Index
|
|
276
|
+
(`{ smi, signal }`). Composes `ta.highest` over `bar.high` and
|
|
277
|
+
`ta.lowest` over `bar.low` (`kLength` window) for the rolling
|
|
278
|
+
midpoint and range, then double-EMA-smooths both numerator
|
|
279
|
+
(`bar.close − midpoint`) and denominator (`range / 2`) through two
|
|
280
|
+
EMA layers each, then computes `100 × numSmoothed / denSmoothed`
|
|
281
|
+
and feeds it through a signal EMA. Bounded `[-100, 100]` (flat
|
|
282
|
+
range → NaN at smi). Defaults `(kLength, firstSmoothing,
|
|
283
|
+
secondSmoothing, dLength) = (10, 3, 5, 3)`.
|
|
284
|
+
- `ta.tsi(source, opts?)` — William Blau's True Strength Index
|
|
285
|
+
(momentum-class; `{ tsi, signal }`). Double-EMA-smoothed ratio of
|
|
286
|
+
one-bar price changes vs their absolute values, scaled ×100.
|
|
287
|
+
Bounded `[-100, 100]` (flat input → NaN at tsi). Defaults
|
|
288
|
+
`(firstSmoothing, secondSmoothing, signalLength) = (25, 13, 13)`
|
|
289
|
+
per TradingView's published TSI study. Note: this is the
|
|
290
|
+
**momentum**-class TSI; the **trend**-class True Strength Index
|
|
291
|
+
ships in Task 17 as `ta.trendStrengthIndex`.
|
|
292
|
+
|
|
293
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
294
|
+
golden + bench pair + conformance scenario (using the Phase-2
|
|
295
|
+
`inlineSource` extension from Task 1) + auto-generated
|
|
296
|
+
`docs/primitives/ta/<id>.md` page.
|
|
297
|
+
|
|
298
|
+
`TA_REGISTRY_METADATA` extends with three new entries: `pmo` and
|
|
299
|
+
`tsi` advertise `primarySeriesKey` + `visibleSeriesKeys` with
|
|
300
|
+
`yDomain: { kind: "auto" }`; `smi` is `{ kind: "fixed", min: -100,
|
|
301
|
+
max: 100 }`.
|
|
302
|
+
|
|
303
|
+
Core surface widens with `PmoOpts` / `PmoResult`, `SmiOpts` /
|
|
304
|
+
`SmiResult`, `TsiOpts` / `TsiResult` plus matching `TaNamespace`
|
|
305
|
+
methods and throw-sentinel stubs. `STATEFUL_PRIMITIVES` extends
|
|
306
|
+
with `ta.pmo` / `ta.smi` / `ta.tsi` (all `slot: true`).
|
|
307
|
+
|
|
308
|
+
Three conformance scenarios (`taPmo.scenario.ts`,
|
|
309
|
+
`taSmi.scenario.ts`, `taTsi.scenario.ts`) registered against
|
|
310
|
+
`ALL_SCENARIOS` via the Task-1 `inlineSource` extension.
|
|
311
|
+
Plot-hash pinning deferred to Phase-2 closeout (Task 30) per the
|
|
312
|
+
established cross-functional scenario convention.
|
|
313
|
+
|
|
314
|
+
Provenance: ported from `invinite/src/components/trading-chart/
|
|
315
|
+
indicators/{pmo,smi,tsi}.ts` at commit
|
|
316
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`.
|
|
317
|
+
|
|
318
|
+
- 38fb475: Phase-2 Task 29 — Universal `opts.offset` backfill on Phase-1 primitives.
|
|
319
|
+
|
|
320
|
+
Wires the universal `opts.offset` (PLAN.md §9.1) onto every Phase-1
|
|
321
|
+
`ta.*` primitive: `sma`, `ema`, `stdev`, `bb`, `rsi`, `macd`, `atr`,
|
|
322
|
+
`crossover`, `crossunder`. Positive `offset` shifts the returned
|
|
323
|
+
series so `series.current` reads the value `offset` bars ago
|
|
324
|
+
(matching `lib/applyOffset`'s `out[i] = values[i − offset]`
|
|
325
|
+
semantics); negative `offset` reads into the future (NaN /
|
|
326
|
+
undefined at the head). `offset === 0` is the strict identity
|
|
327
|
+
fast path — returns the slot's cached un-shifted Series with the
|
|
328
|
+
same reference as before this change (existing identity-pinned
|
|
329
|
+
tests continue to pass).
|
|
330
|
+
|
|
331
|
+
Surface expansion (core, minor):
|
|
332
|
+
|
|
333
|
+
- `offset?: number` added to `SmaOpts`, `EmaOpts`, `StdevOpts`,
|
|
334
|
+
`BbOpts`, `RsiOpts`, `MacdOpts`, `AtrOpts` (Phase-1 opts types
|
|
335
|
+
that previously had no `offset` field).
|
|
336
|
+
- New `CrossoverOpts` / `CrossunderOpts` types (the two cross
|
|
337
|
+
primitives previously took no opts bag); `TaNamespace.crossover`
|
|
338
|
+
/ `crossunder` signatures gain an optional 3rd opts arg.
|
|
339
|
+
- New `makeShiftedSeriesView` runtime helper next to
|
|
340
|
+
`makeSeriesView` (in `packages/runtime/src/seriesView.ts`,
|
|
341
|
+
re-exported from the runtime barrel) — wraps a `RingBufferLike<T>`
|
|
342
|
+
in a Proxy that adjusts `at(n)` reads by `offset`.
|
|
343
|
+
|
|
344
|
+
Composite primitives (`bb`, `macd`) shift all outputs in lockstep
|
|
345
|
+
under a single `offset` value, returning a frozen result record
|
|
346
|
+
cached per offset on the slot. Sub-slot outputs (sma's middle,
|
|
347
|
+
ema's signal) are accessed through their captured ring-buffer
|
|
348
|
+
reference so the parent primitive doesn't re-enter the sub-slot's
|
|
349
|
+
compute on the shifted-view lookup.
|
|
350
|
+
|
|
351
|
+
Compiler patch: the ambient shim in `packages/compiler/src/program.ts`
|
|
352
|
+
mirrors the core type changes (new `offset?` fields + new
|
|
353
|
+
`CrossoverOpts` / `CrossunderOpts` types + extended `TaNamespace`
|
|
354
|
+
signatures).
|
|
355
|
+
|
|
356
|
+
Goldens, bench thresholds, and conformance scenarios are
|
|
357
|
+
unchanged — `offset === 0` is the default and exercises the
|
|
358
|
+
existing code paths. New per-primitive `<id>.test.ts` and
|
|
359
|
+
`<id>.property.test.ts` cases cover positive, negative, zero, and
|
|
360
|
+
identity-cache behaviour for offset.
|
|
361
|
+
|
|
362
|
+
- 38fb475: Phase-2 Task 9 — oscillator ports: `ta.cci`, `ta.stoch`, `ta.williamsR`.
|
|
363
|
+
|
|
364
|
+
Ships three foundational momentum / oscillator primitives under
|
|
365
|
+
`packages/runtime/src/ta/`:
|
|
366
|
+
|
|
367
|
+
- `ta.cci(source, length, opts?)` — Commodity Channel Index over a
|
|
368
|
+
configurable source (typically `bar.hlc3`). Lambert constant
|
|
369
|
+
`scaling = 0.015` hard-coded; flat-window (`meanDev === 0`) emits
|
|
370
|
+
`NaN`. Unbounded by construction.
|
|
371
|
+
- `ta.stoch(opts?)` — Stochastic Oscillator (`%K` + `%D`) over
|
|
372
|
+
`bar.high` / `bar.low` / `bar.close`. Composes `ta.highest` +
|
|
373
|
+
`ta.lowest` + two chained `ta.sma` smoothing layers via sub-slot
|
|
374
|
+
ids. Bounded `[0, 100]` (or `NaN`). Defaults `(kLength=14,
|
|
375
|
+
kSmoothing=3, dLength=3)`.
|
|
376
|
+
- `ta.williamsR(length, opts?)` — Williams %R over `bar.high` /
|
|
377
|
+
`bar.low` / `bar.close`. Composes `ta.highest` + `ta.lowest`.
|
|
378
|
+
Bounded `[-100, 0]` (or `NaN`).
|
|
379
|
+
|
|
380
|
+
Each primitive ships the §22.10 set: impl + unit + property + golden
|
|
381
|
+
|
|
382
|
+
- bench pair + conformance scenario (inlined per Task 1) +
|
|
383
|
+
auto-generated `docs/primitives/ta/<id>.md`.
|
|
384
|
+
|
|
385
|
+
Introduces a new metadata layer on the runtime registry:
|
|
386
|
+
|
|
387
|
+
- `TA_REGISTRY_METADATA: Readonly<Partial<Record<keyof typeof
|
|
388
|
+
TA_REGISTRY, PrimitiveMetadata>>>` — per-primitive `primarySeriesKey`,
|
|
389
|
+
`visibleSeriesKeys`, and `yDomain` hints for renderers (pane layout,
|
|
390
|
+
legend ordering, y-axis scaling). `ta.stoch` records
|
|
391
|
+
`primarySeriesKey: "k"`, `visibleSeriesKeys: ["k", "d"]`,
|
|
392
|
+
`yDomain: { kind: "fixed", min: 0, max: 100 }`; `ta.williamsR`
|
|
393
|
+
records `yDomain: { kind: "fixed", min: -100, max: 0 }`. Unbounded
|
|
394
|
+
primitives (e.g. `ta.cci`, `ta.sma`) carry no metadata entry —
|
|
395
|
+
consumers default to `auto`.
|
|
396
|
+
|
|
397
|
+
Core surface widens with `CciOpts`, `StochOpts`, `WilliamsROpts` opts
|
|
398
|
+
bags + `StochResult` two-output type, plus the matching `TaNamespace`
|
|
399
|
+
methods and throw-sentinel stubs. `STATEFUL_PRIMITIVES` extends with
|
|
400
|
+
`ta.cci` / `ta.stoch` / `ta.williamsR` (all `slot: true`). Compiler
|
|
401
|
+
shim mirrors the new core surface.
|
|
402
|
+
|
|
403
|
+
Three conformance scenarios (`taCci.scenario.ts`, `taStoch.scenario.ts`,
|
|
404
|
+
`taWilliamsR.scenario.ts`) registered against `ALL_SCENARIOS` via
|
|
405
|
+
the Task-1 `inlineSource` extension. Plot-hash pinning deferred to
|
|
406
|
+
Phase-2 closeout (Task 30) per the established cross-functional
|
|
407
|
+
scenario convention.
|
|
408
|
+
|
|
409
|
+
DIVERGENCE from invinite reference (`stoch.ts`): the spec requires
|
|
410
|
+
flat-window (`hh === ll`) → `NaN` at `k`, whereas invinite falls back
|
|
411
|
+
to the prior valid kRaw (or 50 on the first slot, per TradingView).
|
|
412
|
+
The task spec overrides; documented in the impl's provenance header.
|
|
413
|
+
|
|
414
|
+
`CciOpts` intentionally narrows away invinite's `scaling` knob —
|
|
415
|
+
chartlang hard-codes the canonical Lambert constant.
|
|
416
|
+
|
|
417
|
+
- 38fb475: Phase-2 Task 12 — oscillator ports: `ta.kst`, `ta.fisher`,
|
|
418
|
+
`ta.klinger`, `ta.rvgi`.
|
|
419
|
+
|
|
420
|
+
Ships four more multi-output oscillator primitives under
|
|
421
|
+
`packages/runtime/src/ta/`:
|
|
422
|
+
|
|
423
|
+
- `ta.kst(source, opts?)` — Know Sure Thing (Martin Pring, 1992).
|
|
424
|
+
Weighted sum of four SMA-smoothed percentage ROCs plus an SMA
|
|
425
|
+
signal line. Composes 4 `ta.sma` sub-slots for the per-ROC
|
|
426
|
+
smoothing plus one `ta.sma` for the signal; the four percentage
|
|
427
|
+
ROCs are computed inline against a shared `sourceWindow` ring
|
|
428
|
+
(mirrors `ta.coppock` — `ta.change` emits absolute deltas, while
|
|
429
|
+
KST needs percentage rate-of-change). Defaults
|
|
430
|
+
`(10, 15, 20, 30, 10, 10, 10, 15, 9)`.
|
|
431
|
+
- `ta.fisher(length, opts?)` — John Ehlers' Fisher Transform over
|
|
432
|
+
rolling `bar.hl2`. Composes `ta.highest` + `ta.lowest` sub-slots;
|
|
433
|
+
the clamp / atanh / EMA-blend recurrence is bespoke. The `trigger`
|
|
434
|
+
output is the prior bar's `fisher` value (1-bar lag); first bar's
|
|
435
|
+
`trigger` is NaN. Diverges from invinite's ±0.999 clamp per task
|
|
436
|
+
spec — when the recurrence would drive `|x| ≥ 1` we emit NaN at
|
|
437
|
+
`fisher` and hold the recurrence state.
|
|
438
|
+
- `ta.klinger(opts?)` — Klinger Volume Oscillator. Per-bar Volume
|
|
439
|
+
Force accumulator drives the difference of two `ta.ema` sub-slots
|
|
440
|
+
(`fastLength` / `slowLength`); the `signal` is a third
|
|
441
|
+
`ta.ema(klinger, signalLength)`. Defaults `(34, 55, 13)`.
|
|
442
|
+
- `ta.rvgi(opts?)` — Relative Vigor Index (John Ehlers, 2002).
|
|
443
|
+
4-bar `(1, 2, 2, 1) / 6` weighted numerator (`close − open`) and
|
|
444
|
+
denominator (`high − low`), each smoothed via `ta.sma` sub-slot;
|
|
445
|
+
`rvgi = numSma / denSma`. Signal is a 4-bar weighted sum of the
|
|
446
|
+
rvgi line. Defaults `length = 10`; flat-range bars emit NaN.
|
|
447
|
+
|
|
448
|
+
Each primitive ships the §22.10 set: impl + unit + property + golden
|
|
449
|
+
|
|
450
|
+
- bench pair + conformance scenario (inlined per Task 1) +
|
|
451
|
+
auto-generated `docs/primitives/ta/<id>.md`.
|
|
452
|
+
|
|
453
|
+
Extends `TA_REGISTRY_METADATA` with four new entries (all
|
|
454
|
+
`primarySeriesKey` + `visibleSeriesKeys`; all `yDomain: { kind:
|
|
455
|
+
"auto" }` per task §5):
|
|
456
|
+
|
|
457
|
+
- `kst`: `primarySeriesKey: "kst"`, `visibleSeriesKeys: ["kst", "signal"]`.
|
|
458
|
+
- `fisher`: `primarySeriesKey: "fisher"`, `visibleSeriesKeys: ["fisher", "trigger"]`.
|
|
459
|
+
- `klinger`: `primarySeriesKey: "klinger"`, `visibleSeriesKeys: ["klinger", "signal"]`.
|
|
460
|
+
- `rvgi`: `primarySeriesKey: "rvgi"`, `visibleSeriesKeys: ["rvgi", "signal"]`.
|
|
461
|
+
|
|
462
|
+
Core surface widens with `KstOpts`, `FisherOpts`, `KlingerOpts`,
|
|
463
|
+
`RvgiOpts` opts bags + `KstResult`, `FisherResult`, `KlingerResult`,
|
|
464
|
+
`RvgiResult` two-output types, plus the matching `TaNamespace`
|
|
465
|
+
methods and throw-sentinel stubs. `STATEFUL_PRIMITIVES` extends
|
|
466
|
+
with `ta.kst` / `ta.fisher` / `ta.klinger` / `ta.rvgi` (all
|
|
467
|
+
`slot: true`). Compiler shim mirrors the new core surface.
|
|
468
|
+
|
|
469
|
+
Four conformance scenarios (`taKst.scenario.ts`,
|
|
470
|
+
`taFisher.scenario.ts`, `taKlinger.scenario.ts`,
|
|
471
|
+
`taRvgi.scenario.ts`) registered against `ALL_SCENARIOS` via the
|
|
472
|
+
Task-1 `inlineSource` extension. Plot-hash pinning deferred to
|
|
473
|
+
Phase-2 closeout (Task 30) per the established multi-output scenario
|
|
474
|
+
convention.
|
|
475
|
+
|
|
476
|
+
- 38fb475: Phase-2 Task 10 — oscillator ports: `ta.ppo`, `ta.dpo`,
|
|
477
|
+
`ta.connorsRsi`.
|
|
478
|
+
|
|
479
|
+
Ships three derived oscillator primitives under
|
|
480
|
+
`packages/runtime/src/ta/`:
|
|
481
|
+
|
|
482
|
+
- `ta.ppo(source, opts?)` — Percentage Price Oscillator, the
|
|
483
|
+
scale-invariant cousin of MACD. Three outputs (`{ ppo, signal,
|
|
484
|
+
hist }`) over `100 * (fastEma - slowEma) / slowEma`. Composes three
|
|
485
|
+
`ta.ema` sub-slots (`${slotId}/fast`, `${slotId}/slow`,
|
|
486
|
+
`${slotId}/signal`) per §9.4 — folds invinite's private EMA copy
|
|
487
|
+
onto the canonical primitive. Defaults `(12, 26, 9)`. `slow === 0`
|
|
488
|
+
emits `NaN` at the PPO line; signal can still be defined off prior
|
|
489
|
+
values.
|
|
490
|
+
- `ta.dpo(source, length, opts?)` — Detrended Price Oscillator
|
|
491
|
+
(non-centered, TradingView default). `dpo[i] = source[i -
|
|
492
|
+
displacement] - sma[i]` with `displacement = floor(length / 2) +
|
|
493
|
+
1`. Composes one `ta.sma` sub-slot plus a per-slot source-window
|
|
494
|
+
Float64RingBuffer for the O(1) per-bar shifted-source lookup.
|
|
495
|
+
- `ta.connorsRsi(source, opts?)` — Connors RSI, a `[0, 100]`-bounded
|
|
496
|
+
blend of `RSI(source, rsiLength)`, `RSI(streak, streakLength)`,
|
|
497
|
+
and `PercentRank(ROC(source, 1), rocLength)`. Composes two
|
|
498
|
+
`ta.rsi` sub-slots — no private RSI math duplication. Defaults
|
|
499
|
+
`(3, 2, 100)`. Sub-component NaN → component skipped in the
|
|
500
|
+
average (per task spec §6, diverges from invinite's stricter
|
|
501
|
+
all-finite requirement to align with the Pine semantic).
|
|
502
|
+
|
|
503
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
504
|
+
golden + bench pair + conformance scenario (inlined per Task 1) +
|
|
505
|
+
auto-generated `docs/primitives/ta/<id>.md`.
|
|
506
|
+
|
|
507
|
+
`TA_REGISTRY_METADATA` extends with:
|
|
508
|
+
|
|
509
|
+
- `ppo`: `primarySeriesKey: "ppo"`, `visibleSeriesKeys: ["ppo",
|
|
510
|
+
"signal", "hist"]`, `yDomain: { kind: "auto" }`.
|
|
511
|
+
- `connorsRsi`: `yDomain: { kind: "fixed", min: 0, max: 100 }`.
|
|
512
|
+
- `dpo`: no metadata entry (unbounded — consumers default to
|
|
513
|
+
`auto`).
|
|
514
|
+
|
|
515
|
+
Core surface widens with `PpoOpts`, `DpoOpts`, `ConnorsRsiOpts`
|
|
516
|
+
opts bags + `PpoResult` three-output type, plus the matching
|
|
517
|
+
`TaNamespace` methods and throw-sentinel stubs.
|
|
518
|
+
`STATEFUL_PRIMITIVES` extends with `ta.ppo` / `ta.dpo` /
|
|
519
|
+
`ta.connorsRsi` (all `slot: true`). Compiler shim mirrors the new
|
|
520
|
+
core surface.
|
|
521
|
+
|
|
522
|
+
Three conformance scenarios (`taPpo.scenario.ts`,
|
|
523
|
+
`taDpo.scenario.ts`, `taConnorsRsi.scenario.ts`) registered against
|
|
524
|
+
`ALL_SCENARIOS` via the Task-1 `inlineSource` extension.
|
|
525
|
+
Plot-hash pinning deferred to Phase-2 closeout (Task 30) per the
|
|
526
|
+
established cross-functional scenario convention.
|
|
527
|
+
|
|
528
|
+
DEVIATIONS from invinite reference (commit
|
|
529
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`):
|
|
530
|
+
|
|
531
|
+
- `ppo.ts` — invinite carries a private EMA copy
|
|
532
|
+
(`computeMaSeries(oscillatorMaType, ...)`); chartlang routes
|
|
533
|
+
through the canonical `ta.ema` primitive via sub-slot
|
|
534
|
+
composition (matches `ta.macd`). §9.4 fold satisfied.
|
|
535
|
+
- `dpo.ts` — only the non-centered (TradingView default) render
|
|
536
|
+
mode is shipped. Invinite's `centered: true` mode emits
|
|
537
|
+
`dpo[i] = src[i] - sma[i + displacement]`, which depends on the
|
|
538
|
+
future SMA; chartlang's append-only ring-buffer contract can't
|
|
539
|
+
backfill, so that mode is deferred. Documented in the impl's
|
|
540
|
+
provenance header.
|
|
541
|
+
- `connorsRsi.ts` — invinite requires all three components finite
|
|
542
|
+
for the CRSI line to define; the task spec (§6) overrides with
|
|
543
|
+
"sub-component NaN → component skipped in the average". We
|
|
544
|
+
follow the spec, which tightens alignment with the Pine
|
|
545
|
+
`ta.connorsRsi` semantic where streak-RSI warmup doesn't gate
|
|
546
|
+
the rsi-on-close component.
|
|
547
|
+
|
|
548
|
+
- 38fb475: Phase-2 Task 11 — oscillator ports: `ta.stochRsi`, `ta.ultimateOsc`,
|
|
549
|
+
`ta.coppock`.
|
|
550
|
+
|
|
551
|
+
Ships three more oscillator primitives under
|
|
552
|
+
`packages/runtime/src/ta/`:
|
|
553
|
+
|
|
554
|
+
- `ta.stochRsi(source, opts?)` — Stochastic RSI (`%K` + `%D`).
|
|
555
|
+
Composes `ta.rsi` + `ta.highest` + `ta.lowest` + two chained
|
|
556
|
+
`ta.sma` smoothing layers via sub-slot ids. Bounded `[0, 100]`
|
|
557
|
+
(or `NaN`). Defaults `(rsiLength=14, stochLength=14, kSmoothing=3,
|
|
558
|
+
dSmoothing=3)`. Flat-RSI-window (`hh === ll`) emits `NaN` at `k`
|
|
559
|
+
— diverges from invinite's prev-or-50 fallback per task spec.
|
|
560
|
+
- `ta.ultimateOsc(opts?)` — Larry Williams' Ultimate Oscillator over
|
|
561
|
+
`bar.high` / `bar.low` / `bar.close`. Weighted average of three
|
|
562
|
+
buying-pressure / true-range ratios across `shortLength` /
|
|
563
|
+
`mediumLength` / `longLength` windows (defaults `7` / `14` / `28`).
|
|
564
|
+
Bounded `[0, 100]` (or `NaN`); zero-TR window emits `NaN`.
|
|
565
|
+
- `ta.coppock(source, opts?)` — Edwin Coppock's Curve.
|
|
566
|
+
`WMA(ROC(source, roc1Length) + ROC(source, roc2Length),
|
|
567
|
+
wmaLength)` over percentage ROC. Defaults `(11, 14, 10)`. Unbounded;
|
|
568
|
+
zero-crossings are the canonical signal. Inlines the percentage-ROC
|
|
569
|
+
computation against its own `sourceWindow` (the spec's hint to
|
|
570
|
+
compose `ta.change` does not fit — `ta.change` emits absolute
|
|
571
|
+
deltas, not percentages).
|
|
572
|
+
|
|
573
|
+
Each primitive ships the §22.10 set: impl + unit + property + golden
|
|
574
|
+
|
|
575
|
+
- bench pair + conformance scenario (inlined per Task 1) +
|
|
576
|
+
auto-generated `docs/primitives/ta/<id>.md`.
|
|
577
|
+
|
|
578
|
+
Extends `TA_REGISTRY_METADATA` with two new bounded-oscillator
|
|
579
|
+
entries:
|
|
580
|
+
|
|
581
|
+
- `stochRsi`: `primarySeriesKey: "k"`, `visibleSeriesKeys: ["k", "d"]`,
|
|
582
|
+
`yDomain: { kind: "fixed", min: 0, max: 100 }`.
|
|
583
|
+
- `ultimateOsc`: `yDomain: { kind: "fixed", min: 0, max: 100 }`.
|
|
584
|
+
|
|
585
|
+
`ta.coppock` is unbounded — no metadata entry; consumers default to
|
|
586
|
+
`auto`.
|
|
587
|
+
|
|
588
|
+
Core surface widens with `StochRsiOpts`, `UltimateOscOpts`,
|
|
589
|
+
`CoppockOpts` opts bags + `StochRsiResult` two-output type, plus the
|
|
590
|
+
matching `TaNamespace` methods and throw-sentinel stubs.
|
|
591
|
+
`STATEFUL_PRIMITIVES` extends with `ta.stochRsi` / `ta.ultimateOsc` /
|
|
592
|
+
`ta.coppock` (all `slot: true`). Compiler shim mirrors the new core
|
|
593
|
+
surface.
|
|
594
|
+
|
|
595
|
+
Three conformance scenarios (`taStochRsi.scenario.ts`,
|
|
596
|
+
`taUltimateOsc.scenario.ts`, `taCoppock.scenario.ts`) registered
|
|
597
|
+
against `ALL_SCENARIOS` via the Task-1 `inlineSource` extension.
|
|
598
|
+
Plot-hash pinning deferred to Phase-2 closeout (Task 30) per the
|
|
599
|
+
established cross-functional scenario convention.
|
|
600
|
+
|
|
601
|
+
- 38fb475: Phase-2 Task 1 — three foundational widenings every subsequent
|
|
602
|
+
Phase-2 port depends on:
|
|
603
|
+
|
|
604
|
+
1. **`PlotKind` expansion (3 → 9).** Adds `histogram`, `bars`,
|
|
605
|
+
`area`, `filled-band`, `label`, `marker` per PLAN.md §7.3. The
|
|
606
|
+
`PlotStyle` discriminated union in
|
|
607
|
+
`@invinite-org/chartlang-adapter-kit` extends in lockstep; the
|
|
608
|
+
`validateEmission` switch grows matching arms with per-kind
|
|
609
|
+
payload rules; the `capabilities` builder gains `histogram()` /
|
|
610
|
+
`bars()` / `area()` / `filledBand()` / `label()` / `marker()` /
|
|
611
|
+
`allPhase2Plots()`. The canvas2d reference adapter ships six new
|
|
612
|
+
pure-on-`RenderCtx` renderers (`render/histogram.ts`, `bars.ts`,
|
|
613
|
+
`area.ts`, `filledBand.ts`, `label.ts`, `marker.ts`) and flips
|
|
614
|
+
`CANVAS2D_CAPABILITIES.plots` to `capabilities.allPhase2Plots()`
|
|
615
|
+
(9 kinds). `RenderCtx` + `MockCanvas2DContext` extend with
|
|
616
|
+
`fillText`, `globalAlpha`, `font`, `textAlign`, `textBaseline`.
|
|
617
|
+
|
|
618
|
+
2. **`Bar` derived sources.** Extends the script-facing `Bar`
|
|
619
|
+
(`packages/core/src/types.ts`) with the four pre-computed derived
|
|
620
|
+
sources `hl2` / `hlc3` / `ohlc4` / `hlcc4`. The runtime's
|
|
621
|
+
`BarView` (`packages/runtime/src/streamState.ts`) already
|
|
622
|
+
populates these on every close — Phase 2 surfaces them so authors
|
|
623
|
+
can write `ta.cci(bar.hlc3, 20)` like Pine. No runtime change.
|
|
624
|
+
|
|
625
|
+
3. **`Scenario.inlineSource`.** Extends the conformance `Scenario`
|
|
626
|
+
type (`packages/conformance/src/runConformanceSuite.ts`) with an
|
|
627
|
+
optional `inlineSource?: string` field that is mutually exclusive
|
|
628
|
+
with the existing `scriptPath?: string`. `runConformanceSuite`
|
|
629
|
+
writes the inline source to the existing `.cache/` tmp file and
|
|
630
|
+
compiles + imports it exactly like the `scriptPath` branch, with
|
|
631
|
+
a virtual `<inline:${id}>.chart.ts` `sourcePath` so callsite-id
|
|
632
|
+
injection produces stable, pinnable slot ids. Phase-2 ports use
|
|
633
|
+
this to carry their `defineIndicator` source inline rather than
|
|
634
|
+
spawning 80+ files in `examples/scripts/`.
|
|
635
|
+
|
|
636
|
+
The new `PLOT_KIND_COVERAGE_SCENARIO` exercises the `inlineSource`
|
|
637
|
+
path + the wider capability surface end-to-end (one inline
|
|
638
|
+
`plot(bar.close)` + `hline(50)` script; asserts no
|
|
639
|
+
`unsupported-plot-kind` and no `malformed-emission` diagnostics
|
|
640
|
+
fire). Per-port Phase-2 tasks (Tasks 21+) each add their own
|
|
641
|
+
scenario asserting the specific new kind's drained emissions once
|
|
642
|
+
the runtime acquires the matching emission path.
|
|
643
|
+
|
|
644
|
+
No runtime / host-worker source-level changes in this task —
|
|
645
|
+
`BarView` already carries the four derived fields, and the
|
|
646
|
+
`PlotKind` expansion is additive at every consumer.
|
|
647
|
+
|
|
648
|
+
- 38fb475: Phase 2 quality-pass fixes (cross-cutting).
|
|
649
|
+
|
|
650
|
+
- `@invinite-org/chartlang-core`: new `STATEFUL_PRIMITIVES_BY_NAME`
|
|
651
|
+
export — a `ReadonlyMap<string, StatefulPrimitiveEntry>` derived
|
|
652
|
+
from the same canonical entry list as `STATEFUL_PRIMITIVES`. Lets
|
|
653
|
+
the compiler look up entries by callee name in O(1) instead of an
|
|
654
|
+
O(n) scan over the 93-entry set on every visited call site.
|
|
655
|
+
- `@invinite-org/chartlang-compiler`: `callsiteIdInjection` and
|
|
656
|
+
`statefulCallInLoop` now consume `STATEFUL_PRIMITIVES_BY_NAME`
|
|
657
|
+
via a `statefulByName: ReadonlyMap<string, StatefulPrimitiveEntry>`
|
|
658
|
+
parameter (was `statefulSet: ReadonlySet<StatefulPrimitiveEntry>`).
|
|
659
|
+
Internal-only API change — neither pass is publicly exported from
|
|
660
|
+
`packages/compiler/src/index.ts`. The per-pass `hasName` /
|
|
661
|
+
`findEntry` helpers are dropped.
|
|
662
|
+
- `@invinite-org/chartlang-runtime`: `ta/lib/maTypes.ts` re-exports
|
|
663
|
+
`MaTypeNoVolume` from `@invinite-org/chartlang-core` instead of
|
|
664
|
+
re-declaring it locally — keeps the two definitions from drifting
|
|
665
|
+
when a 6th MA kind is added. `MaType` (which adds `"vwma"`) stays
|
|
666
|
+
local since core has no equivalent. `__fixtures__/syntheticBars.ts`
|
|
667
|
+
and `nanTick.test.ts`'s inline `Bar` literals now carry the
|
|
668
|
+
`hl2` / `hlc3` / `ohlc4` / `hlcc4` fields the Phase-2 `Bar`
|
|
669
|
+
extension made required (the per-package tsconfig had been hiding
|
|
670
|
+
the typecheck miss).
|
|
671
|
+
|
|
672
|
+
Also: `examples/canvas2d-adapter` — extracted the duplicated
|
|
673
|
+
`dashPattern(LineStyle)` from `render/area.ts` + `render/horizontalLine.ts`
|
|
674
|
+
into `render/lineDash.ts`, re-exported from `render/index.ts`. No
|
|
675
|
+
behaviour change.
|
|
676
|
+
|
|
677
|
+
- 38fb475: Phase-2 Task 26 — S/R ports: `ta.chandelier`, `ta.chandeKrollStop`,
|
|
678
|
+
`ta.williamsFractal`.
|
|
679
|
+
|
|
680
|
+
Ships three new S/R `ta.*` primitives under
|
|
681
|
+
`packages/runtime/src/ta/`:
|
|
682
|
+
|
|
683
|
+
- `ta.chandelier(opts?)` — Chandelier Exit returning
|
|
684
|
+
`{ long, short }`. Composes Phase-1 `ta.atr` plus Task-5
|
|
685
|
+
`ta.highest` / `ta.lowest` at sub-slots `${slotId}/atr` /
|
|
686
|
+
`${slotId}/highHigh` / `${slotId}/lowLow`. `long = highest(high,
|
|
687
|
+
length) − multiplier · atr(length)`; `short` symmetric. Defaults
|
|
688
|
+
`length = 22`, `multiplier = 3` per Pine canonical. Source
|
|
689
|
+
hard-coded to `bar.high` / `bar.low` (deliberate divergence from
|
|
690
|
+
invinite's `source` parameter — matches Pine `ta.chandelier_exit`).
|
|
691
|
+
|
|
692
|
+
- `ta.chandeKrollStop(opts?)` — Chande Kroll Stop returning
|
|
693
|
+
`{ long, short }`. Two-pass smoothed trailing stop: first pass
|
|
694
|
+
computes `firstHigh = highest(high, length) − multiplier · atr` /
|
|
695
|
+
`firstLow = lowest(low, length) + multiplier · atr` (composed via
|
|
696
|
+
`ta.atr` + `ta.highest` / `ta.lowest` sub-slots); second pass
|
|
697
|
+
walks a slot-owned `Float64RingBuffer` of size `smoothingLength`
|
|
698
|
+
for the rolling max / min. Defaults `length = 10`, `multiplier = 1`,
|
|
699
|
+
`smoothingLength = 9` (matches Chande Kroll's 1995 paper).
|
|
700
|
+
|
|
701
|
+
- `ta.williamsFractal(opts?)` — Williams Fractal returning
|
|
702
|
+
`{ up, down }` as **price-level series** (NaN when no fractal,
|
|
703
|
+
`bar.high(centre)` for up-fractal, `bar.low(centre)` for down).
|
|
704
|
+
Self-contained centred-window scan over a `2 · length + 1` ring
|
|
705
|
+
buffer per side. Output is centred: at live bar `t`, the value
|
|
706
|
+
emitted reflects bar `t − length`'s fractal status (when bar `t`
|
|
707
|
+
closes, we now have the right-window bars to confirm bar
|
|
708
|
+
`t − length`). Default `length = 2` (5-bar window). Strict
|
|
709
|
+
comparison: tied highs/lows in the window → no fractal.
|
|
710
|
+
|
|
711
|
+
Deviation from the task spec's literal `Series<boolean>` wording:
|
|
712
|
+
emits price levels instead so the `marker` plot has a meaningful
|
|
713
|
+
y-anchor. Matches invinite's `upFractals[i] = high` shape.
|
|
714
|
+
|
|
715
|
+
Each primitive ships the §22.10 set (impl + unit + property + golden
|
|
716
|
+
hash + bench pair) plus a `taChandelier.scenario.ts`,
|
|
717
|
+
`taChandeKrollStop.scenario.ts`, and `taWilliamsFractal.scenario.ts`
|
|
718
|
+
conformance scenario. JSDoc per §17.2 with `@formula`, `@warmup`,
|
|
719
|
+
`@since 0.2`, `@experimental`, `@example`, and `@anchors`.
|
|
720
|
+
|
|
721
|
+
**`PlotOptsStyle` marker widening (core + runtime + compiler shim).**
|
|
722
|
+
Adds the `marker` variant to `PlotOptsStyle` in core (mirrors the
|
|
723
|
+
adapter-kit's `PlotStyle.marker` shape declared by Task 1), the
|
|
724
|
+
matching dispatch branch to `buildStyle` in
|
|
725
|
+
`packages/runtime/src/emit/plot.ts`, and the same widening in the
|
|
726
|
+
compiler's ambient shim. The Williams Fractal scenario is the first
|
|
727
|
+
to exercise the marker plot kind end-to-end. The cap-gated dispatch
|
|
728
|
+
path is unit-covered in `plot.test.ts`'s new marker case.
|
|
729
|
+
|
|
730
|
+
`TaNamespace` (core) and `RuntimeTaNamespace` (runtime) extend with
|
|
731
|
+
three new methods + matching opts / result types. `STATEFUL_PRIMITIVES`
|
|
732
|
+
appends three new `slot: true` entries. `TA_REGISTRY` adds three
|
|
733
|
+
entries plus `TA_REGISTRY_METADATA` records for each
|
|
734
|
+
(`primarySeriesKey` / `visibleSeriesKeys` / `yDomain = auto`).
|
|
735
|
+
|
|
736
|
+
Auto-generated documentation pages land at
|
|
737
|
+
`docs/primitives/ta/{chandelier,chandeKrollStop,williamsFractal}.md`
|
|
738
|
+
via the Task-2 generator. The `docs/primitives/ta/index.md` carries a
|
|
739
|
+
new "S/R (Task 26)" subsection.
|
|
740
|
+
|
|
741
|
+
- 38fb475: Phase-2 Task 25 — S/R ports: `ta.psar` and `ta.supertrend`.
|
|
742
|
+
|
|
743
|
+
Ships two new flagship trend-following S/R `ta.*` primitives under
|
|
744
|
+
`packages/runtime/src/ta/`:
|
|
745
|
+
|
|
746
|
+
- `ta.psar(opts?)` — Wilder Parabolic SAR returning
|
|
747
|
+
`{ sar, direction }`. Self-contained state machine over
|
|
748
|
+
`bar.high` / `bar.low` / `bar.close` with extreme-point +
|
|
749
|
+
acceleration-factor tracking and trend-flip semantics. Defaults
|
|
750
|
+
`accelerationStart = 0.02`, `accelerationStep = 0.02`,
|
|
751
|
+
`accelerationMax = 0.2` per Pine / Wilder. Bar 0 emits the seed
|
|
752
|
+
(`sar = bar.low`, `direction = +1`); bar 1 decides the initial
|
|
753
|
+
direction from `close[1] >= close[0]`; bar 2+ runs the standard
|
|
754
|
+
recurrence with the lower/upper-bound clamps against the prior
|
|
755
|
+
two bars' lows/highs.
|
|
756
|
+
- `ta.supertrend(opts?)` — ATR-driven trailing-stop trend follower
|
|
757
|
+
returning `{ line, direction }`. Composes Phase-1 `ta.atr` at
|
|
758
|
+
sub-slot `${slotId}/atr`, so a fix to ATR flows in for free.
|
|
759
|
+
Defaults `length = 10`, `multiplier = 3`. Reads `bar.hl2` for the
|
|
760
|
+
band midpoint (Pine-canonical). The final-band persistence rule
|
|
761
|
+
carries the prior band forward unless the prior close pierced it;
|
|
762
|
+
direction flips when the current close crosses the prior
|
|
763
|
+
`finalUpper` / `finalLower`.
|
|
764
|
+
|
|
765
|
+
Both primitives suspend their recurrence state on NaN OHLC so the
|
|
766
|
+
next finite bar resumes from the prior state. `replaceHead`
|
|
767
|
+
correctness is asserted via append-vs-replaceHead property tests
|
|
768
|
+
over adversarial sharp-reversal sequences — both implementations
|
|
769
|
+
snapshot the state at the start of each bar BEFORE the close-side
|
|
770
|
+
recurrence advances so a final tick replays from the seed.
|
|
771
|
+
|
|
772
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
773
|
+
golden + bench pair + conformance scenario (using the Phase-2
|
|
774
|
+
`inlineSource` extension from Task 1) + auto-generated
|
|
775
|
+
`docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries the
|
|
776
|
+
multi-output / y-domain hints (`psar: { primarySeriesKey: "sar",
|
|
777
|
+
visibleSeriesKeys: ["sar", "direction"], yDomain: auto }`,
|
|
778
|
+
`supertrend: { primarySeriesKey: "line", visibleSeriesKeys:
|
|
779
|
+
["line", "direction"], yDomain: auto }`).
|
|
780
|
+
|
|
781
|
+
Core adds `PsarOpts`, `PsarResult`, `SupertrendOpts`,
|
|
782
|
+
`SupertrendResult` exports + the two `TaNamespace` methods.
|
|
783
|
+
`STATEFUL_PRIMITIVES` grows by 2 (`ta.psar`, `ta.supertrend`; both
|
|
784
|
+
`slot: true`). `TA_REGISTRY` mirrors with the leading
|
|
785
|
+
`slotId: string` on each method.
|
|
786
|
+
|
|
787
|
+
- 38fb475: Phase-2 Task 27 — S/R ports: `ta.zigZag`, `ta.pivotsHighLow`,
|
|
788
|
+
`ta.pivotsStandard`, and `ta.volatilityStop` (closes §9.2's S/R
|
|
789
|
+
list).
|
|
790
|
+
|
|
791
|
+
Ships four new S/R `ta.*` primitives under
|
|
792
|
+
`packages/runtime/src/ta/`:
|
|
793
|
+
|
|
794
|
+
- `ta.zigZag(opts?)` — streaming swing-pivot detector. Walks the
|
|
795
|
+
close series tracking a running candidate pivot; confirms a new
|
|
796
|
+
pivot when the price has reversed by ≥ `deviation %` AND `depth`
|
|
797
|
+
bars have elapsed. Returns `{ value, direction }` where `value`
|
|
798
|
+
carries the most-recently-confirmed pivot price (held constant
|
|
799
|
+
between confirmations, NaN before the first) and `direction` is
|
|
800
|
+
`+1` / `-1` / NaN. Defaults `deviation = 5`, `depth = 10`.
|
|
801
|
+
Streaming adaptation of invinite's batch ZigZag — invinite's
|
|
802
|
+
linear-interpolation rendering between pivots isn't representable
|
|
803
|
+
in the append-only `Series` model, so the output is the closest
|
|
804
|
+
surface (a "trailing reference level").
|
|
805
|
+
- `ta.pivotsHighLow(opts?)` — centred-window swing-pivot detector
|
|
806
|
+
with asymmetric `(leftLength, rightLength)` confirmation windows.
|
|
807
|
+
Returns `{ high, low }` (price-level series — `bar.high(centre)`
|
|
808
|
+
or `bar.low(centre)` when a pivot confirms, NaN otherwise).
|
|
809
|
+
Mirrors invinite's tie-break: strict-greater on the left window,
|
|
810
|
+
geq on the right (matches Pine `ta.pivothigh`). Defaults
|
|
811
|
+
`leftLength = rightLength = 4` (9-bar window).
|
|
812
|
+
- `ta.pivotsStandard(opts?)` — classical daily pivot-point levels
|
|
813
|
+
(P, R1..R3, S1..S3) derived from the previous UTC-day's HLC.
|
|
814
|
+
Returns seven `Series<number>` (`{ pp, r1, s1, r2, s2, r3, s3 }`).
|
|
815
|
+
Four formula systems: `"classic"` (default), `"fibonacci"`,
|
|
816
|
+
`"camarilla"`, `"woodie"`. UTC-day boundary detection via
|
|
817
|
+
`Math.floor(bar.time / 86_400_000)`. R4 / R5 / S4 / S5 levels
|
|
818
|
+
(Camarilla's full table) and DeMark / Traditional systems
|
|
819
|
+
intentionally defer per the Phase-2 README "Deferred / Follow-Up
|
|
820
|
+
Work" footnote.
|
|
821
|
+
- `ta.volatilityStop(opts?)` — PSAR-like trend-following stop
|
|
822
|
+
driven by ATR. Composes Phase-1 `ta.atr` at sub-slot
|
|
823
|
+
`${slotId}/atr`. Returns `{ value, direction }` (`+1` uptrend →
|
|
824
|
+
stop is BELOW price; `-1` downtrend → stop ABOVE). Defaults
|
|
825
|
+
`length = 20`, `multiplier = 2`. Source hard-coded to `bar.close`
|
|
826
|
+
(Pine `ta.vstop` convention; invinite's `source` field is
|
|
827
|
+
omitted, a `source` opt could land in a follow-up).
|
|
828
|
+
|
|
829
|
+
All four primitives suspend their recurrence state on NaN OHLC so
|
|
830
|
+
the next finite bar resumes from the prior state. `replaceHead`
|
|
831
|
+
correctness is asserted via append-vs-replaceHead property tests
|
|
832
|
+
over `arbBar` fixtures — ZigZag and Volatility Stop snapshot their
|
|
833
|
+
state-machine state at the start of each bar BEFORE the close-side
|
|
834
|
+
recurrence advances so a final tick replays from the seed
|
|
835
|
+
(mirrors Task 25's PSAR / Supertrend pattern).
|
|
836
|
+
|
|
837
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
838
|
+
golden + bench pair + conformance scenario (using the Phase-2
|
|
839
|
+
`inlineSource` extension from Task 1) + auto-generated
|
|
840
|
+
`docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries the
|
|
841
|
+
multi-output / y-domain hints (all four use `yDomain: { kind:
|
|
842
|
+
"auto" }`).
|
|
843
|
+
|
|
844
|
+
Core adds `ZigZagOpts`, `ZigZagResult`, `PivotsHighLowOpts`,
|
|
845
|
+
`PivotsHighLowResult`, `PivotsStandardOpts`,
|
|
846
|
+
`PivotsStandardResult`, `PivotsStandardSystem`,
|
|
847
|
+
`VolatilityStopOpts`, and `VolatilityStopResult` exports + four
|
|
848
|
+
`TaNamespace` methods. `STATEFUL_PRIMITIVES` grows by 4 (all
|
|
849
|
+
`slot: true`). `TA_REGISTRY` mirrors with the leading
|
|
850
|
+
`slotId: string` on each method.
|
|
851
|
+
|
|
852
|
+
Compiler patch: the ambient shim mirrors the four new methods +
|
|
853
|
+
nine new types.
|
|
854
|
+
|
|
855
|
+
- 38fb475: Phase-2 Task 28 — statistical `ta.*` ports: `ta.median`, `ta.adr`,
|
|
856
|
+
`ta.ulcerIndex`.
|
|
857
|
+
|
|
858
|
+
Ships three new statistical primitives under
|
|
859
|
+
`packages/runtime/src/ta/`:
|
|
860
|
+
|
|
861
|
+
- `ta.median(source, length, opts?)` — rolling median over the
|
|
862
|
+
trailing `length` source values. Odd-`length` → middle value;
|
|
863
|
+
even-`length` → mean of the two middle values. NaN slots are
|
|
864
|
+
dropped from the sort (window length effectively shrinks). Range
|
|
865
|
+
invariant pinned: `min(window) ≤ out ≤ max(window)`. Tick-mode
|
|
866
|
+
substitutes the head value before sorting (closed window
|
|
867
|
+
unchanged).
|
|
868
|
+
- `ta.adr(opts?)` — Average Daily Range. SMA of `high − low` over
|
|
869
|
+
the trailing `length` (default `14`) completed UTC calendar days.
|
|
870
|
+
Reads `bar.high` / `bar.low` / `bar.time` directly (no `source`
|
|
871
|
+
param). Phase-2 keys "daily" on the UTC midnight boundary
|
|
872
|
+
(`Math.floor(bar.time / 86_400_000)`); Phase 4 lifts this onto
|
|
873
|
+
`syminfo.session`. The in-progress (currently-aggregating) day is
|
|
874
|
+
NEVER included in the average — matches invinite's "completed N
|
|
875
|
+
daily bars" semantics. Tick mode emits the cached SMA (no day-
|
|
876
|
+
boundary advance per the runtime tick invariant).
|
|
877
|
+
- `ta.ulcerIndex(source, length, opts?)` — drawdown-based volatility
|
|
878
|
+
(rolling RMS of percent declines from the rolling-window high).
|
|
879
|
+
Composes `ta.highest` via sub-slot id `${slotId}/highest`. Range
|
|
880
|
+
invariant pinned: `out ≥ 0`. NaN source → NaN output (window
|
|
881
|
+
unchanged).
|
|
882
|
+
|
|
883
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
884
|
+
golden + bench pair + conformance scenario (inline-source per Task
|
|
885
|
+
1's extension) + auto-generated `docs/primitives/ta/<id>.md`.
|
|
886
|
+
|
|
887
|
+
`STATEFUL_PRIMITIVES` grows by `+3` (`ta.median`, `ta.adr`,
|
|
888
|
+
`ta.ulcerIndex` — all `slot: true`). `TA_REGISTRY` grows by `+3`.
|
|
889
|
+
`TaNamespace` and `RuntimeTaNamespace` extend in lockstep with
|
|
890
|
+
`MedianOpts`, `AdrOpts` (`{ length?: number; offset?: number;
|
|
891
|
+
lineStyle?: PlotLineStyle }`), and `UlcerIndexOpts`.
|
|
892
|
+
|
|
893
|
+
`ALL_SCENARIOS` (conformance) grows by `+3`. The three new
|
|
894
|
+
scenarios assert `alert-count: 0` + the standard
|
|
895
|
+
`lookback-exceeded` / `malformed-emission` diagnostic-absent gates
|
|
896
|
+
(no `plot-hash` — the rolling primitives' outputs are pinned
|
|
897
|
+
elsewhere via the runtime golden tests).
|
|
898
|
+
|
|
899
|
+
- 38fb475: Phase-2 Task 16 — trend ports: `ta.adx`, `ta.dmi`, `ta.trix`.
|
|
900
|
+
|
|
901
|
+
Ships three new trend `ta.*` primitives under
|
|
902
|
+
`packages/runtime/src/ta/`:
|
|
903
|
+
|
|
904
|
+
- `ta.adx(length, opts?)` — Wilder's Average Directional Index
|
|
905
|
+
(single Series bounded `[0, 100]`). Reads `bar.high` /
|
|
906
|
+
`bar.low` / `bar.close` directly (mirrors Pine's `ta.adx(length)`
|
|
907
|
+
— no source param). Composes the same Wilder DI recurrence
|
|
908
|
+
`ta.dmi` runs, then folds DX through a second
|
|
909
|
+
Wilder-smoothing window of length `opts.smoothing ?? 14`.
|
|
910
|
+
- `ta.dmi(length, opts?)` — Wilder's Directional Movement Index
|
|
911
|
+
(`{ plusDi, minusDi }`, both ∈ [0, 100]). Reads OHLC directly
|
|
912
|
+
per Pine's `ta.dmi(length)`. Incremental `wilderStep` over
|
|
913
|
+
`+DM` / `−DM` / TR; output validated against the
|
|
914
|
+
full-recompute reference `lib/wilderDirectional`.
|
|
915
|
+
- `ta.trix(source, length, opts?)` — TRIX triple-smoothed EMA
|
|
916
|
+
rate-of-change with an EMA-signal line (`{ trix, signal }`).
|
|
917
|
+
Composes three EMA sub-slots (`${slotId}/ema1` / `/ema2` /
|
|
918
|
+
`/ema3`) for the triple chain + a fourth `${slotId}/signal`
|
|
919
|
+
EMA, mirroring the MACD sub-slot composition pattern.
|
|
920
|
+
|
|
921
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
922
|
+
golden + bench pair + conformance scenario (using the Phase-2
|
|
923
|
+
`inlineSource` extension from Task 1) + auto-generated
|
|
924
|
+
`docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries
|
|
925
|
+
y-domain + multi-output hints (`adx: { yDomain: fixed 0-100 }`,
|
|
926
|
+
`dmi: { primarySeriesKey: "plusDi", visibleSeriesKeys: ["plusDi",
|
|
927
|
+
"minusDi"], yDomain: fixed 0-100 }`, `trix: { primarySeriesKey:
|
|
928
|
+
"trix", visibleSeriesKeys: ["trix", "signal"], yDomain: auto }`).
|
|
929
|
+
|
|
930
|
+
ADX / DMI reuse Phase-1 `lib/wilderSmoothing` (`wilderStep`) for
|
|
931
|
+
the per-bar Wilder recurrence and Wave-3 Task-4
|
|
932
|
+
`lib/wilderDirectional` + `lib/adxFromDi` as the property-test
|
|
933
|
+
reference (Float64Array-in / Float64Array-out full-recompute).
|
|
934
|
+
TRIX reuses Phase-1 `lib/emaFloat64` (`computeEmaOfFloat64`) as
|
|
935
|
+
the property-test reference plus the runtime `ta.ema` primitive
|
|
936
|
+
for the four composed sub-slots.
|
|
937
|
+
|
|
938
|
+
Core adds `AdxOpts`, `DmiOpts`, `DmiResult`, `TrixOpts`,
|
|
939
|
+
`TrixResult` exports plus three new methods on `TaNamespace`.
|
|
940
|
+
`STATEFUL_PRIMITIVES` grows by 3 (`ta.adx`, `ta.dmi`, `ta.trix`;
|
|
941
|
+
all `slot: true`). `TA_REGISTRY` mirrors with the leading
|
|
942
|
+
`slotId: string` on each method.
|
|
943
|
+
|
|
944
|
+
- 38fb475: Phase-2 Task 15 — trend ports: `ta.aroon` and `ta.aroonOsc`.
|
|
945
|
+
|
|
946
|
+
Ships two new trend `ta.*` primitives under
|
|
947
|
+
`packages/runtime/src/ta/`:
|
|
948
|
+
|
|
949
|
+
- `ta.aroon(length, opts?)` — Aroon Up / Down (`{ up, down }`,
|
|
950
|
+
both ∈ [0, 100]). Reads `bar.high` / `bar.low` directly per
|
|
951
|
+
Pine's `ta.aroon(length)` signature (no source param). Scans the
|
|
952
|
+
trailing `length + 1` window per close for the argmax / argmin
|
|
953
|
+
using strict `>` / `<` so the most-recent tied bar wins
|
|
954
|
+
(TradingView convention). Tick replay substitutes the head value
|
|
955
|
+
without mutating the closed window.
|
|
956
|
+
- `ta.aroonOsc(length, opts?)` — `aroon.up − aroon.down`, bounded
|
|
957
|
+
in [-100, 100]. Composes `ta.aroon` at sub-slot
|
|
958
|
+
`${slotId}/aroon` so a fix to Aroon flows in for free.
|
|
959
|
+
|
|
960
|
+
Each primitive ships the §22.10 set: impl + unit + property + golden
|
|
961
|
+
|
|
962
|
+
- bench pair + conformance scenario (using the Phase-2 `inlineSource`
|
|
963
|
+
extension from Task 1) + auto-generated `docs/primitives/ta/<id>.md`.
|
|
964
|
+
`TA_REGISTRY_METADATA` carries the multi-output / y-domain hints
|
|
965
|
+
(`aroon: { primarySeriesKey: "up", visibleSeriesKeys: ["up", "down"],
|
|
966
|
+
yDomain: fixed 0-100 }`, `aroonOsc: { yDomain: fixed -100-100 }`).
|
|
967
|
+
|
|
968
|
+
Core adds `AroonOpts`, `AroonOscOpts`, `AroonResult` exports + the
|
|
969
|
+
two `TaNamespace` methods. `STATEFUL_PRIMITIVES` grows by 2
|
|
970
|
+
(`ta.aroon`, `ta.aroonOsc`; both `slot: true`). `TA_REGISTRY`
|
|
971
|
+
mirrors with the leading `slotId: string` on each method.
|
|
972
|
+
|
|
973
|
+
- 38fb475: Phase-2 Task 17 — trend ports: `ta.vortex`, `ta.trendStrengthIndex`,
|
|
974
|
+
`ta.ichimoku`.
|
|
975
|
+
|
|
976
|
+
Ships three new trend `ta.*` primitives under
|
|
977
|
+
`packages/runtime/src/ta/`:
|
|
978
|
+
|
|
979
|
+
- `ta.vortex(length, opts?)` — Botes & Siepman (2010) Vortex
|
|
980
|
+
Indicator. Reads `bar.high` / `bar.low` / `bar.close` directly
|
|
981
|
+
(mirrors Pine's `ta.vortex(length)` — no source param). Returns
|
|
982
|
+
`{ plus, minus }` (the +VI / −VI lines). Maintains rolling
|
|
983
|
+
running-sum windows over per-bar `vmPlus`, `vmMinus`, and TR for
|
|
984
|
+
O(1) per-bar updates. NaN-on-zero-TR semantic per chartlang task
|
|
985
|
+
spec §6 (invinite emits 0 on zero TR; chartlang surfaces the
|
|
986
|
+
degenerate window).
|
|
987
|
+
- `ta.trendStrengthIndex(source, length, opts?)` — TradingView's
|
|
988
|
+
Trend Strength Index: Pearson correlation between `source` and
|
|
989
|
+
bar index over each trailing `length`-bar window. Bounded
|
|
990
|
+
`[-1, +1]`. Default `length = 20` (chartlang task spec; invinite
|
|
991
|
+
default is 14). Distinct from `ta.tsi` (Task 14's True Strength
|
|
992
|
+
Index momentum oscillator) — name collision avoided via the
|
|
993
|
+
longer `trendStrengthIndex` surface.
|
|
994
|
+
- `ta.ichimoku(opts?)` — Ichimoku Cloud (Tenkan / Kijun / Senkou A
|
|
995
|
+
/ Senkou B / Chikou). Defaults `(conversionLength=9, baseLength=
|
|
996
|
+
26, leadingSpanBLength=52, displacement=26)`. Composes six
|
|
997
|
+
`ta.highest` / `ta.lowest` sub-slots (one pair each for Tenkan /
|
|
998
|
+
Kijun / Senkou B) — the same composition seam `ta.donchian` uses
|
|
999
|
+
— so a fix to either rolling-extreme primitive flows in for free.
|
|
1000
|
+
Forward-displaced Senkou A / Senkou B and backward-displaced
|
|
1001
|
+
Chikou are produced via per-slot delay ring buffers of capacity
|
|
1002
|
+
`displacement + 1`. `chikou.current` returns `close[t −
|
|
1003
|
+
displacement]` (the backward-shifted close — programmatic
|
|
1004
|
+
semantic for script-author conditionals).
|
|
1005
|
+
|
|
1006
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
1007
|
+
golden + bench pair + conformance scenario (using the Phase-2
|
|
1008
|
+
`inlineSource` extension from Task 1) + auto-generated
|
|
1009
|
+
`docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries
|
|
1010
|
+
y-domain + multi-output hints:
|
|
1011
|
+
|
|
1012
|
+
- `vortex: { primarySeriesKey: "plus", visibleSeriesKeys:
|
|
1013
|
+
["plus", "minus"], yDomain: auto }`
|
|
1014
|
+
- `trendStrengthIndex: { yDomain: fixed [-1, 1] }`
|
|
1015
|
+
- `ichimoku: { primarySeriesKey: "tenkan", visibleSeriesKeys:
|
|
1016
|
+
["tenkan", "kijun", "senkouA", "senkouB", "chikou"], yDomain:
|
|
1017
|
+
auto }` (the cloud renders via the Task-1 `filled-band` PlotKind
|
|
1018
|
+
between `senkouA` and `senkouB` — script-author drives the
|
|
1019
|
+
styling in their `plot()` call).
|
|
1020
|
+
|
|
1021
|
+
Reuse:
|
|
1022
|
+
|
|
1023
|
+
- Vortex's property test uses Phase-1 `lib/trSeries.ts`
|
|
1024
|
+
(`computeTrSeries`) as the per-bar TR reference; golden test
|
|
1025
|
+
pins the per-output hashes of a 100-bar Mulberry32 fixture.
|
|
1026
|
+
- TrendStrengthIndex's property test uses Wave-3 `lib/pearson.ts`
|
|
1027
|
+
against a linear bar-index series as the reference.
|
|
1028
|
+
- Ichimoku's property test uses Wave-3 `lib/donchianMid.ts` as the
|
|
1029
|
+
per-line reference (Tenkan / Kijun / SenkouB raw all share the
|
|
1030
|
+
same Donchian-midpoint math).
|
|
1031
|
+
|
|
1032
|
+
Core adds `VortexOpts`, `VortexResult`, `TrendStrengthIndexOpts`,
|
|
1033
|
+
`IchimokuOpts`, `IchimokuResult` exports plus three new methods
|
|
1034
|
+
on `TaNamespace` + three throwing stubs on the `ta` const.
|
|
1035
|
+
`STATEFUL_PRIMITIVES` grows by 3 (`ta.vortex`,
|
|
1036
|
+
`ta.trendStrengthIndex`, `ta.ichimoku`; all `slot: true`) — final
|
|
1037
|
+
Phase-2 size 93. `TA_REGISTRY` grows by 3 — final size 90.
|
|
1038
|
+
Conformance scenarios + `ALL_SCENARIOS` array grow by 3.
|
|
1039
|
+
|
|
1040
|
+
- 38fb475: Phase-2 Task 18 — volatility ports: `ta.bbPercentB`, `ta.bbw`, and
|
|
1041
|
+
`ta.donchian`.
|
|
1042
|
+
|
|
1043
|
+
Ships three new volatility `ta.*` primitives under
|
|
1044
|
+
`packages/runtime/src/ta/`:
|
|
1045
|
+
|
|
1046
|
+
- `ta.bbPercentB(source, length, opts?)` — Bollinger %B,
|
|
1047
|
+
`(src − lower) / (upper − lower)` over the BB envelope. NaN
|
|
1048
|
+
when the band collapses (zero width). Composes `ta.bb` via
|
|
1049
|
+
sub-slot `${slotId}/bb` so a fix to the envelope flows in for
|
|
1050
|
+
free. Default `multiplier = 2`.
|
|
1051
|
+
- `ta.bbw(source, length, opts?)` — Bollinger BandWidth,
|
|
1052
|
+
`(upper − lower) / middle` over the BB envelope. Raw ratio
|
|
1053
|
+
scale (multiply by 100 in the script for TradingView-parity
|
|
1054
|
+
display). NaN on zero middle. Composes `ta.bb` via the same
|
|
1055
|
+
sub-slot pattern. Default `multiplier = 2`.
|
|
1056
|
+
- `ta.donchian(length, opts?)` — Donchian Channels,
|
|
1057
|
+
`{ upper, middle, lower }` over a fixed `length`-bar window.
|
|
1058
|
+
`upper = highest(bar.high, length)` and `lower =
|
|
1059
|
+
lowest(bar.low, length)` via sub-slots `${slotId}/highest` /
|
|
1060
|
+
`${slotId}/lowest` — the slot-aware composition of the
|
|
1061
|
+
registered Task-5 primitives; equivalent to `lib/donchianMid`
|
|
1062
|
+
but routed through the registry so a fix flows in for free.
|
|
1063
|
+
Mid = `(upper + lower) / 2`.
|
|
1064
|
+
|
|
1065
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
1066
|
+
golden + bench pair + conformance scenario (using the Phase-2
|
|
1067
|
+
`inlineSource` extension from Task 1) + auto-generated
|
|
1068
|
+
`docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA.donchian`
|
|
1069
|
+
records the multi-output hints (`primarySeriesKey: "middle"`,
|
|
1070
|
+
`visibleSeriesKeys: ["upper", "middle", "lower"]`,
|
|
1071
|
+
`yDomain: { kind: "auto" }`).
|
|
1072
|
+
|
|
1073
|
+
Core adds `BbPercentBOpts`, `BbwOpts`, `DonchianOpts`,
|
|
1074
|
+
`DonchianResult` exports + the three `TaNamespace` methods.
|
|
1075
|
+
`STATEFUL_PRIMITIVES` grows by 3 (all three `slot: true`).
|
|
1076
|
+
`TA_REGISTRY` mirrors with the leading `slotId: string` on each
|
|
1077
|
+
method.
|
|
1078
|
+
|
|
1079
|
+
- 38fb475: Phase-2 Task 20 — volatility ports: `ta.historicalVolatility`,
|
|
1080
|
+
`ta.rvi`, and `ta.massIndex`.
|
|
1081
|
+
|
|
1082
|
+
Ships three new volatility `ta.*` primitives under
|
|
1083
|
+
`packages/runtime/src/ta/`:
|
|
1084
|
+
|
|
1085
|
+
- `ta.historicalVolatility(source, length, opts?)` — annualised
|
|
1086
|
+
stddev of log returns ×100. Default `annualisationFactor = 365`
|
|
1087
|
+
(TradingView's "Crypto" convention; use `252` for trading-day
|
|
1088
|
+
equity series). NaN through `[0, length − 1]` warmup; non-positive
|
|
1089
|
+
or non-finite source short-circuits log returns to NaN.
|
|
1090
|
+
- `ta.rvi(source, length, opts?)` — Relative Volatility Index, the
|
|
1091
|
+
RSI-style oscillator that uses rolling stddev of the source as
|
|
1092
|
+
the magnitude instead of absolute close changes. Bounded `[0, 100]`.
|
|
1093
|
+
Composes `ta.ema` via sub-slots `${slotId}/upEma` and
|
|
1094
|
+
`${slotId}/downEma` so a fix to EMA's recurrence flows in for
|
|
1095
|
+
free. Warmup `2 · length − 1`. NaN on zero-denominator (both EMA
|
|
1096
|
+
arms zero).
|
|
1097
|
+
- `ta.massIndex(opts?)` — sub-pane volatility line that tracks the
|
|
1098
|
+
range-EMA "bulge" ratio to flag trend-reversal setups via the
|
|
1099
|
+
canonical 27 threshold. Reads `bar.high − bar.low` directly (no
|
|
1100
|
+
source param). Composes two chained `ta.ema` sub-slots
|
|
1101
|
+
(`${slotId}/ema1`, `${slotId}/ema2`). Defaults `emaLength = 9`,
|
|
1102
|
+
`sumLength = 25`. Warmup `2 · emaLength + sumLength − 3`.
|
|
1103
|
+
|
|
1104
|
+
Adds the §22.10 five-file set per primitive (impl + unit + property
|
|
1105
|
+
|
|
1106
|
+
- golden + bench pair) and a conformance scenario per primitive
|
|
1107
|
+
under `packages/conformance/src/scenarios/`.
|
|
1108
|
+
|
|
1109
|
+
Extends core's `TaNamespace` + `STATEFUL_PRIMITIVES` and the
|
|
1110
|
+
runtime's `RuntimeTaNamespace` + `TA_REGISTRY` accordingly. Three
|
|
1111
|
+
auto-generated docs pages under `docs/primitives/ta/` ship via the
|
|
1112
|
+
Task-2 `chartlang docs` generator.
|
|
1113
|
+
|
|
1114
|
+
Provenance: ported from invinite at commit
|
|
1115
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`. The RVI math follows
|
|
1116
|
+
invinite's TradingView-reference shape (EMA-smoothed up/down stddev
|
|
1117
|
+
arms), not the spec's draft Wilder-smoothing description.
|
|
1118
|
+
|
|
1119
|
+
- 38fb475: Phase-2 Task 19 — volatility ports: `ta.keltner`, `ta.envelope`, and
|
|
1120
|
+
`ta.chop`.
|
|
1121
|
+
|
|
1122
|
+
Ships three new volatility `ta.*` primitives under
|
|
1123
|
+
`packages/runtime/src/ta/`:
|
|
1124
|
+
|
|
1125
|
+
- `ta.keltner(opts?)` — Keltner Channels overlay envelope.
|
|
1126
|
+
`middle = MA(close, length, maType)` with `upper / lower =
|
|
1127
|
+
middle ± multiplier · ATR(length)`. Defaults `length = 20`,
|
|
1128
|
+
`multiplier = 2`, `maType = "ema"` (TradingView / Linda Raschke
|
|
1129
|
+
canonical form). Composes `ta.atr` via sub-slot `${slotId}/atr`
|
|
1130
|
+
and the registered MA primitive (`sma` / `ema` / `wma` / `smma`)
|
|
1131
|
+
via sub-slot `${slotId}/<maType>` — fixes to either flow in for
|
|
1132
|
+
free.
|
|
1133
|
+
- `ta.envelope(source, opts?)` — price-percent envelope overlay.
|
|
1134
|
+
`middle = MA(source, length, maType)` with `upper / lower =
|
|
1135
|
+
middle · (1 ± percent / 100)`. Defaults `length = 20`,
|
|
1136
|
+
`percent = 10`, `maType = "sma"`. Composes the registered MA
|
|
1137
|
+
primitive via sub-slot `${slotId}/<maType>` so fixes flow in
|
|
1138
|
+
for free.
|
|
1139
|
+
- `ta.chop(length, opts?)` — Choppiness Index sub-pane regime
|
|
1140
|
+
gauge. `chop = 100 · log10(sumTR(length) / (highest(high,
|
|
1141
|
+
length) − lowest(low, length))) / log10(length)`, clamped to
|
|
1142
|
+
`[0, 100]`. High values flag sideways / choppy markets; low
|
|
1143
|
+
values flag strong trends. Composes `ta.highest` / `ta.lowest`
|
|
1144
|
+
via sub-slots; the TR-sum numerator is a sliding-window sum
|
|
1145
|
+
inside the slot (same internal TR math as `ta.atr`, but raw —
|
|
1146
|
+
Pine `ta.chop` does NOT use the Wilder-smoothed ATR).
|
|
1147
|
+
|
|
1148
|
+
Each primitive ships the §22.10 set: impl + unit + property +
|
|
1149
|
+
golden + bench pair + conformance scenario (using the Phase-2
|
|
1150
|
+
`inlineSource` extension from Task 1) + auto-generated
|
|
1151
|
+
`docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA.keltner` and
|
|
1152
|
+
`.envelope` record the multi-output hints
|
|
1153
|
+
(`primarySeriesKey: "middle"`,
|
|
1154
|
+
`visibleSeriesKeys: ["upper", "middle", "lower"]`,
|
|
1155
|
+
`yDomain: { kind: "auto" }`); `TA_REGISTRY_METADATA.chop` pins
|
|
1156
|
+
the bounded `{ yDomain: { kind: "fixed", min: 0, max: 100 } }`
|
|
1157
|
+
oscillator range.
|
|
1158
|
+
|
|
1159
|
+
Core adds `KeltnerOpts`, `KeltnerResult`, `EnvelopeOpts`,
|
|
1160
|
+
`EnvelopeResult`, `ChopOpts` exports + the three `TaNamespace`
|
|
1161
|
+
methods. `STATEFUL_PRIMITIVES` grows by 3 (all three `slot: true`).
|
|
1162
|
+
`TA_REGISTRY` mirrors with the leading `slotId: string` on each
|
|
1163
|
+
method.
|
|
1164
|
+
|
|
1165
|
+
- 38fb475: Phase-2 Task 23 — volume ports `ta.chaikinOsc`, `ta.mfi`,
|
|
1166
|
+
`ta.netVolume`, `ta.pvo`.
|
|
1167
|
+
|
|
1168
|
+
Ports four volume primitives from invinite (commit
|
|
1169
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`) onto the chartlang
|
|
1170
|
+
runtime — each lands the §22.10 five-file set (impl + unit +
|
|
1171
|
+
property + golden + bench pair) alongside an inline conformance
|
|
1172
|
+
scenario and an auto-generated docs page:
|
|
1173
|
+
|
|
1174
|
+
- `ta.chaikinOsc(opts?)` — Chaikin Oscillator, `EMA(ADL, fast) −
|
|
1175
|
+
EMA(ADL, slow)`. Defaults `(3, 10)`. Composes one `ta.adl`
|
|
1176
|
+
sub-slot + two `ta.ema` sub-slots; a fix to either flows in for
|
|
1177
|
+
free. Warmup `slowLength − 1`.
|
|
1178
|
+
- `ta.mfi(length, opts?)` — Money Flow Index, volume-weighted RSI
|
|
1179
|
+
over a trailing window of typical-price comparisons. Bounded
|
|
1180
|
+
`[0, 100]`; emits 100 on perfect upflow, 0 on perfect downflow,
|
|
1181
|
+
NaN on zero total flow (invinite's zero-denominator guard).
|
|
1182
|
+
Warmup `length + 1`.
|
|
1183
|
+
- `ta.netVolume(opts?)` — cumulative `sign(close − prevClose) ·
|
|
1184
|
+
volume`. **Math is identical to `ta.obv`** (both primitives
|
|
1185
|
+
exist in invinite under their own names; chartlang mirrors the
|
|
1186
|
+
public surface for naming parity). Property-tested for
|
|
1187
|
+
hash-equality against `ta.obv` over a 100-bar synthetic walk.
|
|
1188
|
+
Warmup 1 (bar 0 emits 0).
|
|
1189
|
+
- `ta.pvo(opts?)` — Percentage Volume Oscillator, MACD shape on
|
|
1190
|
+
`bar.volume`. Defaults `(12, 26, 9)`. Composes three `ta.ema`
|
|
1191
|
+
sub-slots over volume. Multi-output `{ pvo, signal, hist }`;
|
|
1192
|
+
`TA_REGISTRY_METADATA.pvo` records `primarySeriesKey: "pvo"`,
|
|
1193
|
+
`visibleSeriesKeys: ["pvo", "signal", "hist"]`, `yDomain: {
|
|
1194
|
+
kind: "auto" }`. Warmup `slowLength + signalLength − 2`.
|
|
1195
|
+
|
|
1196
|
+
Surface deltas:
|
|
1197
|
+
|
|
1198
|
+
- `TaNamespace` extends with the four new methods + opts types
|
|
1199
|
+
(`ChaikinOscOpts`, `MfiOpts`, `NetVolumeOpts`, `PvoOpts` +
|
|
1200
|
+
`PvoResult`).
|
|
1201
|
+
- `STATEFUL_PRIMITIVES` grows by four `slot: true` entries.
|
|
1202
|
+
- `TA_REGISTRY` + `RuntimeTaNamespace` mirror the same delta;
|
|
1203
|
+
`TA_REGISTRY_METADATA.pvo` carries the multi-series metadata;
|
|
1204
|
+
`ALL_SCENARIOS` grows by four inline scenarios.
|
|
1205
|
+
|
|
1206
|
+
All four primitives carry the §16.6 100% coverage gate via their
|
|
1207
|
+
five-file test set; golden hashes pinned against `syntheticBars(100,
|
|
1208
|
+
42)` (placeholder pin in the initial commit — repinned on first
|
|
1209
|
+
deterministic green). Per-port bench thresholds reuse the
|
|
1210
|
+
`THRESHOLD_MS = 300` ceiling from the existing volume primitives.
|
|
1211
|
+
|
|
1212
|
+
- 38fb475: Phase-2 Task 22 — volume ports `ta.obv`, `ta.adl`, `ta.bop`, `ta.cmf`.
|
|
1213
|
+
|
|
1214
|
+
Ports four volume primitives from invinite (commit
|
|
1215
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`) onto the chartlang
|
|
1216
|
+
runtime — each lands the §22.10 five-file set (impl + unit +
|
|
1217
|
+
property + golden + bench pair) alongside an inline conformance
|
|
1218
|
+
scenario and an auto-generated docs page:
|
|
1219
|
+
|
|
1220
|
+
- `ta.obv()` — On-Balance Volume, cumulative `sign(close − prevClose) ·
|
|
1221
|
+
volume`. Warmup 1 (bar 0 emits 0). Slot snapshots
|
|
1222
|
+
`prevClosedCumObv` / `prevClosedPrevClose` for tick-mode replay.
|
|
1223
|
+
NaN volume carries the accumulator forward without an update.
|
|
1224
|
+
- `ta.adl()` — Accumulation / Distribution Line, cumulative
|
|
1225
|
+
`((C − L) − (H − C)) / (H − L) · volume`. Warmup 0. Zero-range
|
|
1226
|
+
bars (`high === low`) contribute 0 (matches invinite's CLV
|
|
1227
|
+
guard); NaN OHLC / volume contributes 0.
|
|
1228
|
+
- `ta.bop()` — Balance of Power, raw per-bar `(C − O) / (H − L)`.
|
|
1229
|
+
Warmup 0; stateless math, output buffer only.
|
|
1230
|
+
- `ta.cmf(length)` — Chaikin Money Flow, trailing-window
|
|
1231
|
+
`Σ MFV / Σ volume`. Warmup `length − 1`; bounded `[-1, 1]`.
|
|
1232
|
+
Tick-mode substitutes the head slot's contribution without
|
|
1233
|
+
mutating the rolling window (matches `ulcerIndex`'s shape).
|
|
1234
|
+
|
|
1235
|
+
Surface deltas:
|
|
1236
|
+
|
|
1237
|
+
- `TaNamespace` extends with the four new methods + opts types
|
|
1238
|
+
(`ObvOpts`, `AdlOpts`, `BopOpts`, `CmfOpts` — each `{ offset?;
|
|
1239
|
+
lineStyle? }`).
|
|
1240
|
+
- `STATEFUL_PRIMITIVES` grows by four `slot: true` entries.
|
|
1241
|
+
- `TA_REGISTRY` + `RuntimeTaNamespace` mirror the same delta;
|
|
1242
|
+
`ALL_SCENARIOS` grows by four inline scenarios.
|
|
1243
|
+
|
|
1244
|
+
All four primitives carry the §16.6 100% coverage gate via their
|
|
1245
|
+
five-file test set; golden hashes pinned against `syntheticBars(100,
|
|
1246
|
+
42)`. Per-port bench thresholds reuse the `THRESHOLD_MS = 300`
|
|
1247
|
+
ceiling from the existing volume primitives.
|
|
1248
|
+
|
|
1249
|
+
- 38fb475: Phase-2 Task 24 — volume ports `ta.pvt`, `ta.eom`, `ta.nvi`,
|
|
1250
|
+
`ta.pvi`. Closes the §9.2 volume list (excluding the 4 volume-
|
|
1251
|
+
profile primitives deferred to Phase 5).
|
|
1252
|
+
|
|
1253
|
+
Ports four volume primitives from invinite (commit
|
|
1254
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`) onto the chartlang
|
|
1255
|
+
runtime — each lands the §22.10 five-file set (impl + unit +
|
|
1256
|
+
property + golden + bench pair) alongside an inline conformance
|
|
1257
|
+
scenario and an auto-generated docs page:
|
|
1258
|
+
|
|
1259
|
+
- `ta.pvt(opts?)` — Price Volume Trend, cumulative `volume ·
|
|
1260
|
+
(close − prevClose) / prevClose`. First bar emits 0;
|
|
1261
|
+
zero-prevClose bars emit NaN AND carry the accumulator forward;
|
|
1262
|
+
NaN volume contributes 0. Warmup 1.
|
|
1263
|
+
- `ta.eom(length, opts?)` — Ease of Movement, `length`-bar SMA of
|
|
1264
|
+
per-bar `((midpointMove) / boxRatio)` where `boxRatio = (volume
|
|
1265
|
+
/ 10000) / (high − low)`. Hard-codes invinite's default divisor
|
|
1266
|
+
of 10000. Zero-range / zero-volume / NaN-input bars propagate
|
|
1267
|
+
NaN through the trailing window (forces a clean restart after
|
|
1268
|
+
any defective bar). Warmup `length`.
|
|
1269
|
+
- `ta.nvi(opts?)` — Negative Volume Index, cumulative
|
|
1270
|
+
close-pct-change on bars whose volume is strictly LOWER than the
|
|
1271
|
+
prior bar's; bars with equal-or-higher volume carry the prior
|
|
1272
|
+
value unchanged. Seeded at 1000 (anchor pinned by property
|
|
1273
|
+
test). Warmup 1.
|
|
1274
|
+
- `ta.pvi(opts?)` — Positive Volume Index, mirror of NVI on bars
|
|
1275
|
+
whose volume is strictly HIGHER than the prior bar's. Seeded at 1000. Warmup 1.
|
|
1276
|
+
|
|
1277
|
+
Surface deltas:
|
|
1278
|
+
|
|
1279
|
+
- `TaNamespace` extends with the four new methods + opts types
|
|
1280
|
+
(`PvtOpts`, `EomOpts`, `NviOpts`, `PviOpts`). All four opts
|
|
1281
|
+
bags share the `{ offset?: number; lineStyle?: PlotLineStyle }`
|
|
1282
|
+
shape.
|
|
1283
|
+
- `STATEFUL_PRIMITIVES` grows by four `slot: true` entries
|
|
1284
|
+
(86 → 90; `slot: true` count 85 → 89).
|
|
1285
|
+
- `TA_REGISTRY` + `RuntimeTaNamespace` mirror the same delta
|
|
1286
|
+
(83 → 87). No new `TA_REGISTRY_METADATA` rows — all four are
|
|
1287
|
+
single-output `Series<number>` with auto y-domain.
|
|
1288
|
+
- `ALL_SCENARIOS` grows by four inline scenarios.
|
|
1289
|
+
|
|
1290
|
+
All four primitives carry the §16.6 100% coverage gate via their
|
|
1291
|
+
five-file test set; golden hashes pinned against
|
|
1292
|
+
`syntheticBars(100, 42)` (placeholder pin in the initial commit —
|
|
1293
|
+
repinned on first deterministic green). Per-port bench thresholds
|
|
1294
|
+
reuse the `THRESHOLD_MS = 300` ceiling from the existing volume
|
|
1295
|
+
primitives.
|
|
1296
|
+
|
|
1297
|
+
- 38fb475: Phase-2 Task 21 — port the three foundational volume primitives:
|
|
1298
|
+
|
|
1299
|
+
- **`ta.vol(opts?)`** — passthrough of `bar.volume` as a `Series<number>`.
|
|
1300
|
+
Warmup 0; NaN volume propagates to NaN output.
|
|
1301
|
+
- **`ta.vwap(opts?)`** — session-anchored VWAP keyed on the UTC
|
|
1302
|
+
calendar-day boundary (`floor(bar.time / 86_400_000)`). Phase 4
|
|
1303
|
+
lifts the session detection to `syminfo.session.regularStart` per
|
|
1304
|
+
invinite; until then `ta.vwap` is a UTC-day-anchored VWAP.
|
|
1305
|
+
Source defaults to `"hlc3"` per Pine; accepts `"close"` / `"hl2"` /
|
|
1306
|
+
`"ohlc4"` / `"hlcc4"`.
|
|
1307
|
+
- **`ta.anchoredVwap(anchorTime, opts?)`** — anchored VWAP that
|
|
1308
|
+
starts accumulating at the first bar with `bar.time >= anchorTime`
|
|
1309
|
+
and never resets. The anchor is sticky (captured on the first
|
|
1310
|
+
call; later anchor args are ignored). Phase 4's `input.time()`
|
|
1311
|
+
lifts the anchor to a runtime user input.
|
|
1312
|
+
|
|
1313
|
+
All three carry the §22.10 five-file set + JSDoc with
|
|
1314
|
+
`@formula`/`@warmup`/`@since 0.2`/`@experimental`/`@example`; all
|
|
1315
|
+
register in `STATEFUL_PRIMITIVES` as `slot: true` and in
|
|
1316
|
+
`TA_REGISTRY` / `RuntimeTaNamespace`.
|
|
1317
|
+
|
|
1318
|
+
### `PlotOpts.style?` widening
|
|
1319
|
+
|
|
1320
|
+
To exercise the Task-1 `histogram` PlotKind end-to-end on
|
|
1321
|
+
`ta.vol`, this PR widens the script-facing `PlotOpts` with an
|
|
1322
|
+
optional `style?: PlotOptsStyle` discriminated-union field
|
|
1323
|
+
(`{ kind: "line" }` | `{ kind: "step-line" }` |
|
|
1324
|
+
`{ kind: "histogram"; baseline?: number }`). The runtime's
|
|
1325
|
+
`plot()` impl honours the field; the canvas2d reference adapter
|
|
1326
|
+
dispatches `kind: "histogram"` through Task-1's `drawHistogram`
|
|
1327
|
+
renderer. Backward-compatible — omitting `opts.style` keeps the
|
|
1328
|
+
existing `kind: "line"` default.
|
|
1329
|
+
|
|
1330
|
+
Future ports adding their own PlotKind (e.g. MACD-hist in Task 16,
|
|
1331
|
+
`bars` / `area` / `filled-band` / `label` / `marker` in their
|
|
1332
|
+
consumer ports) extend this same `PlotOptsStyle` union additively
|
|
1333
|
+
and add their dispatch arm to `createCanvas2dAdapter.applyPlot`.
|
|
1334
|
+
|
|
1335
|
+
### Conformance scenarios
|
|
1336
|
+
|
|
1337
|
+
- `taVol.scenario.ts` — `plot(ta.vol(), { style: { kind: "histogram", baseline: 0 } })`.
|
|
1338
|
+
- `taVwap.scenario.ts` — `plot(ta.vwap({ source: "hlc3" }))`.
|
|
1339
|
+
- `taAnchoredVwap.scenario.ts` — `plot(ta.anchoredVwap(1_700_000_000_000))`.
|
|
1340
|
+
|
|
1341
|
+
### Provenance
|
|
1342
|
+
|
|
1343
|
+
All three ports trace to `invinite/src/components/trading-chart/
|
|
1344
|
+
indicators/{vol,vwap,anchored-vwap}.ts` at commit
|
|
1345
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`.
|
|
1346
|
+
|
|
1347
|
+
- b0d296b: Phase 3 closeout — `0.3` "Full Drawing Parity".
|
|
1348
|
+
|
|
1349
|
+
61 drawing kinds across 13 categories ship under `draw.*` with the
|
|
1350
|
+
full §22.10 set per kind (impl + property + golden + bench + JSDoc
|
|
1351
|
+
|
|
1352
|
+
- conformance scenario + auto-generated docs page). 5-bucket
|
|
1353
|
+
`DrawingCounts` budget, per-kind capability gating, `DrawingHandle`
|
|
1354
|
+
across-bar stability, real-impl `validateEmission` + `decodeDrawing`,
|
|
1355
|
+
`drawing-hash` conformance assertion variant, 13 category + 1
|
|
1356
|
+
umbrella capability builders, canvas2d reference adapter renders
|
|
1357
|
+
every kind, `defineDrawing` constructor for interactive tools.
|
|
1358
|
+
|
|
1359
|
+
Final cardinalities: `STATEFUL_PRIMITIVES.size === 154` (93 Phase-2
|
|
1360
|
+
|
|
1361
|
+
- 61 Phase-3 `draw.*` entries); `DRAWING_KINDS.length === 61`.
|
|
1362
|
+
|
|
1363
|
+
Per-bucket kind tally pinned by `bucketFor` (6 + 5 + 6 + 25 + 19 = 61):
|
|
1364
|
+
|
|
1365
|
+
- `lines` (6): `line`, `horizontal-line`, `horizontal-ray`,
|
|
1366
|
+
`vertical-line`, `cross-line`, `trend-angle`.
|
|
1367
|
+
- `boxes` (5): `rectangle`, `rotated-rectangle`, `triangle`,
|
|
1368
|
+
`circle`, `ellipse`.
|
|
1369
|
+
- `labels` (6): `marker`, `text`, `arrow`, `arrow-marker`,
|
|
1370
|
+
`arrow-mark-up`, `arrow-mark-down`.
|
|
1371
|
+
- `polylines` (25): `polyline`, `path`, `arc`, `curve`,
|
|
1372
|
+
`double-curve`, `pen`, `highlighter`, `brush`,
|
|
1373
|
+
`trend-channel`, `flat-top-bottom`, `disjoint-channel`,
|
|
1374
|
+
`regression-trend`, `pitchfork`, `pitchfan`, `xabcd-pattern`,
|
|
1375
|
+
`cypher-pattern`, `head-and-shoulders`, `abcd-pattern`,
|
|
1376
|
+
`triangle-pattern`, `three-drives-pattern`,
|
|
1377
|
+
`elliott-impulse-wave`, `elliott-correction-wave`,
|
|
1378
|
+
`elliott-triangle-wave`, `elliott-double-combo`,
|
|
1379
|
+
`elliott-triple-combo`.
|
|
1380
|
+
- `other` (19): 10 `fib-*` + 4 `gann-*` + 3 cycles
|
|
1381
|
+
(`cyclic-lines`, `time-cycles`, `sine-line`) + 2 containers
|
|
1382
|
+
(`group`, `frame`).
|
|
1383
|
+
|
|
1384
|
+
Conformance scenarios: 61 per-kind + 12 task bundles +
|
|
1385
|
+
`drawAll61` + `drawBudgetOverflow` + `drawUnsupportedKind` = **76**.
|
|
1386
|
+
Docs: 61 auto-generated `docs/primitives/draw/<kind>.md` pages +
|
|
1387
|
+
1 hand-written `index.md`.
|
|
1388
|
+
|
|
1389
|
+
Variant collapses pinned in Task 1 (carried forward unchanged):
|
|
1390
|
+
|
|
1391
|
+
- `pitchfork.variant: "standard" | "schiff" | "modified-schiff" | "inside"`
|
|
1392
|
+
collapses the 4 invinite pitchfork tools.
|
|
1393
|
+
- `line.{extendLeft, extendRight}` collapses the `ray` /
|
|
1394
|
+
`extended-line` tools.
|
|
1395
|
+
- `cypherPattern` ships as a `defineDrawing`-only kind (no
|
|
1396
|
+
standalone interactive tool).
|
|
1397
|
+
|
|
1398
|
+
Compiler: `callsiteIdInjection` recognises every `draw.*` callable
|
|
1399
|
+
via the widened 154-entry `STATEFUL_PRIMITIVES`;
|
|
1400
|
+
`statefulCallInLoop` flags `draw.*` in unbounded loops with the
|
|
1401
|
+
existing `stateful-call-inside-loop` error.
|
|
1402
|
+
|
|
1403
|
+
Bench thresholds (re-verified post-Phase-3 on Apple-silicon):
|
|
1404
|
+
|
|
1405
|
+
- `pushDrawing.bench.test.ts` — 10 000 line drawings under 2 000ms
|
|
1406
|
+
wall-clock (`ceil(median × 3)` per §22.10; no drift across
|
|
1407
|
+
Tasks 4–18 — the budget/validate path is independent of
|
|
1408
|
+
per-kind canvas renderers). `pnpm bench:ci` median ~180ms.
|
|
1409
|
+
- The Phase-2 ta / ringBuffer / seriesView / onBarClose /
|
|
1410
|
+
plot / hline bench thresholds were bumped from the
|
|
1411
|
+
`200/250/300/400/500/600ms` solo-run pins to a uniform `1500ms`
|
|
1412
|
+
(3000ms for plot + hline) to absorb the parallel-worker
|
|
1413
|
+
scheduling overhead during workspace `pnpm test` (665 test
|
|
1414
|
+
files in parallel). Solo `pnpm bench:ci` medians remain in the
|
|
1415
|
+
10–200ms range — well under both old and new thresholds — so
|
|
1416
|
+
this is a noise-floor adjustment, not a perf-regression
|
|
1417
|
+
accommodation.
|
|
1418
|
+
|
|
1419
|
+
`apiVersion: 1` script header unchanged; Phase 3 is additive at
|
|
1420
|
+
runtime.
|
|
1421
|
+
|
|
1422
|
+
- b0d296b: Phase-3 Task 1 — `draw.*` type surface foundation.
|
|
1423
|
+
|
|
1424
|
+
Adds the canonical Phase-3 type surface to `@invinite-org/chartlang-core`:
|
|
1425
|
+
|
|
1426
|
+
- `DrawingKind` — 61-entry kebab-case discriminated union (lines /
|
|
1427
|
+
boxes / curves / freehand / annotations / channels / fib / gann /
|
|
1428
|
+
pitchforks / patterns / elliott / cycles / containers). The
|
|
1429
|
+
kebab-case wire format is the source-of-truth; the camelCase
|
|
1430
|
+
TypeScript surface (`draw.horizontalLine`, `draw.fibRetracement`,
|
|
1431
|
+
…) is pinned via the `KIND_CAMELCASE` / `KIND_KEBABCASE` bijection.
|
|
1432
|
+
- `DRAWING_KINDS` — iterable form of `DrawingKind` in canonical
|
|
1433
|
+
declaration order.
|
|
1434
|
+
- `WorldPoint` + `AnchorPair` / `AnchorTriple` / `AnchorQuad` /
|
|
1435
|
+
`AnchorQuint` / `AnchorHept` helpers.
|
|
1436
|
+
- `DrawingState` — discriminated union with one variant per kind.
|
|
1437
|
+
Geometry + style fields only; collab-only fields (Yjs ids,
|
|
1438
|
+
layerIds, intervals, parentGroupId/FrameId, createdAt, authorId)
|
|
1439
|
+
from the invinite source are stripped per PLAN.md §10.4. Variants
|
|
1440
|
+
are minimal shells in this task; Tasks 5–18 refine per-category
|
|
1441
|
+
payloads.
|
|
1442
|
+
- Per-kind style bag types: `LineDrawStyle`, `ShapeStyle`,
|
|
1443
|
+
`HighlighterStyle`, `BrushStyle`, `TextOpts`, `ArrowOpts`,
|
|
1444
|
+
`ArrowMarkerOpts`, `PathOpts`, `FibOpts`, `RegressionTrendOpts`,
|
|
1445
|
+
`FrameOpts`.
|
|
1446
|
+
- `DrawingHandle` — script-facing handle returned by every
|
|
1447
|
+
`draw.<kind>(...)` call. Impl lives in the runtime (Task 3).
|
|
1448
|
+
- `DrawNamespace` + `FibSubNamespace` / `GannSubNamespace` /
|
|
1449
|
+
`ElliottSubNamespace` / `PatternSubNamespace` — the type the
|
|
1450
|
+
runtime swaps the throwing-stub `draw` Proxy for at boot. The
|
|
1451
|
+
stub mirrors the `plot` / `hline` / `alert` pattern from
|
|
1452
|
+
`plot/plot.ts`.
|
|
1453
|
+
- `DrawingBucket` + `KIND_BUCKET` + `bucketFor(kind)` — canonical
|
|
1454
|
+
kind → bucket map (`lines` / `labels` / `boxes` / `polylines` /
|
|
1455
|
+
`other`). Consumed by the runtime budget enforcer (Task 3) and
|
|
1456
|
+
by adapters that pre-budget.
|
|
1457
|
+
- `DrawingCounts` — moved here from `@invinite-org/chartlang-adapter-kit`
|
|
1458
|
+
so `ScriptManifest.maxDrawings?: DrawingCounts` and
|
|
1459
|
+
`Capabilities.maxDrawingsPerScript` pin the same shape without
|
|
1460
|
+
introducing a `core → adapter-kit` dependency cycle. The
|
|
1461
|
+
`adapter-kit` `DrawingCounts` export is now a type re-export of
|
|
1462
|
+
the core declaration — no public-surface drift, no consumer-visible
|
|
1463
|
+
change.
|
|
1464
|
+
- `ScriptManifest.maxDrawings?: DrawingCounts` + matching
|
|
1465
|
+
`DefineIndicatorOpts.maxDrawings?: DrawingCounts` propagation.
|
|
1466
|
+
|
|
1467
|
+
Extends `STATEFUL_PRIMITIVES` by 61 `draw.<camelKind>` entries (all
|
|
1468
|
+
`slot: true`). Cardinality grows from **93 → 154**. The new entries
|
|
1469
|
+
follow the canonical `DRAWING_KINDS` order. The compiler's
|
|
1470
|
+
`callsiteIdInjection` + `statefulCallInLoop` passes pick them up by
|
|
1471
|
+
name automatically.
|
|
1472
|
+
|
|
1473
|
+
No runtime behavior change in this task — `draw` is a throwing-stub
|
|
1474
|
+
Proxy until Task 3 wires the runtime emit infra. Phase-3 downstream
|
|
1475
|
+
tasks (2–22) all import from this surface.
|
|
1476
|
+
|
|
1477
|
+
- b0d296b: Phase 3 Task 11 — Fibonacci A (`fibRetracement` / `fibTrendExtension`
|
|
1478
|
+
/ `fibChannel` / `fibTimeZone` / `fibWedge`).
|
|
1479
|
+
|
|
1480
|
+
- **core** — `DrawNamespace` flattened: the four sub-namespace types
|
|
1481
|
+
(`FibSubNamespace`, `GannSubNamespace`, `ElliottSubNamespace`,
|
|
1482
|
+
`PatternSubNamespace`) are removed; every kind now lives as a flat
|
|
1483
|
+
method directly on `DrawNamespace` matching the canonical
|
|
1484
|
+
`STATEFUL_PRIMITIVES` names (`draw.fibRetracement(...)`,
|
|
1485
|
+
`draw.gannBox(...)`, `draw.elliottImpulseWave(...)`,
|
|
1486
|
+
`draw.xabcdPattern(...)`, etc.). The throwing-stub `draw` Proxy
|
|
1487
|
+
drops the sub-namespace branch. Script authors use the flat
|
|
1488
|
+
Pine/invinite-parity surface; the compiler resolves callsites
|
|
1489
|
+
through its existing 2-segment property-access path. The 30
|
|
1490
|
+
not-yet-ported method signatures (Tasks 12–18 fib-B / gann /
|
|
1491
|
+
pitchfork / pattern / elliott / cycle / container kinds) are
|
|
1492
|
+
declared as flat stubs so Tasks 12–18 only need to extend the
|
|
1493
|
+
runtime `KIND_IMPLS` map. **BREAKING** for any consumer that
|
|
1494
|
+
referenced `draw.fib.retracement(...)` or one of the four
|
|
1495
|
+
sub-namespace types — none currently exist outside Phase-3 work.
|
|
1496
|
+
- **adapter-kit** — 5 new per-kind validators
|
|
1497
|
+
(`validateFibRetracementState`, `validateFibTrendExtensionState`,
|
|
1498
|
+
`validateFibChannelState`, `validateFibTimeZoneState`,
|
|
1499
|
+
`validateFibWedgeState`) + 1 file-local style helper
|
|
1500
|
+
(`validateFibOpts`) covering FibOpts (`levels` finite-array,
|
|
1501
|
+
`showLabels` / `color` / `extendLeft` / `extendRight`).
|
|
1502
|
+
- **runtime** — 5 new emit functions under
|
|
1503
|
+
`packages/runtime/src/emit/draw/fibA/` wired into `DRAW_NAMESPACE`
|
|
1504
|
+
as flat methods. `fibRetracement` / `fibTimeZone` use the 4-arg
|
|
1505
|
+
form `(slotId, a, b, opts?)`; the other 3 use the 3-arg
|
|
1506
|
+
`(slotId, anchors, opts?)` form. No new sub-namespace wiring.
|
|
1507
|
+
- **canvas2d-adapter** — 5 new renderers reusing Task-4's
|
|
1508
|
+
`FIB_LEVELS` + `formatLevel` and Task-5's `extendLineSegment` for
|
|
1509
|
+
the `fib-retracement` viewport extension. Default colour
|
|
1510
|
+
`"#facc15"` (warm yellow) per invinite's fib-tool palette.
|
|
1511
|
+
- **conformance** — 6 new scenarios (5 per-kind + 1
|
|
1512
|
+
`drawFibA` bundle) with pinned `drawing-hash` assertions.
|
|
1513
|
+
Conformance + scenarios test-capability fixtures grow `other`
|
|
1514
|
+
bucket from 0 to 100 and add the 5 fib-A kebab kinds.
|
|
1515
|
+
|
|
1516
|
+
Divergences flagged in `tasks/phase-3-drawing-parity/11-fibonacci-a.plan.md`:
|
|
1517
|
+
|
|
1518
|
+
- `fib-time-zone` uses the canonical ratio array (`FIB_LEVELS`),
|
|
1519
|
+
NOT the integer Fibonacci sequence; `fibSequence.ts` helper is
|
|
1520
|
+
NOT created (Task-1 reshape follow-up).
|
|
1521
|
+
- `fib-wedge` rays are drawn with a fixed length
|
|
1522
|
+
`max(pxWidth, pxHeight) * 2` rather than via a directional
|
|
1523
|
+
`extendLineSegment` variant.
|
|
1524
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
1525
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–10.
|
|
1526
|
+
|
|
1527
|
+
See `tasks/phase-3-drawing-parity/11-fibonacci-a.plan.md` for the
|
|
1528
|
+
full audit + divergence list.
|
|
1529
|
+
|
|
1530
|
+
- b0d296b: Phase 3 Task 20 — `defineDrawing` constructor + interactive-tool
|
|
1531
|
+
conformance scenarios.
|
|
1532
|
+
|
|
1533
|
+
- **core** — new `defineDrawing(opts)` constructor + `DefineDrawingOpts`
|
|
1534
|
+
type. Mirrors `defineIndicator` structurally; the only differences are
|
|
1535
|
+
`manifest.kind === "drawing"` and `manifest.capabilities ===
|
|
1536
|
+
["drawings"]`. The runtime treats indicator and drawing scripts
|
|
1537
|
+
identically at the per-bar level — the discriminator is a host-side
|
|
1538
|
+
hint the editor uses to distinguish drawing scripts in the
|
|
1539
|
+
script-picker UI (PLAN.md §4.1). The constructor accepts the same
|
|
1540
|
+
Phase-3 `maxDrawings?: DrawingCounts` per-bucket cap propagation as
|
|
1541
|
+
`defineIndicator`.
|
|
1542
|
+
- **compiler** — `analysis/structuralChecks.ts` widens its recognised
|
|
1543
|
+
constructor set to include `defineDrawing` and maps it to
|
|
1544
|
+
`manifest.kind === "drawing"`. `StructuralCheckResult.kind` widens
|
|
1545
|
+
to `"indicator" | "drawing" | "alert"` (matches `buildManifest`'s
|
|
1546
|
+
existing type). The in-memory ambient `.d.ts` shim in `program.ts`
|
|
1547
|
+
declares `DefineDrawingOpts` + `defineDrawing` so a `defineDrawing`
|
|
1548
|
+
script type-checks under the host-machine-independent program.
|
|
1549
|
+
`extractCapabilities` now takes a `kind` parameter and seeds with
|
|
1550
|
+
`"drawings"` (or `"alerts"`) when the script is a `defineDrawing`
|
|
1551
|
+
(or `defineAlert`) — previously every script unconditionally
|
|
1552
|
+
declared `"indicators"`. Error messages on
|
|
1553
|
+
`missing-default-export` / `api-version-mismatch` now mention all
|
|
1554
|
+
three constructor names.
|
|
1555
|
+
- **conformance** — three new bundled scenarios, all default-exporting
|
|
1556
|
+
through `defineDrawing`:
|
|
1557
|
+
|
|
1558
|
+
- `DEFINE_DRAWING_BASIC_SCENARIO` — single `draw.fibRetracement(...)`
|
|
1559
|
+
emission on bar 0 through the new constructor. Verifies the
|
|
1560
|
+
constructor + compiler structural-check + capability extraction
|
|
1561
|
+
- runtime emit path end-to-end. Pinned `drawing-hash`:
|
|
1562
|
+
`eae59a6d44c41ef3b08b20728a9ee723bf0a0cd62e1107c9ab19aa4efa27b488`.
|
|
1563
|
+
- `DRAW_INTERACTIVE_UPDATE_SCENARIO` — captures the
|
|
1564
|
+
`draw.horizontalLine(bar.close)` handle in module-level state
|
|
1565
|
+
on bar 0, then calls `handle.update({ price: bar.close })` on
|
|
1566
|
+
every subsequent bar across the 10 000-bar goldenBars stream.
|
|
1567
|
+
Pins handle-id stability + the full emission sequence (1
|
|
1568
|
+
`create` + 9 999 `update`s). Pinned `drawing-hash`:
|
|
1569
|
+
`797d159809da91f43fc32149998da9e5d71b011134564d42c3e5da2027c22e6f`.
|
|
1570
|
+
- `DRAW_HANDLE_REMOVE_SCENARIO` — creates a `draw.text(...)` on
|
|
1571
|
+
bar 0, calls `handle.remove()` on bar 100 (= time
|
|
1572
|
+
`1_708_640_000_000`; goldenBars are 1-day intervals). Pinned
|
|
1573
|
+
`drawing-hash` captures both the `op: "create"` and
|
|
1574
|
+
`op: "remove"` emissions; `drawing-budget-exceeded` absent.
|
|
1575
|
+
Pinned `drawing-hash`:
|
|
1576
|
+
`b742d39fe5d03cb211b57bc26f0d24a89f9db966c481279368cc083932394a09`.
|
|
1577
|
+
|
|
1578
|
+
Scenario cardinality after Task 20: \*\*61 per-kind + 12 task-bundles
|
|
1579
|
+
|
|
1580
|
+
- 3 (smoke + budget + capability) + 3 (Task-20 constructor) = 79\*\*,
|
|
1581
|
+
of which 78 are in `ALL_SCENARIOS` (the Task-19
|
|
1582
|
+
`DRAW_UNSUPPORTED_KIND_SCENARIO` remains opt-in only).
|
|
1583
|
+
|
|
1584
|
+
### Divergences from spec (`tasks/phase-3-drawing-parity/20-define-drawing.md`)
|
|
1585
|
+
|
|
1586
|
+
1. **Spec § Requirements §1 sketches a `compute` shape and a separate
|
|
1587
|
+
`onCreate(ctx, anchors)` / `onUpdate(handle, ctx, anchors)`
|
|
1588
|
+
callback pair.** Per the team-lead brief + the spec's own example
|
|
1589
|
+
(lines 53–58, which uses `compute`), Phase 3 ships the
|
|
1590
|
+
`compute`-based shape only. The `onCreate`/`onUpdate` interactive-
|
|
1591
|
+
editor callbacks are Phase 4 sugar layered on top of the
|
|
1592
|
+
constructor (PLAN.md §10.1.1).
|
|
1593
|
+
2. **Spec § Requirements §4.2 asks for a new `manifest-kind`
|
|
1594
|
+
`ScenarioAssertion` variant.** Deferred — adding a new assertion
|
|
1595
|
+
variant is a runner-API change out of scope here. The
|
|
1596
|
+
`manifest.kind === "drawing"` contract is covered by unit tests:
|
|
1597
|
+
`defineDrawing.test.ts` (constructor side), `manifest.test.ts`
|
|
1598
|
+
(compiler-builder side), `structuralChecks.test.ts` (AST-walk
|
|
1599
|
+
side), and `compile.test.ts` (end-to-end compile of a
|
|
1600
|
+
`defineDrawing` script). Flag as a Phase-4 follow-up if
|
|
1601
|
+
downstream adapter authors accumulate similar capability/manifest
|
|
1602
|
+
assertions.
|
|
1603
|
+
3. **Spec § Files lists `defineDrawing.types.test.ts`.** Not created.
|
|
1604
|
+
The sibling `defineIndicator.ts` / `defineAlert.ts` don't have
|
|
1605
|
+
`.types.test.ts` files; the typings are covered through the
|
|
1606
|
+
runtime tests' `script.manifest.kind` access.
|
|
1607
|
+
4. **Spec § Requirements §6 mentions a "manifest extractor test in
|
|
1608
|
+
compiler package".** Covered by widening
|
|
1609
|
+
`structuralChecks.test.ts` (which captures `kind` from the
|
|
1610
|
+
AST) + extending `manifest.test.ts` + adding the `compile.test.ts`
|
|
1611
|
+
end-to-end row. No new file needed.
|
|
1612
|
+
5. **`extractCapabilities` widening was not in the original task
|
|
1613
|
+
list** — but is required so a `defineDrawing` script emits
|
|
1614
|
+
`capabilities: ["drawings"]` instead of `["indicators"]`. The
|
|
1615
|
+
change is backwards-compatible (the new `kind` parameter
|
|
1616
|
+
defaults to `"indicator"`) and pinned with new test rows.
|
|
1617
|
+
|
|
1618
|
+
- b0d296b: Phase-3 Task 3 — runtime `draw.*` emission infrastructure.
|
|
1619
|
+
|
|
1620
|
+
**Runtime** — new `packages/runtime/src/emit/draw/` subtree:
|
|
1621
|
+
|
|
1622
|
+
- `createDrawingHandle(slotId, subId, kind, initialState)` allocates
|
|
1623
|
+
a per-handle slot in `ctx.drawingSlots` keyed by `slotId#subId`,
|
|
1624
|
+
emits the first `op: "create"`, and returns a `DrawingHandle`
|
|
1625
|
+
whose `update(patch)` re-emits the FULL merged state under
|
|
1626
|
+
`op: "update"` (PLAN.md §10.3 full-state semantic) and whose
|
|
1627
|
+
`remove()` emits one final `op: "remove"` and flags the slot
|
|
1628
|
+
`removed: true`. Subsequent `update` / `remove` calls on a removed
|
|
1629
|
+
handle no-op. Cross-bar re-entry at the same `slotId#subId`
|
|
1630
|
+
resurrects the slot and emits `op: "update"`.
|
|
1631
|
+
- `pushDrawing(ctx, e)` enforces capability gating
|
|
1632
|
+
(`unsupported-drawing-kind`), wire-shape validation
|
|
1633
|
+
(`malformed-emission`), per-bucket budget on
|
|
1634
|
+
`op: "create"`/`"remove"` against
|
|
1635
|
+
`min(scriptMaxDrawings, adapter.maxDrawingsPerScript)`
|
|
1636
|
+
(`drawing-budget-exceeded`, clamped at zero on remove), and
|
|
1637
|
+
per-bar `(handleId, bar)` dedup (last-write-wins).
|
|
1638
|
+
- `nextSubId(ctx, slotId)` / `resetSubIdCounters(ctx)` —
|
|
1639
|
+
per-callsite per-bar counter; reset at the top of every
|
|
1640
|
+
`onBarClose` / `onBarTick` so iteration `i` at the same callsite
|
|
1641
|
+
yields the same `slotId#i` across bars.
|
|
1642
|
+
- `draw` re-exports core's throwing-stub Proxy verbatim. Per-kind
|
|
1643
|
+
Tasks 5–18 swap real impls into this seam (mirroring how the
|
|
1644
|
+
Phase-2 `ta` re-export switched to `TA_REGISTRY`).
|
|
1645
|
+
|
|
1646
|
+
`RuntimeContext` widens with four new fields: `drawingSlots`,
|
|
1647
|
+
`drawingSubIdCounters`, `drawingBucketCounters`, `scriptMaxDrawings`.
|
|
1648
|
+
`createScriptRunner` initialises them and reads
|
|
1649
|
+
`compiled.manifest.maxDrawings` for the script-side cap. `dispose`
|
|
1650
|
+
clears the slots and resets counters.
|
|
1651
|
+
|
|
1652
|
+
`buildComputeContext` now injects `draw` into the `ComputeContext`
|
|
1653
|
+
the runner hands the compiled script.
|
|
1654
|
+
|
|
1655
|
+
**Core** — `ComputeContext.draw: DrawNamespace` field added (the
|
|
1656
|
+
script-facing surface). Phase-1/-2 scripts that do not consume
|
|
1657
|
+
`draw` keep compiling unchanged; new scripts pick up the namespace
|
|
1658
|
+
through the same destructure pattern as `ta` / `plot` / `hline` /
|
|
1659
|
+
`alert`.
|
|
1660
|
+
|
|
1661
|
+
**Conformance** — `ScenarioAssertion` grows a sixth `drawing-hash`
|
|
1662
|
+
variant. `BufferedRun.drawings` carries the per-bar drained
|
|
1663
|
+
emissions; `hashDrawingSeries(drawings, handleId?)` hashes
|
|
1664
|
+
JSON-stringified `{ handleId, kind, op, state, bar }` tuples in
|
|
1665
|
+
emission order. Failure messages mirror `plot-hash`:
|
|
1666
|
+
`drawing-hash[<label>]: expected <pinned>, actual <computed>
|
|
1667
|
+
(<N> emissions)` — copy `actual` to re-pin.
|
|
1668
|
+
|
|
1669
|
+
No behaviour change for Phase-1/-2 scenarios — the runtime still
|
|
1670
|
+
emits no drawings until the per-kind ports (Tasks 5–18) land.
|
|
1671
|
+
|
|
1672
|
+
- Phase 4 - Editor + Inputs + Timeframes + Tier-1 Pine parity.
|
|
1673
|
+
Adds: input._ builders, state._ / state.tick.\* slots,
|
|
1674
|
+
barstate / syminfo / timeframe views, request.security typed
|
|
1675
|
+
surface (NaN fallback), defineIndicator overrides,
|
|
1676
|
+
Capabilities triad (intervals / multiTimeframe / subPanes /
|
|
1677
|
+
symInfoFields / maxDrawingsPerScript / alertConditions / logs),
|
|
1678
|
+
language-service hover registry + LSP-style API, CodeMirror 6
|
|
1679
|
+
editor shell + /react sub-export, Inputs UI ViewModel + React
|
|
1680
|
+
form. See tasks/phase-4-editor-tier1/README.md.
|
|
1681
|
+
- Add the Phase 4 `input.*` builder namespace and typed input descriptor
|
|
1682
|
+
surface. `InputSchema` now carries `InputDescriptor<unknown>` values,
|
|
1683
|
+
and the compiler ambient shim mirrors the new core declarations so
|
|
1684
|
+
script type resolution stays in lockstep.
|
|
1685
|
+
- Add the Phase 4 `state.*` and `state.tick.*` slot builder surface,
|
|
1686
|
+
including the `MutableSlot<T>` handle type and `ComputeContext.state`.
|
|
1687
|
+
The state builders are compile-time callable holes until the runtime
|
|
1688
|
+
slot implementation lands, and `STATEFUL_PRIMITIVES` now tracks the
|
|
1689
|
+
8 new slot-id-aware state builders.
|
|
1690
|
+
- Add Phase 4 `barstate`, `syminfo`, and `timeframe` core view exports with matching `ComputeContext` types.
|
|
1691
|
+
- Add Phase 4 script override fields to core define options and compiler manifests.
|
|
1692
|
+
- Add the Phase 4 `request.security` core type surface and sentinel callable hole.
|
|
1693
|
+
- Add compiler extraction for static `request.security` intervals and `requiresIntervals`, and register `request.security` for callsite slot ids.
|
|
1694
|
+
- Resolve runtime `input.*` overrides at mount, add adapter input resolver wiring, and audit universal `ta.*` offset support.
|