@tony01/astroneum 0.4.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +237 -0
  2. package/LICENSE +21 -0
  3. package/README.md +198 -0
  4. package/dist/Indicator-BBI3L_lx.d.ts +1181 -0
  5. package/dist/ar-SA-AEPUSRMF.js +2 -0
  6. package/dist/astroneum.css +1 -0
  7. package/dist/chunk-2SN3RH42.js +2 -0
  8. package/dist/chunk-2YYGUSVX.js +3 -0
  9. package/dist/chunk-3GJSZFLM.js +2 -0
  10. package/dist/chunk-4YOLQ5DC.js +2 -0
  11. package/dist/chunk-I4YQBP2M.js +3 -0
  12. package/dist/chunk-OOMZRONH.js +35 -0
  13. package/dist/chunk-PV2GAINM.js +2 -0
  14. package/dist/chunk-SDXH2WAI.js +3 -0
  15. package/dist/chunk-YFPXTHZX.js +2 -0
  16. package/dist/chunk-YW3STIPY.js +653 -0
  17. package/dist/de-DE-4PR3NRQ7.js +2 -0
  18. package/dist/entries/alerts.d.ts +93 -0
  19. package/dist/entries/alerts.js +2 -0
  20. package/dist/entries/datafeeds/crypto.d.ts +65 -0
  21. package/dist/entries/datafeeds/crypto.js +2 -0
  22. package/dist/entries/datafeeds/polygon.d.ts +113 -0
  23. package/dist/entries/datafeeds/polygon.js +2 -0
  24. package/dist/entries/multichart.d.ts +96 -0
  25. package/dist/entries/multichart.js +2 -0
  26. package/dist/entries/portfolio.d.ts +55 -0
  27. package/dist/entries/portfolio.js +2 -0
  28. package/dist/entries/replay.d.ts +141 -0
  29. package/dist/entries/replay.js +2 -0
  30. package/dist/entries/script.d.ts +68 -0
  31. package/dist/entries/script.js +2 -0
  32. package/dist/entries/watchlist.d.ts +43 -0
  33. package/dist/entries/watchlist.js +2 -0
  34. package/dist/es-ES-HNDVPSLW.js +2 -0
  35. package/dist/fr-FR-Y7XWRGF2.js +2 -0
  36. package/dist/hi-IN-KEGIKIMV.js +2 -0
  37. package/dist/id-ID-QXDIUQUZ.js +2 -0
  38. package/dist/index.d.ts +1434 -0
  39. package/dist/index.js +2 -0
  40. package/dist/it-IT-UDTDFSRB.js +2 -0
  41. package/dist/ja-JP-NIODTBW3.js +2 -0
  42. package/dist/ko-KR-DQHPXKBA.js +2 -0
  43. package/dist/nl-NL-BB3ZHCXS.js +2 -0
  44. package/dist/pl-PL-I5MZDLFD.js +2 -0
  45. package/dist/pt-BR-MAMRTOYR.js +2 -0
  46. package/dist/ru-RU-F43D6B7G.js +2 -0
  47. package/dist/th-TH-KTFIUAD6.js +2 -0
  48. package/dist/tr-TR-WFTKJ22Y.js +2 -0
  49. package/dist/vi-VN-CD3WI2FQ.js +2 -0
  50. package/dist/zh-CN-Y2C6RSOI.js +3 -0
  51. package/docs/STRUCTURE.md +231 -0
  52. package/docs/TODO-DESIGN.md +261 -0
  53. package/docs/TODO.md +222 -0
  54. package/docs/api.md +528 -0
  55. package/docs/datafeed-guide.md +311 -0
  56. package/docs/design-astroneum.md +479 -0
  57. package/docs/plugin-development.md +565 -0
  58. package/docs/tv-functions-skill.md +706 -0
  59. package/package.json +147 -0
