oakscriptjs 0.9.6 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/array/index.d.ts +9 -23
  3. package/dist/cjs/array/index.d.ts.map +1 -1
  4. package/dist/cjs/array/index.js +4 -0
  5. package/dist/cjs/array/index.js.map +2 -2
  6. package/dist/cjs/drawing/bar-time.d.ts +24 -0
  7. package/dist/cjs/drawing/bar-time.d.ts.map +1 -0
  8. package/dist/cjs/drawing/bar-time.js +47 -0
  9. package/dist/cjs/drawing/bar-time.js.map +7 -0
  10. package/dist/cjs/drawing/output.d.ts +32 -0
  11. package/dist/cjs/drawing/output.d.ts.map +1 -0
  12. package/dist/cjs/drawing/output.js +184 -0
  13. package/dist/cjs/drawing/output.js.map +7 -0
  14. package/dist/cjs/drawing/registry.d.ts +5 -4
  15. package/dist/cjs/drawing/registry.d.ts.map +1 -1
  16. package/dist/cjs/drawing/registry.js +11 -2
  17. package/dist/cjs/drawing/registry.js.map +2 -2
  18. package/dist/cjs/index.d.ts +6 -3
  19. package/dist/cjs/index.d.ts.map +1 -1
  20. package/dist/cjs/index.js +9 -2
  21. package/dist/cjs/index.js.map +2 -2
  22. package/dist/cjs/polyline/index.d.ts +3 -5
  23. package/dist/cjs/polyline/index.d.ts.map +1 -1
  24. package/dist/cjs/polyline/index.js +0 -5
  25. package/dist/cjs/polyline/index.js.map +2 -2
  26. package/dist/cjs/runtime/types.d.ts +22 -0
  27. package/dist/cjs/runtime/types.d.ts.map +1 -1
  28. package/dist/cjs/runtime/types.js.map +1 -1
  29. package/dist/cjs/script/index.d.ts +82 -5
  30. package/dist/cjs/script/index.d.ts.map +1 -1
  31. package/dist/cjs/script/index.js +141 -26
  32. package/dist/cjs/script/index.js.map +3 -3
  33. package/dist/cjs/table/index.d.ts +87 -0
  34. package/dist/cjs/table/index.d.ts.map +1 -0
  35. package/dist/cjs/table/index.js +150 -0
  36. package/dist/cjs/table/index.js.map +7 -0
  37. package/dist/cjs/text/index.d.ts +17 -2
  38. package/dist/cjs/text/index.d.ts.map +1 -1
  39. package/dist/cjs/text/index.js +15 -1
  40. package/dist/cjs/text/index.js.map +2 -2
  41. package/dist/cjs/types/index.d.ts +30 -1
  42. package/dist/cjs/types/index.d.ts.map +1 -1
  43. package/dist/cjs/types/index.js +12 -0
  44. package/dist/cjs/types/index.js.map +2 -2
  45. package/dist/cjs/types/metadata.d.ts +258 -26
  46. package/dist/cjs/types/metadata.d.ts.map +1 -1
  47. package/dist/cjs/types/metadata.js.map +1 -1
  48. package/dist/esm/array/index.d.ts +9 -23
  49. package/dist/esm/array/index.d.ts.map +1 -1
  50. package/dist/esm/array/index.js +10 -22
  51. package/dist/esm/array/index.js.map +1 -1
  52. package/dist/esm/drawing/bar-time.d.ts +24 -0
  53. package/dist/esm/drawing/bar-time.d.ts.map +1 -0
  54. package/dist/esm/drawing/bar-time.js +44 -0
  55. package/dist/esm/drawing/bar-time.js.map +1 -0
  56. package/dist/esm/drawing/output.d.ts +32 -0
  57. package/dist/esm/drawing/output.d.ts.map +1 -0
  58. package/dist/esm/drawing/output.js +190 -0
  59. package/dist/esm/drawing/output.js.map +1 -0
  60. package/dist/esm/drawing/registry.d.ts +5 -4
  61. package/dist/esm/drawing/registry.d.ts.map +1 -1
  62. package/dist/esm/drawing/registry.js +12 -2
  63. package/dist/esm/drawing/registry.js.map +1 -1
  64. package/dist/esm/index.d.ts +6 -3
  65. package/dist/esm/index.d.ts.map +1 -1
  66. package/dist/esm/index.js +7 -3
  67. package/dist/esm/index.js.map +1 -1
  68. package/dist/esm/polyline/index.d.ts +3 -5
  69. package/dist/esm/polyline/index.d.ts.map +1 -1
  70. package/dist/esm/polyline/index.js +3 -9
  71. package/dist/esm/polyline/index.js.map +1 -1
  72. package/dist/esm/runtime/types.d.ts +22 -0
  73. package/dist/esm/runtime/types.d.ts.map +1 -1
  74. package/dist/esm/script/index.d.ts +82 -5
  75. package/dist/esm/script/index.d.ts.map +1 -1
  76. package/dist/esm/script/index.js +167 -21
  77. package/dist/esm/script/index.js.map +1 -1
  78. package/dist/esm/table/index.d.ts +87 -0
  79. package/dist/esm/table/index.d.ts.map +1 -0
  80. package/dist/esm/table/index.js +169 -0
  81. package/dist/esm/table/index.js.map +1 -0
  82. package/dist/esm/text/index.d.ts +17 -2
  83. package/dist/esm/text/index.d.ts.map +1 -1
  84. package/dist/esm/text/index.js +17 -2
  85. package/dist/esm/text/index.js.map +1 -1
  86. package/dist/esm/types/index.d.ts +30 -1
  87. package/dist/esm/types/index.d.ts.map +1 -1
  88. package/dist/esm/types/index.js +14 -0
  89. package/dist/esm/types/index.js.map +1 -1
  90. package/dist/esm/types/metadata.d.ts +258 -26
  91. package/dist/esm/types/metadata.d.ts.map +1 -1
  92. package/package.json +1 -1
  93. package/src/array/index.ts +12 -23
  94. package/src/drawing/bar-time.ts +42 -0
  95. package/src/drawing/output.ts +214 -0
  96. package/src/drawing/registry.ts +16 -6
  97. package/src/index.ts +9 -3
  98. package/src/polyline/index.ts +3 -12
  99. package/src/runtime/types.ts +23 -0
  100. package/src/script/index.ts +254 -24
  101. package/src/table/index.ts +221 -0
  102. package/src/text/index.ts +18 -2
  103. package/src/types/index.ts +32 -1
  104. package/src/types/metadata.ts +325 -26
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Renderable form of the live drawing objects (labels, lines, boxes, linefills, polylines, tables): the
3
+ * `IndicatorResult` fields `labels`, `lines`, `boxes`, `linefills`, `polylines` and `tables`.
4
+ *
5
+ * Conversion rules:
6
+ * - x coordinates become bar times: a `bar_index` x is the time of that bar, or of a future bar after the last bar
7
+ * (see {@link barTime}); a `bar_time` x (UNIX ms, as PineScript) is converted to the unit of the bar times
8
+ * - an object with an `na` coordinate (or a bar index before the first bar) is not drawn, as in PineScript
9
+ * - a property the script did not set is omitted (the renderer uses the PineScript default); a colour set to `na`
10
+ * is 'transparent'
11
+ * - `force_overlay` is kept only when true
12
+ *
13
+ * @module drawing/output
14
+ */
15
+
16
+ import { all } from './registry.js';
17
+ import { barInterval, barTime } from './bar-time.js';
18
+ import type { Box, ChartPoint, Label, Line, Polyline, Table, color } from '../types/index.js';
19
+ import type {
20
+ BoxData,
21
+ LabelData,
22
+ LineDrawingData,
23
+ LinefillData,
24
+ PolylineData,
25
+ TableCellData,
26
+ TableData,
27
+ } from '../types/metadata.js';
28
+
29
+ /** Drawing fields of an IndicatorResult; a kind without live objects is undefined. */
30
+ export interface DrawingOutputs {
31
+ labels?: LabelData[];
32
+ lines?: LineDrawingData[];
33
+ boxes?: BoxData[];
34
+ linefills?: LinefillData[];
35
+ polylines?: PolylineData[];
36
+ tables?: TableData[];
37
+ }
38
+
39
+ /** A colour of the result: 'transparent' for na (null), '#rrggbb' for a numeric colour. */
40
+ function colorOut(c: color | null | undefined): string | undefined {
41
+ if (c === undefined) return undefined;
42
+ if (c === null || (typeof c === 'number' && Number.isNaN(c))) return 'transparent';
43
+ return typeof c === 'number' ? `#${(c & 0xffffff).toString(16).padStart(6, '0')}` : c;
44
+ }
45
+
46
+ /** The object without its undefined fields (so that the result has only the properties that were set). */
47
+ function compact<T extends object>(obj: T): T {
48
+ for (const k of Object.keys(obj) as Array<keyof T>) if (obj[k] === undefined) delete obj[k];
49
+ return obj;
50
+ }
51
+
52
+ const overlay = (flag: boolean | undefined): true | undefined => (flag ? true : undefined);
53
+
54
+ /**
55
+ * Converts the live drawing objects of the registry. `bars` are the chart bars (their `time` in `timeUnit`, 's' by
56
+ * default as lightweight-charts); they give the time of a bar index.
57
+ */
58
+ export function drawingOutputs(bars: ReadonlyArray<{ time: number }>, timeUnit: 's' | 'ms' = 's'): DrawingOutputs {
59
+ const interval = barInterval(bars);
60
+ const msUnit = timeUnit === 'ms' ? 1 : 1000;
61
+ const xTime = (x: number, xloc: 'bar_index' | 'bar_time'): number =>
62
+ xloc === 'bar_time' ? x / msUnit : barTime(bars, x, interval);
63
+ const ok = (...values: number[]): boolean => values.every(Number.isFinite);
64
+
65
+ const lineData = (l: Line): LineDrawingData | undefined => {
66
+ const time1 = xTime(l.x1, l.xloc);
67
+ const time2 = xTime(l.x2, l.xloc);
68
+ if (!ok(time1, time2, l.y1, l.y2)) return undefined;
69
+ return compact({
70
+ time1,
71
+ price1: l.y1,
72
+ time2,
73
+ price2: l.y2,
74
+ color: colorOut(l.color),
75
+ width: l.width,
76
+ style: l.style,
77
+ extend: l.extend,
78
+ forceOverlay: overlay(l.force_overlay),
79
+ });
80
+ };
81
+
82
+ const labelData = (l: Label): LabelData | undefined => {
83
+ const time = xTime(l.x, l.xloc);
84
+ // abovebar / belowbar labels are placed at the bar, not at y
85
+ if (!ok(time) || (l.yloc === 'price' && !ok(l.y))) return undefined;
86
+ return compact({
87
+ time,
88
+ price: l.y,
89
+ text: l.text ?? '',
90
+ color: colorOut(l.color),
91
+ textColor: colorOut(l.textcolor),
92
+ style: l.style,
93
+ size: l.size as LabelData['size'],
94
+ yloc: l.yloc,
95
+ textAlign: l.textalign,
96
+ tooltip: l.tooltip,
97
+ fontFamily: l.text_font_family,
98
+ textFormatting: l.text_formatting,
99
+ forceOverlay: overlay(l.force_overlay),
100
+ });
101
+ };
102
+
103
+ const boxData = (b: Box): BoxData | undefined => {
104
+ const time1 = xTime(b.left, b.xloc);
105
+ const time2 = xTime(b.right, b.xloc);
106
+ if (!ok(time1, time2, b.top, b.bottom)) return undefined;
107
+ return compact({
108
+ time1,
109
+ price1: b.top,
110
+ time2,
111
+ price2: b.bottom,
112
+ bgColor: colorOut(b.bgcolor),
113
+ borderColor: colorOut(b.border_color),
114
+ borderWidth: b.border_width,
115
+ borderStyle: b.border_style,
116
+ text: b.text,
117
+ textColor: colorOut(b.text_color),
118
+ textSize: b.text_size as BoxData['textSize'],
119
+ textHAlign: b.text_halign,
120
+ textVAlign: b.text_valign,
121
+ textWrap: b.text_wrap,
122
+ fontFamily: b.text_font_family,
123
+ textFormatting: b.text_formatting,
124
+ extend: b.extend,
125
+ forceOverlay: overlay(b.force_overlay),
126
+ });
127
+ };
128
+
129
+ const polylineData = (p: Polyline): PolylineData | undefined => {
130
+ const points: PolylineData['points'] = [];
131
+ for (const point of p.points as ChartPoint[]) {
132
+ const x = p.xloc === 'bar_time' ? point.time : point.index;
133
+ const time = x === null ? NaN : xTime(x, p.xloc);
134
+ if (ok(time, point.price)) points.push({ time, price: point.price });
135
+ }
136
+ if (points.length === 0) return undefined;
137
+ return compact({
138
+ points,
139
+ curved: p.curved,
140
+ closed: p.closed,
141
+ lineColor: colorOut(p.line_color),
142
+ fillColor: p.fill_color === null ? undefined : colorOut(p.fill_color),
143
+ lineStyle: p.line_style,
144
+ lineWidth: p.line_width,
145
+ forceOverlay: overlay(p.force_overlay),
146
+ });
147
+ };
148
+
149
+ const tableData = (t: Table): TableData => {
150
+ const cells: TableCellData[] = [];
151
+ for (const [key, c] of t.cells ?? []) {
152
+ const [column, row] = key.split(',').map(Number) as [number, number];
153
+ cells.push(
154
+ compact({
155
+ row,
156
+ column,
157
+ text: c.text ?? '',
158
+ bgColor: colorOut(c.bgcolor),
159
+ textColor: colorOut(c.text_color),
160
+ textSize: c.text_size as TableCellData['textSize'],
161
+ width: c.width,
162
+ height: c.height,
163
+ textHAlign: c.text_halign,
164
+ textVAlign: c.text_valign,
165
+ tooltip: c.tooltip,
166
+ fontFamily: c.text_font_family,
167
+ textFormatting: c.text_formatting,
168
+ })
169
+ );
170
+ }
171
+ cells.sort((a, b) => a.row - b.row || a.column - b.column);
172
+ const merges = (t.merges ?? []).map((m) => ({
173
+ startColumn: m.start_column,
174
+ startRow: m.start_row,
175
+ endColumn: m.end_column,
176
+ endRow: m.end_row,
177
+ }));
178
+ return compact({
179
+ position: t.position,
180
+ columns: t.columns,
181
+ rows: t.rows,
182
+ cells,
183
+ merges: merges.length ? merges : undefined,
184
+ bgColor: colorOut(t.bgcolor),
185
+ frameColor: colorOut(t.frame_color),
186
+ frameWidth: t.frame_width,
187
+ borderColor: colorOut(t.border_color),
188
+ borderWidth: t.border_width,
189
+ forceOverlay: overlay(t.force_overlay),
190
+ });
191
+ };
192
+
193
+ const convert = <T, R>(items: T[], fn: (item: T) => R | undefined): R[] | undefined => {
194
+ const out: R[] = [];
195
+ for (const item of items) {
196
+ const r = fn(item);
197
+ if (r !== undefined) out.push(r);
198
+ }
199
+ return out.length ? out : undefined;
200
+ };
201
+
202
+ return {
203
+ labels: convert(all('label'), labelData),
204
+ lines: convert(all('line'), lineData),
205
+ boxes: convert(all('box'), boxData),
206
+ linefills: convert(all('linefill'), (f): LinefillData | undefined => {
207
+ const line1 = lineData(f.line1);
208
+ const line2 = lineData(f.line2);
209
+ return line1 && line2 ? compact({ line1, line2, color: colorOut(f.color) }) : undefined;
210
+ }),
211
+ polylines: convert(all('polyline'), polylineData),
212
+ tables: convert(all('table'), tableData),
213
+ };
214
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Registry of the live drawing objects (lines, labels, boxes, polylines, linefills), as PineScript
2
+ * Registry of the live drawing objects (lines, labels, boxes, polylines, linefills, tables), as PineScript
3
3
  * keeps them. PineScript rules:
4
4
  *
5
5
  * - `line.all`, `label.all`, ... list the live objects in creation order (a copy of the list)
@@ -15,9 +15,9 @@
15
15
  * @module drawing/registry
16
16
  */
17
17
 
18
- import type { Box, Label, Line, Linefill, Polyline } from '../types/index.js';
18
+ import type { Box, Label, Line, Linefill, Polyline, Table } from '../types/index.js';
19
19
 
20
- export type DrawingKind = 'line' | 'label' | 'box' | 'polyline' | 'linefill';
20
+ export type DrawingKind = 'line' | 'label' | 'box' | 'polyline' | 'linefill' | 'table';
21
21
 
22
22
  interface DrawingTypes {
23
23
  line: Line;
@@ -25,6 +25,7 @@ interface DrawingTypes {
25
25
  box: Box;
26
26
  polyline: Polyline;
27
27
  linefill: Linefill;
28
+ table: Table;
28
29
  }
29
30
 
30
31
  /** Default `max_lines_count`, `max_labels_count`, `max_boxes_count`, `max_polylines_count`. */
@@ -32,9 +33,16 @@ export const DEFAULT_MAX_COUNT = 50;
32
33
  /** Objects above the maximum that PineScript keeps before it deletes the oldest ones. */
33
34
  const SLACK = 5;
34
35
 
35
- export type DrawingLimits = Partial<Record<Exclude<DrawingKind, 'linefill'>, number>>;
36
+ export type DrawingLimits = Partial<Record<Exclude<DrawingKind, 'linefill' | 'table'>, number>>;
36
37
 
37
- const live: { [K in DrawingKind]: Array<DrawingTypes[K]> } = { line: [], label: [], box: [], polyline: [], linefill: [] };
38
+ const live: { [K in DrawingKind]: Array<DrawingTypes[K]> } = {
39
+ line: [],
40
+ label: [],
41
+ box: [],
42
+ polyline: [],
43
+ linefill: [],
44
+ table: [],
45
+ };
38
46
  let limits: Required<DrawingLimits> = {
39
47
  line: DEFAULT_MAX_COUNT,
40
48
  label: DEFAULT_MAX_COUNT,
@@ -50,6 +58,7 @@ const COORDINATES: { [K in DrawingKind]: Array<keyof DrawingTypes[K]> } = {
50
58
  box: ['left', 'top', 'right', 'bottom'],
51
59
  polyline: [],
52
60
  linefill: [],
61
+ table: [],
53
62
  };
54
63
 
55
64
  function markDeleted<K extends DrawingKind>(kind: K, obj: DrawingTypes[K], explicit: boolean): void {
@@ -64,7 +73,8 @@ function markDeleted<K extends DrawingKind>(kind: K, obj: DrawingTypes[K], expli
64
73
  export function register<K extends DrawingKind>(kind: K, obj: DrawingTypes[K]): DrawingTypes[K] {
65
74
  const list = live[kind];
66
75
  list.push(obj);
67
- const max = limits[kind === 'linefill' ? 'line' : (kind as Exclude<DrawingKind, 'linefill'>)];
76
+ if (kind === 'table') return obj; // tables have no maximum count
77
+ const max = limits[kind === 'linefill' ? 'line' : (kind as keyof DrawingLimits)];
68
78
  if (list.length > max + SLACK) {
69
79
  for (const old of list.splice(0, list.length - max)) markDeleted(kind, old, false);
70
80
  }
package/src/index.ts CHANGED
@@ -32,11 +32,16 @@ import * as label from './label/index.js';
32
32
  import * as linefill from './linefill/index.js';
33
33
  import * as chartPoint from './chartpoint/index.js';
34
34
  import * as polyline from './polyline/index.js';
35
+ import * as table from './table/index.js';
35
36
  import * as text from './text/index.js';
36
37
  import * as compare from './compare/index.js';
37
38
  import * as callsite from './callsite/index.js';
38
39
 
39
- export { taCore, math, array, map, str, color, time, timeframe, matrix, line, box, label, linefill, chartPoint, polyline, text, compare, callsite };
40
+ export { taCore, math, array, map, str, color, time, timeframe, matrix, line, box, label, linefill, chartPoint, polyline, table, text, compare, callsite };
41
+
42
+ // Renderable drawings (IndicatorResult labels, lines, boxes, linefills, polylines, tables) and future bar times
43
+ export { drawingOutputs, type DrawingOutputs } from './drawing/output.js';
44
+ export { barInterval, barTime } from './drawing/bar-time.js';
40
45
 
41
46
  // Export Series class (self-contained, no context)
42
47
  export { Series, BarData } from './runtime/series.js';
@@ -148,6 +153,7 @@ export type {
148
153
  HLineConfig,
149
154
  FillConfig,
150
155
  ArrowConfig,
156
+ CandleConfig,
151
157
  } from './runtime/types.js';
152
158
 
153
159
  // Strategy types and constants (the script API forwards strategy.* calls to a host engine)
@@ -164,7 +170,7 @@ export type { LightweightSeriesDefinitions } from './runtime/adapters/Lightweigh
164
170
  export { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';
165
171
 
166
172
  // Version
167
- export const VERSION = '0.9.6';
173
+ export const VERSION = '0.10.0';
168
174
 
169
175
  /**
170
176
  * Library information
@@ -182,7 +188,7 @@ export const info = {
182
188
  },
183
189
  namespaces: {
184
190
  core: ['ta', 'math', 'array', 'map', 'str', 'color', 'time', 'timeframe', 'matrix'],
185
- drawing: ['line', 'box', 'label', 'linefill', 'chartPoint', 'polyline', 'text'],
191
+ drawing: ['line', 'box', 'label', 'linefill', 'chartPoint', 'polyline', 'table', 'text'],
186
192
  runtime: ['setContext', 'plot', 'hline', 'input_*'],
187
193
  indicator: ['indicator', 'input', 'plotHelper', 'createPlot']
188
194
  }
@@ -4,8 +4,8 @@
4
4
  *
5
5
  * @remarks
6
6
  * Polylines allow connecting multiple points with line segments, enabling complex chart drawings
7
- * like trend channels, patterns, and custom shapes. This implementation focuses on basic
8
- * polylines (straight lines) - curved polylines can be added in a future iteration.
7
+ * like trend channels, patterns, and custom shapes. The `curved` flag goes to the renderer
8
+ * (`result.polylines` of the script API), which draws the curve.
9
9
  *
10
10
  * @version 6
11
11
  */
@@ -30,7 +30,7 @@ function generateId(): string {
30
30
  * Creates a new polyline connecting all points.
31
31
  *
32
32
  * @param points - Array of chart.point objects to connect
33
- * @param curved - If true, use curved line segments (default: false, NOT YET SUPPORTED)
33
+ * @param curved - If true, use curved line segments (default: false)
34
34
  * @param closed - If true, connect first point to last point (default: false)
35
35
  * @param xloc - X-coordinate mode: 'bar_index' or 'bar_time' (default: 'bar_index')
36
36
  * @param line_color - Color of line segments (default: '#2196F3' - blue)
@@ -41,8 +41,6 @@ function generateId(): string {
41
41
  * @returns New Polyline object
42
42
  *
43
43
  * @remarks
44
- * - The curved parameter is accepted but currently logs a warning as curved lines
45
- * are not yet supported. Straight-line connections are used instead.
46
44
  * - For meaningful polylines, provide at least 2 points.
47
45
  * - Closed polylines can be filled with a color by setting fill_color.
48
46
  *
@@ -82,13 +80,6 @@ export function new_polyline(
82
80
  line_width: number = 1,
83
81
  force_overlay: boolean = false
84
82
  ): Polyline {
85
- // Warn about curved polylines not being supported yet
86
- if (curved) {
87
- console.warn(
88
- 'polyline.new(): curved polylines are not yet supported. Using straight-line connections.'
89
- );
90
- }
91
-
92
83
  // Validate line_width is positive
93
84
  if (line_width < 1) {
94
85
  console.warn('polyline.new(): line_width must be at least 1. Using 1.');
@@ -138,6 +138,29 @@ export interface ArrowConfig {
138
138
  forceOverlay?: boolean;
139
139
  }
140
140
 
141
+ /**
142
+ * Configuration of a PineScript `plotcandle()` (kind 'candle') or `plotbar()` (kind 'bar') declaration. The candles
143
+ * are in `result.plotCandles[id]`, the bars in `result.plotBars[id]`.
144
+ */
145
+ export interface CandleConfig {
146
+ /** Unique identifier (key of the data in the result) */
147
+ id: string;
148
+ /** 'candle' for plotcandle, 'bar' for plotbar */
149
+ kind: 'candle' | 'bar';
150
+ /** Display title */
151
+ title?: string;
152
+ /** Static body colour (plotcandle) or bar colour (plotbar) */
153
+ color?: string;
154
+ /** Static wick colour (plotcandle only) */
155
+ wickColor?: string;
156
+ /** Static border colour (plotcandle only) */
157
+ borderColor?: string;
158
+ /** Display mode */
159
+ display?: 'all' | 'none' | 'data_window' | 'status_line' | 'pane';
160
+ /** Drawn on the main chart pane even when the script is not an overlay (PineScript `force_overlay`); default false */
161
+ forceOverlay?: boolean;
162
+ }
163
+
141
164
  /**
142
165
  * Configuration for horizontal line outputs in generated indicators
143
166
  * Matches PineScript hline() function parameters