@@ -0,0 +1,565 @@
1
+ # Plugin & Indicator Development Guide
2
+
3
+ This guide shows how to extend Astroneum with custom indicators, WebGL renderers, chart plugins, and script-based indicators.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Concepts overview](#concepts-overview)
10
+ 2. [IndicatorPlugin — typed TypeScript indicator](#indicatorplugin--typed-typescript-indicator)
11
+ - [Simple scalar output](#simple-scalar-output)
12
+ - [Multi-series output](#multi-series-output)
13
+ - [Canvas 2D renderer (render2D)](#canvas-2d-renderer-render2d)
14
+ - [WebGL2 renderer (renderGL)](#webgl2-renderer-rendergl)
15
+ 3. [ChartPlugin — per-chart lifecycle](#chartplugin--per-chart-lifecycle)
16
+ 4. [Raw engine indicator (IndicatorTemplate)](#raw-engine-indicator-indicatortemplate)
17
+ 5. [ScriptEngine — runtime scripting](#scriptengine--runtime-scripting)
18
+ 6. [Built-in indicator reference](#built-in-indicator-reference)
19
+ 7. [Full API reference](#full-api-reference)
20
+
21
+ ---
22
+
23
+ ## Concepts overview
24
+
25
+ | Layer | When to use |
26
+ |---|---|
27
+ | `IndicatorPlugin` | Custom indicator written in TypeScript with optional Canvas 2D or WebGL2 renderer. **Recommended entry point.** |
28
+ | `ChartPlugin` | Bundle one or more `IndicatorPlugin`s with chart lifecycle hooks (e.g. auto-create on mount, teardown on unmount). |
29
+ | `IndicatorTemplate` (engine) | Direct access to the engine's low-level indicator format. Use when you need full control over figures, drawing, and pane behaviour. |
30
+ | `ScriptEngine` | Let end-users write Pine-Script-inspired JS snippets at runtime without a build step. |
31
+
32
+ ---
33
+
34
+ ## IndicatorPlugin — typed TypeScript indicator
35
+
36
+ ### Interface
37
+
38
+ ```typescript
39
+ interface IndicatorPlugin<TOutput> {
40
+ name: string // unique registry key — used in createIndicator()
41
+ shortName?: string // display name in chart legend (defaults to name)
42
+ calcParams?: number[] // default params, overridable by user
43
+ calc(data: CandleData[], params: number[]): TOutput[]
44
+ render2D?(ctx: CanvasRenderingContext2D, output: TOutput[], viewport: Viewport): void
45
+ renderGL?(gl: WebGL2RenderingContext, output: TOutput[], viewport: Viewport, vbo: WebGLBuffer): void
46
+ }
47
+ ```
48
+
49
+ `calc` is the only required method. `render2D` and `renderGL` are optional custom draw passes.
50
+ When **neither** renderer is provided, Astroneum auto-plots the output values as line(s).
51
+ When `renderGL` is present it runs on a dedicated WebGL2 layer with a stable per-indicator `vbo`.
52
+ If WebGL2 is unavailable in the browser, `render2D` is used as fallback when available.
53
+
54
+ ---
55
+
56
+ ### Simple scalar output
57
+
58
+ Each `calc` return element maps to one candle bar. Return a plain `number` (or `null`) per bar.
59
+
60
+ ```typescript
61
+ import { registerIndicatorPlugin, type IndicatorPlugin, type CandleData } from '@tony01/astroneum'
62
+
63
+ const spreadIndicator: IndicatorPlugin<number> = {
64
+ name: 'SPREAD',
65
+ shortName: 'Spread',
66
+ calc(data: CandleData[]): number[] {
67
+ return data.map(bar => bar.high - bar.low)
68
+ }
69
+ }
70
+
71
+ registerIndicatorPlugin(spreadIndicator)
72
+ ```
73
+
74
+ Then add it to any chart:
75
+
76
+ ```tsx
77
+ <AstroneumChart
78
+ subIndicators={['SPREAD']}
79
+ // or via ref:
80
+ // ref.current.createIndicator('SPREAD')
81
+ ...
82
+ />
83
+ ```
84
+
85
+ ---
86
+
87
+ ### Multi-series output
88
+
89
+ Return an object per bar to plot multiple named lines simultaneously.
90
+
91
+ ```typescript
92
+ interface BandOutput {
93
+ upper: number | null
94
+ middle: number | null
95
+ lower: number | null
96
+ }
97
+
98
+ const donchianChannel: IndicatorPlugin<BandOutput> = {
99
+ name: 'DONCHIAN',
100
+ shortName: 'Donchian',
101
+ calcParams: [20],
102
+ calc(data: CandleData[], [len]: number[]): BandOutput[] {
103
+ return data.map((_, index) => {
104
+ const slice = data.slice(Math.max(0, index - len + 1), index + 1)
105
+ const highs = slice.map(b => b.high)
106
+ const lows = slice.map(b => b.low)
107
+ return {
108
+ upper: Math.max(...highs),
109
+ middle: (Math.max(...highs) + Math.min(...lows)) / 2,
110
+ lower: Math.min(...lows)
111
+ }
112
+ })
113
+ }
114
+ }
115
+
116
+ registerIndicatorPlugin(donchianChannel)
117
+ ```
118
+
119
+ Each key in the returned object becomes a separate series in the chart legend.
120
+ Return `null` for bars where a value is not yet computable (e.g. warm-up period).
121
+
122
+ ---
123
+
124
+ ### Canvas 2D renderer (render2D)
125
+
126
+ Use `render2D` for lightweight overlays (< 10 k points) or any drawing that doesn't need GPU acceleration.
127
+
128
+ The `Viewport` argument describes the currently visible region:
129
+
130
+ ```typescript
131
+ interface Viewport {
132
+ priceMin: number // visible price range bottom
133
+ priceMax: number // visible price range top
134
+ timeMin: number // earliest visible candle timestamp (ms)
135
+ timeMax: number // latest visible candle timestamp (ms)
136
+ resolution: readonly [width: number, height: number] // canvas size in device pixels
137
+ }
138
+ ```
139
+
140
+ ```typescript
141
+ import {
142
+ registerIndicatorPlugin,
143
+ type IndicatorPlugin,
144
+ type CandleData,
145
+ type Viewport
146
+ } from '@tony01/astroneum'
147
+
148
+ interface PivotOutput {
149
+ pivot: number | null
150
+ }
151
+
152
+ const pivotLines: IndicatorPlugin<PivotOutput> = {
153
+ name: 'PIVOT_LINES',
154
+ shortName: 'Pivot',
155
+ calc(data: CandleData[]): PivotOutput[] {
156
+ return data.map((bar, i) => {
157
+ if (i === 0) return { pivot: null }
158
+ const prev = data[i - 1]
159
+ return { pivot: (prev.high + prev.low + prev.close) / 3 }
160
+ })
161
+ },
162
+ render2D(ctx: CanvasRenderingContext2D, output: PivotOutput[], vp: Viewport): void {
163
+ const [width, height] = vp.resolution
164
+ const priceRange = vp.priceMax - vp.priceMin
165
+
166
+ ctx.save()
167
+ ctx.strokeStyle = '#f5a623'
168
+ ctx.lineWidth = 1
169
+ ctx.setLineDash([4, 4])
170
+
171
+ output.forEach(row => {
172
+ if (row.pivot === null) return
173
+ const y = height - ((row.pivot - vp.priceMin) / priceRange) * height
174
+ ctx.beginPath()
175
+ ctx.moveTo(0, y)
176
+ ctx.lineTo(width, y)
177
+ ctx.stroke()
178
+ })
179
+
180
+ ctx.restore()
181
+ }
182
+ }
183
+
184
+ registerIndicatorPlugin(pivotLines)
185
+ ```
186
+
187
+ > **Important:** always call `ctx.save()` / `ctx.restore()` around your draw code.
188
+ > Do not clear the canvas — Astroneum composites multiple layers.
189
+
190
+ ---
191
+
192
+ ### WebGL2 renderer (renderGL)
193
+
194
+ Use `renderGL` for high-density data, smooth anti-aliased lines, or GPU-intensive effects.
195
+
196
+ Astroneum provides a stable `vbo` (vertex buffer object) that persists across frames — upload new data only when your output changes, not every frame.
197
+
198
+ ```typescript
199
+ import {
200
+ registerIndicatorPlugin,
201
+ type IndicatorPlugin,
202
+ type CandleData,
203
+ type Viewport
204
+ } from '@tony01/astroneum'
205
+
206
+ const VERT_SHADER = `#version 300 es
207
+ in vec2 a_pos;
208
+ uniform vec2 u_resolution;
209
+ void main() {
210
+ vec2 clip = (a_pos / u_resolution) * 2.0 - 1.0;
211
+ gl_Position = vec4(clip.x, -clip.y, 0, 1);
212
+ }`
213
+
214
+ const FRAG_SHADER = `#version 300 es
215
+ precision mediump float;
216
+ uniform vec4 u_color;
217
+ out vec4 fragColor;
218
+ void main() { fragColor = u_color; }`
219
+
220
+ function compileProgram (gl: WebGL2RenderingContext): WebGLProgram {
221
+ function shader (type: number, src: string) {
222
+ const sh = gl.createShader(type)!
223
+ gl.shaderSource(sh, src)
224
+ gl.compileShader(sh)
225
+ return sh
226
+ }
227
+ const prog = gl.createProgram()!
228
+ gl.attachShader(prog, shader(gl.VERTEX_SHADER, VERT_SHADER))
229
+ gl.attachShader(prog, shader(gl.FRAGMENT_SHADER, FRAG_SHADER))
230
+ gl.linkProgram(prog)
231
+ return prog
232
+ }
233
+
234
+ let _program: WebGLProgram | null = null
235
+
236
+ interface SMAOutput { value: number | null }
237
+
238
+ const smaGL: IndicatorPlugin<SMAOutput> = {
239
+ name: 'SMA_GL',
240
+ shortName: 'SMA (GL)',
241
+ calcParams: [20],
242
+ calc(data: CandleData[], [len]: number[]): SMAOutput[] {
243
+ return data.map((_, i) => {
244
+ if (i < len - 1) return { value: null }
245
+ const slice = data.slice(i - len + 1, i + 1)
246
+ return { value: slice.reduce((s, b) => s + b.close, 0) / len }
247
+ })
248
+ },
249
+ renderGL(
250
+ gl: WebGL2RenderingContext,
251
+ output: SMAOutput[],
252
+ vp: Viewport,
253
+ vbo: WebGLBuffer
254
+ ): void {
255
+ if (!_program) _program = compileProgram(gl)
256
+
257
+ const [width, height] = vp.resolution
258
+ const priceRange = vp.priceMax - vp.priceMin
259
+ const timeRange = vp.timeMax - vp.timeMin
260
+
261
+ // Build vertex array — one x,y pair per visible bar
262
+ const vertices: number[] = []
263
+ output.forEach((row, i) => {
264
+ if (row.value === null) return
265
+ // map to pixel space; use index ratio as a simple x approximation
266
+ const x = (i / (output.length - 1)) * width
267
+ const y = height - ((row.value - vp.priceMin) / priceRange) * height
268
+ vertices.push(x, y)
269
+ void timeRange // suppress unused warning; use real time mapping in production
270
+ })
271
+ if (vertices.length < 4) return
272
+
273
+ // Upload vertices to the reusable VBO
274
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo)
275
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.DYNAMIC_DRAW)
276
+
277
+ gl.useProgram(_program)
278
+
279
+ const resLoc = gl.getUniformLocation(_program, 'u_resolution')
280
+ const colorLoc = gl.getUniformLocation(_program, 'u_color')
281
+ const posLoc = gl.getAttribLocation(_program, 'a_pos')
282
+
283
+ gl.uniform2f(resLoc, width, height)
284
+ gl.uniform4f(colorLoc, 0.16, 0.38, 1.0, 1.0) // #2962ff
285
+
286
+ gl.enableVertexAttribArray(posLoc)
287
+ gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0)
288
+
289
+ gl.drawArrays(gl.LINE_STRIP, 0, vertices.length / 2)
290
+ }
291
+ }
292
+
293
+ registerIndicatorPlugin(smaGL)
294
+ ```
295
+
296
+ > **Tips:**
297
+ > - Compile shaders once and cache them outside the render function.
298
+ > - The `vbo` is created per indicator and destroyed when the indicator is removed — never delete it manually.
299
+ > - `gl.clear()` is called by Astroneum before your pass; do not call it yourself.
300
+
301
+ ---
302
+
303
+ ## ChartPlugin — per-chart lifecycle
304
+
305
+ Use `ChartPlugin` when you want to:
306
+ - Bundle one or more indicators that auto-create when a chart mounts
307
+ - Run setup logic (subscribe to external data, register hotkeys, etc.)
308
+ - Guarantee cleanup when the chart unmounts
309
+
310
+ ```typescript
311
+ import {
312
+ type ChartPlugin,
313
+ type ChartPluginContext,
314
+ type IndicatorPlugin
315
+ } from '@tony01/astroneum'
316
+
317
+ const vwapIndicator: IndicatorPlugin<number | null> = {
318
+ name: 'VWAP',
319
+ shortName: 'VWAP',
320
+ calc(data) {
321
+ let cumPV = 0, cumVol = 0
322
+ return data.map(bar => {
323
+ const vol = bar.volume ?? 0
324
+ cumPV += ((bar.high + bar.low + bar.close) / 3) * vol
325
+ cumVol += vol
326
+ return cumVol === 0 ? null : cumPV / cumVol
327
+ })
328
+ }
329
+ }
330
+
331
+ const vwapPlugin: ChartPlugin = {
332
+ name: 'vwap-plugin',
333
+ // 1. Register indicator templates before chart creates any indicators
334
+ indicators: [vwapIndicator],
335
+ // 2. Called once after the chart is mounted
336
+ onInit({ chart }: ChartPluginContext) {
337
+ chart.createIndicator('VWAP', true) // true = overlay on main pane
338
+
339
+ // Return a disposer — called when the chart unmounts
340
+ return () => {
341
+ chart.removeIndicator({ name: 'VWAP' })
342
+ }
343
+ }
344
+ }
345
+ ```
346
+
347
+ Pass the plugin as a prop:
348
+
349
+ ```tsx
350
+ <AstroneumChart
351
+ plugins={[vwapPlugin]}
352
+ symbol={...}
353
+ period={...}
354
+ datafeed={...}
355
+ />
356
+ ```
357
+
358
+ Multiple plugins are supported and executed in order. Disposers run in **reverse** order (LIFO).
359
+
360
+ ### `ChartPluginContext`
361
+
362
+ | Property | Type | Description |
363
+ |---|---|---|
364
+ | `chart` | `Chart` | The engine chart instance |
365
+ | `registerIndicatorPlugin` | `(plugin) => void` | Register a single plugin at runtime |
366
+ | `registerIndicatorPlugins` | `(plugins) => void` | Register multiple plugins at runtime |
367
+
368
+ ---
369
+
370
+ ## Raw engine indicator (IndicatorTemplate)
371
+
372
+ For full control — custom figure types, tooltip labels, drawing primitives — use `registerIndicator` directly.
373
+
374
+ ```typescript
375
+ import { registerIndicator, type CandleData } from '@tony01/astroneum'
376
+ import type { IndicatorTemplate } from '@tony01/astroneum' // re-exported from engine
377
+
378
+ const myTemplate: IndicatorTemplate = {
379
+ name: 'MY_INDICATOR',
380
+ shortName: 'My Ind',
381
+ series: 'normal', // 'normal' = sub-pane, 'price' = overlay on candles
382
+ precision: 2,
383
+ calcParams: [14],
384
+ figures: [
385
+ { key: 'value', title: 'Value: ', type: 'line' }
386
+ ],
387
+ calc(dataList: CandleData[], indicator) {
388
+ const [len] = indicator.calcParams
389
+ return dataList.map((_, i) => {
390
+ if (i < len - 1) return { value: null }
391
+ const slice = dataList.slice(i - len + 1, i + 1)
392
+ return { value: slice.reduce((s, b) => s + b.close, 0) / len }
393
+ })
394
+ }
395
+ }
396
+
397
+ registerIndicator(myTemplate)
398
+ ```
399
+
400
+ `getSupportedIndicators()` returns the list of all registered names (built-in + custom).
401
+
402
+ ---
403
+
404
+ ## ScriptEngine — runtime scripting
405
+
406
+ `ScriptEngine` lets end-users write Pine-Script-inspired indicator logic in plain JavaScript without a build step. Scripts run in a strict sandbox with no access to `window`, `document`, `fetch`, or `eval`.
407
+
408
+ ### Usage
409
+
410
+ ```typescript
411
+ import { ScriptEngine, AstroneumChart } from '@tony01/astroneum'
412
+
413
+ const engine = ScriptEngine.getInstance()
414
+
415
+ const template = engine.compile(`
416
+ study('My Oscillator', { overlay: false })
417
+
418
+ const len = input('Length', 14)
419
+ const highs = ta.highest(high, len)
420
+ const lows = ta.lowest(low, len)
421
+ const range = highs.map((h, i) => h - lows[i])
422
+
423
+ plot(range, { title: 'Range', color: '#2962ff' })
424
+ `)
425
+
426
+ // template.name is set from study()
427
+ // Immediately usable in any chart
428
+ chartRef.current.createIndicator(template.name)
429
+ ```
430
+
431
+ ### Script API
432
+
433
+ #### `study(name, options?)`
434
+
435
+ Declares the indicator metadata.
436
+
437
+ | Parameter | Type | Description |
438
+ |---|---|---|
439
+ | `name` | `string` | Indicator name used as registry key |
440
+ | `options.shortName` | `string` | Display label (defaults to `name`) |
441
+ | `options.overlay` | `boolean` | `true` to render on the main price pane |
442
+ | `options.precision` | `number` | Decimal places in tooltip (default `4`) |
443
+
444
+ #### `input(title, defaultValue, options?)`
445
+
446
+ Declares a user-editable parameter. Returns `defaultValue` at compile time.
447
+
448
+ ```javascript
449
+ const length = input('Length', 14)
450
+ const source = input('Source', 'close', { options: ['open', 'high', 'low', 'close'] })
451
+ ```
452
+
453
+ #### `plot(values, options?)`
454
+
455
+ Registers a series to render as a line.
456
+
457
+ | Parameter | Type | Description |
458
+ |---|---|---|
459
+ | `values` | `number[]` | One value per bar; use `null`/`NaN` to skip a bar |
460
+ | `options.title` | `string` | Legend label |
461
+ | `options.color` | `string` | CSS hex color |
462
+ | `options.lineWidth` | `number` | Line thickness in pixels |
463
+
464
+ Call `plot()` multiple times to add multiple lines.
465
+
466
+ #### Built-in data arrays
467
+
468
+ Inside a script the following arrays are automatically available, each with one element per bar in chronological order:
469
+
470
+ | Variable | Description |
471
+ |---|---|
472
+ | `open` | Open prices |
473
+ | `high` | High prices |
474
+ | `low` | Low prices |
475
+ | `close` | Close prices |
476
+ | `volume` | Volume values |
477
+
478
+ #### `ta` — technical analysis helpers
479
+
480
+ | Function | Signature | Description |
481
+ |---|---|---|
482
+ | `ta.sma` | `(src, len)` | Simple moving average |
483
+ | `ta.ema` | `(src, len)` | Exponential moving average |
484
+ | `ta.rma` | `(src, len)` | Wilder's moving average (used in RSI) |
485
+ | `ta.wma` | `(src, len)` | Weighted moving average |
486
+ | `ta.rsi` | `(src, len)` | Relative Strength Index |
487
+ | `ta.bbands` | `(src, len, mult?)` | Bollinger Bands → `{ upper, middle, lower }` |
488
+ | `ta.macd` | `(src, fast?, slow?, signal?)` | MACD → `{ macd, signal, histogram }` |
489
+ | `ta.highest` | `(src, len)` | Rolling maximum |
490
+ | `ta.lowest` | `(src, len)` | Rolling minimum |
491
+ | `ta.stdev` | `(src, len)` | Rolling standard deviation |
492
+ | `ta.cross` | `(a, b)` | Cross in either direction → `boolean[]` |
493
+ | `ta.crossover` | `(a, b)` | Cross upward → `boolean[]` |
494
+ | `ta.crossunder` | `(a, b)` | Cross downward → `boolean[]` |
495
+
496
+ `math` is also available as an alias for `Math`.
497
+
498
+ ### Complete script example — MACD
499
+
500
+ ```javascript
501
+ study('MACD', { overlay: false })
502
+
503
+ const fast = input('Fast', 12)
504
+ const slow = input('Slow', 26)
505
+ const signal = input('Signal', 9)
506
+
507
+ const { macd, signal: signalLine, histogram } = ta.macd(close, fast, slow, signal)
508
+
509
+ plot(macd, { title: 'MACD', color: '#2962ff' })
510
+ plot(signalLine, { title: 'Signal', color: '#ff6b35' })
511
+ plot(histogram, { title: 'Hist', color: '#26a69a' })
512
+ ```
513
+
514
+ ### ScriptEngine instance methods
515
+
516
+ | Method | Description |
517
+ |---|---|
518
+ | `compile(source, name?)` | Compile source string, register indicator, return `CompiledIndicator`. Throws on syntax/runtime error. |
519
+ | `get(name)` | Return a previously compiled template by name |
520
+ | `list()` | Return all compiled indicator names |
521
+ | `remove(name)` | Remove a compiled indicator from the registry |
522
+
523
+ ---
524
+
525
+ ## Built-in indicator reference
526
+
527
+ All built-in indicators are available by name via `createIndicator()` or the `subIndicators` / `mainIndicators` props.
528
+
529
+ | Name | Description |
530
+ |---|---|
531
+ | `MA` | Moving Average |
532
+ | `EMA` | Exponential Moving Average |
533
+ | `SMA` | Simple Moving Average |
534
+ | `BOLL` | Bollinger Bands |
535
+ | `MACD` | MACD |
536
+ | `RSI` | Relative Strength Index |
537
+ | `KDJ` | Stochastic KDJ |
538
+ | `VOL` | Volume |
539
+ | `OBV` | On Balance Volume |
540
+ | `AVP` | Average Price |
541
+ | `AO` | Awesome Oscillator |
542
+ | `BIAS` | BIAS |
543
+ | `BRAR` | BRAR |
544
+ | `BBI` | Bull & Bear Index |
545
+ | `CCI` | Commodity Channel Index |
546
+ | `CR` | Current Ratio |
547
+ | `DMA` | Different of Moving Average |
548
+ | `DMI` | Directional Movement Index |
549
+ | `EMV` | Ease of Movement |
550
+ | `MTM` | Momentum |
551
+ | `PVT` | Price & Volume Trend |
552
+ | `PSY` | Psychological Line |
553
+ | `ROC` | Rate of Change |
554
+ | `SAR` | Stop and Reverse |
555
+ | `TRIX` | Triple Exponentially Smoothed Average |
556
+ | `VR` | Volume Ratio |
557
+ | `WR` | Williams %R |
558
+
559
+ Use `getSupportedIndicators()` at runtime to retrieve the complete list including any custom-registered indicators.
560
+
561
+ ---
562
+
563
+ ## Full API reference
564
+
565
+ See [api.md](api.md) for the complete type reference including `IndicatorPlugin`, `ChartPlugin`, `ChartPluginContext`, `Viewport`, `registerIndicatorPlugin`, `registerIndicatorPlugins`, `createIndicatorTemplateFromPlugin`, `registerIndicator`, `getSupportedIndicators`, and `ScriptEngine`.