oakscriptjs 0.1.5 → 0.1.7
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/README.md +30 -240
- package/dist/array/index.d.ts +57 -0
- package/dist/array/index.d.ts.map +1 -0
- package/dist/box/index.d.ts +29 -0
- package/dist/box/index.d.ts.map +1 -0
- package/dist/chartpoint/index.d.ts +8 -0
- package/dist/chartpoint/index.d.ts.map +1 -0
- package/dist/color/index.d.ts +28 -0
- package/dist/color/index.d.ts.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6494 -0
- package/dist/index.mjs +6477 -0
- package/dist/indicator.d.ts +42 -0
- package/dist/indicator.d.ts.map +1 -0
- package/dist/input.d.ts +41 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/label/index.d.ts +22 -0
- package/dist/label/index.d.ts.map +1 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/zigzag/index.d.ts +2 -0
- package/dist/lib/zigzag/index.d.ts.map +1 -0
- package/dist/lib/zigzag/zigzag.d.ts +47 -0
- package/dist/lib/zigzag/zigzag.d.ts.map +1 -0
- package/dist/line/index.d.ts +22 -0
- package/dist/line/index.d.ts.map +1 -0
- package/dist/linefill/index.d.ts +8 -0
- package/dist/linefill/index.d.ts.map +1 -0
- package/dist/math/index.d.ts +53 -0
- package/dist/math/index.d.ts.map +1 -0
- package/dist/matrix/index.d.ts +52 -0
- package/dist/matrix/index.d.ts.map +1 -0
- package/dist/plot.d.ts +20 -0
- package/dist/plot.d.ts.map +1 -0
- package/dist/polyline/index.d.ts +10 -0
- package/dist/polyline/index.d.ts.map +1 -0
- package/dist/runtime/adapters/LightweightChartsAdapter.d.ts +15 -0
- package/dist/runtime/adapters/LightweightChartsAdapter.d.ts.map +1 -0
- package/dist/runtime/adapters/SimpleInputAdapter.d.ts +16 -0
- package/dist/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +6 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +556 -0
- package/dist/runtime/index.mjs +533 -0
- package/dist/runtime/inputs.d.ts +10 -0
- package/dist/runtime/inputs.d.ts.map +1 -0
- package/dist/runtime/runtime.d.ts +16 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/series.d.ts +59 -0
- package/dist/runtime/series.d.ts.map +1 -0
- package/dist/runtime/types.d.ts +81 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/str/index.d.ts +23 -0
- package/dist/str/index.d.ts.map +1 -0
- package/dist/ta/index.d.ts +63 -0
- package/dist/ta/index.d.ts.map +1 -0
- package/dist/ta-series.d.ts +67 -0
- package/dist/ta-series.d.ts.map +1 -0
- package/dist/time/index.d.ts +4 -0
- package/dist/time/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +175 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/metadata.d.ts +90 -0
- package/dist/types/metadata.d.ts.map +1 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/package.json +24 -24
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
// src/runtime/runtime.ts
|
|
2
|
+
var context = null;
|
|
3
|
+
var calculateFn = null;
|
|
4
|
+
var activePlots = [];
|
|
5
|
+
var plotCounter = 0;
|
|
6
|
+
function setContext(ctx) {
|
|
7
|
+
context = ctx;
|
|
8
|
+
plotCounter = 0;
|
|
9
|
+
clearPlots();
|
|
10
|
+
}
|
|
11
|
+
function clearContext() {
|
|
12
|
+
clearPlots();
|
|
13
|
+
context = null;
|
|
14
|
+
calculateFn = null;
|
|
15
|
+
plotCounter = 0;
|
|
16
|
+
}
|
|
17
|
+
function getContext() {
|
|
18
|
+
return context;
|
|
19
|
+
}
|
|
20
|
+
function registerCalculate(fn) {
|
|
21
|
+
calculateFn = fn;
|
|
22
|
+
}
|
|
23
|
+
function recalculate() {
|
|
24
|
+
if (calculateFn) {
|
|
25
|
+
clearPlots();
|
|
26
|
+
plotCounter = 0;
|
|
27
|
+
calculateFn();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function clearPlots() {
|
|
31
|
+
if (context) {
|
|
32
|
+
for (const plot2 of activePlots) {
|
|
33
|
+
try {
|
|
34
|
+
context.chart.removeSeries(plot2.series);
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
activePlots.length = 0;
|
|
40
|
+
}
|
|
41
|
+
function getSeriesType(style) {
|
|
42
|
+
switch (style) {
|
|
43
|
+
case "histogram":
|
|
44
|
+
case "columns":
|
|
45
|
+
return "histogram";
|
|
46
|
+
case "area":
|
|
47
|
+
case "areabr":
|
|
48
|
+
return "area";
|
|
49
|
+
case "circles":
|
|
50
|
+
case "cross":
|
|
51
|
+
return "line";
|
|
52
|
+
default:
|
|
53
|
+
return "line";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function getLineStyle(style) {
|
|
57
|
+
switch (style) {
|
|
58
|
+
case "dotted":
|
|
59
|
+
return 1;
|
|
60
|
+
case "dashed":
|
|
61
|
+
return 2;
|
|
62
|
+
case "solid":
|
|
63
|
+
default:
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function plot(series, title, color, linewidth, style) {
|
|
68
|
+
if (!context) {
|
|
69
|
+
throw new Error("OakScript context not set. Call setContext() before plotting.");
|
|
70
|
+
}
|
|
71
|
+
const plotId = `plot_${plotCounter++}${title ? "_" + title.replace(/\s+/g, "_") : ""}`;
|
|
72
|
+
const seriesType = getSeriesType(style);
|
|
73
|
+
const options = {
|
|
74
|
+
color,
|
|
75
|
+
lineWidth: linewidth,
|
|
76
|
+
lineStyle: getLineStyle(style)
|
|
77
|
+
};
|
|
78
|
+
const seriesHandle = context.chart.addSeries(seriesType, options);
|
|
79
|
+
const data = [];
|
|
80
|
+
for (let index = 0; index < series.length; index++) {
|
|
81
|
+
const value = series[index];
|
|
82
|
+
const time = context.ohlcv.time[index];
|
|
83
|
+
if (time !== void 0 && value !== void 0 && !Number.isNaN(value)) {
|
|
84
|
+
data.push({ time, value });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
seriesHandle.setData(data);
|
|
88
|
+
activePlots.push({ id: plotId, series: seriesHandle });
|
|
89
|
+
return plotId;
|
|
90
|
+
}
|
|
91
|
+
function hline(price, title, color, linestyle, linewidth) {
|
|
92
|
+
if (!context) {
|
|
93
|
+
throw new Error("OakScript context not set. Call setContext() before creating hlines.");
|
|
94
|
+
}
|
|
95
|
+
const hlineId = `hline_${plotCounter++}${title ? "_" + title.replace(/\s+/g, "_") : ""}`;
|
|
96
|
+
const options = {
|
|
97
|
+
color,
|
|
98
|
+
lineWidth: linewidth,
|
|
99
|
+
lineStyle: getLineStyle(linestyle)
|
|
100
|
+
};
|
|
101
|
+
const seriesHandle = context.chart.addSeries("line", options);
|
|
102
|
+
const data = context.ohlcv.time.map((time) => ({
|
|
103
|
+
time,
|
|
104
|
+
value: price
|
|
105
|
+
}));
|
|
106
|
+
seriesHandle.setData(data);
|
|
107
|
+
activePlots.push({ id: hlineId, series: seriesHandle });
|
|
108
|
+
return hlineId;
|
|
109
|
+
}
|
|
110
|
+
function getActivePlots() {
|
|
111
|
+
return activePlots;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/runtime/inputs.ts
|
|
115
|
+
var registeredInputs = /* @__PURE__ */ new Map();
|
|
116
|
+
var autoRecalculateEnabled = false;
|
|
117
|
+
function enableAutoRecalculate() {
|
|
118
|
+
autoRecalculateEnabled = true;
|
|
119
|
+
}
|
|
120
|
+
function disableAutoRecalculate() {
|
|
121
|
+
autoRecalculateEnabled = false;
|
|
122
|
+
}
|
|
123
|
+
function resetInputs() {
|
|
124
|
+
registeredInputs.clear();
|
|
125
|
+
inputCounter = 0;
|
|
126
|
+
}
|
|
127
|
+
var inputCounter = 0;
|
|
128
|
+
function generateInputId(title, defval, type) {
|
|
129
|
+
if (title) {
|
|
130
|
+
return title.replace(/\s+/g, "_");
|
|
131
|
+
}
|
|
132
|
+
return `${type}_${inputCounter++}_${String(defval)}`;
|
|
133
|
+
}
|
|
134
|
+
function input_int(defval, title, options) {
|
|
135
|
+
const context2 = getContext();
|
|
136
|
+
if (!context2) {
|
|
137
|
+
return Math.floor(defval);
|
|
138
|
+
}
|
|
139
|
+
const id = generateInputId(title, defval, "int");
|
|
140
|
+
const config = {
|
|
141
|
+
id,
|
|
142
|
+
type: "int",
|
|
143
|
+
defval: Math.floor(defval),
|
|
144
|
+
title,
|
|
145
|
+
min: options?.min,
|
|
146
|
+
max: options?.max,
|
|
147
|
+
step: options?.step ?? 1
|
|
148
|
+
};
|
|
149
|
+
if (!registeredInputs.has(id)) {
|
|
150
|
+
context2.inputs.registerInput(config);
|
|
151
|
+
registeredInputs.set(id, true);
|
|
152
|
+
if (autoRecalculateEnabled) {
|
|
153
|
+
context2.inputs.onInputChange((changedId) => {
|
|
154
|
+
if (changedId === id) {
|
|
155
|
+
recalculate();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const value = context2.inputs.getValue(id);
|
|
161
|
+
return typeof value === "number" ? Math.floor(value) : Math.floor(defval);
|
|
162
|
+
}
|
|
163
|
+
function input_float(defval, title, options) {
|
|
164
|
+
const context2 = getContext();
|
|
165
|
+
if (!context2) {
|
|
166
|
+
return defval;
|
|
167
|
+
}
|
|
168
|
+
const id = generateInputId(title, defval, "float");
|
|
169
|
+
const config = {
|
|
170
|
+
id,
|
|
171
|
+
type: "float",
|
|
172
|
+
defval,
|
|
173
|
+
title,
|
|
174
|
+
min: options?.min,
|
|
175
|
+
max: options?.max,
|
|
176
|
+
step: options?.step ?? 0.1
|
|
177
|
+
};
|
|
178
|
+
if (!registeredInputs.has(id)) {
|
|
179
|
+
context2.inputs.registerInput(config);
|
|
180
|
+
registeredInputs.set(id, true);
|
|
181
|
+
if (autoRecalculateEnabled) {
|
|
182
|
+
context2.inputs.onInputChange((changedId) => {
|
|
183
|
+
if (changedId === id) {
|
|
184
|
+
recalculate();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const value = context2.inputs.getValue(id);
|
|
190
|
+
return typeof value === "number" ? value : defval;
|
|
191
|
+
}
|
|
192
|
+
function input_bool(defval, title) {
|
|
193
|
+
const context2 = getContext();
|
|
194
|
+
if (!context2) {
|
|
195
|
+
return defval;
|
|
196
|
+
}
|
|
197
|
+
const id = generateInputId(title, defval, "bool");
|
|
198
|
+
const config = {
|
|
199
|
+
id,
|
|
200
|
+
type: "bool",
|
|
201
|
+
defval,
|
|
202
|
+
title
|
|
203
|
+
};
|
|
204
|
+
if (!registeredInputs.has(id)) {
|
|
205
|
+
context2.inputs.registerInput(config);
|
|
206
|
+
registeredInputs.set(id, true);
|
|
207
|
+
if (autoRecalculateEnabled) {
|
|
208
|
+
context2.inputs.onInputChange((changedId) => {
|
|
209
|
+
if (changedId === id) {
|
|
210
|
+
recalculate();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const value = context2.inputs.getValue(id);
|
|
216
|
+
return typeof value === "boolean" ? value : defval;
|
|
217
|
+
}
|
|
218
|
+
function input_string(defval, title, options) {
|
|
219
|
+
const context2 = getContext();
|
|
220
|
+
if (!context2) {
|
|
221
|
+
return defval;
|
|
222
|
+
}
|
|
223
|
+
const id = generateInputId(title, defval, "string");
|
|
224
|
+
const config = {
|
|
225
|
+
id,
|
|
226
|
+
type: "string",
|
|
227
|
+
defval,
|
|
228
|
+
title,
|
|
229
|
+
options
|
|
230
|
+
};
|
|
231
|
+
if (!registeredInputs.has(id)) {
|
|
232
|
+
context2.inputs.registerInput(config);
|
|
233
|
+
registeredInputs.set(id, true);
|
|
234
|
+
if (autoRecalculateEnabled) {
|
|
235
|
+
context2.inputs.onInputChange((changedId) => {
|
|
236
|
+
if (changedId === id) {
|
|
237
|
+
recalculate();
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const value = context2.inputs.getValue(id);
|
|
243
|
+
return typeof value === "string" ? value : defval;
|
|
244
|
+
}
|
|
245
|
+
function input_source(defval, title) {
|
|
246
|
+
const context2 = getContext();
|
|
247
|
+
if (!context2) {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
const id = generateInputId(title, defval, "source");
|
|
251
|
+
const config = {
|
|
252
|
+
id,
|
|
253
|
+
type: "source",
|
|
254
|
+
defval,
|
|
255
|
+
title,
|
|
256
|
+
options: ["open", "high", "low", "close", "volume", "hl2", "hlc3", "ohlc4"]
|
|
257
|
+
};
|
|
258
|
+
if (!registeredInputs.has(id)) {
|
|
259
|
+
context2.inputs.registerInput(config);
|
|
260
|
+
registeredInputs.set(id, true);
|
|
261
|
+
if (autoRecalculateEnabled) {
|
|
262
|
+
context2.inputs.onInputChange((changedId) => {
|
|
263
|
+
if (changedId === id) {
|
|
264
|
+
recalculate();
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const sourceName = context2.inputs.getValue(id) ?? defval;
|
|
270
|
+
return getSourceData(context2.ohlcv, sourceName);
|
|
271
|
+
}
|
|
272
|
+
function getSourceData(ohlcv, sourceName) {
|
|
273
|
+
switch (sourceName) {
|
|
274
|
+
case "open":
|
|
275
|
+
return ohlcv.open;
|
|
276
|
+
case "high":
|
|
277
|
+
return ohlcv.high;
|
|
278
|
+
case "low":
|
|
279
|
+
return ohlcv.low;
|
|
280
|
+
case "close":
|
|
281
|
+
return ohlcv.close;
|
|
282
|
+
case "volume":
|
|
283
|
+
return ohlcv.volume;
|
|
284
|
+
case "hl2":
|
|
285
|
+
return ohlcv.high.map((h, i) => {
|
|
286
|
+
const l = ohlcv.low[i];
|
|
287
|
+
return l !== void 0 ? (h + l) / 2 : NaN;
|
|
288
|
+
});
|
|
289
|
+
case "hlc3":
|
|
290
|
+
return ohlcv.high.map((h, i) => {
|
|
291
|
+
const l = ohlcv.low[i];
|
|
292
|
+
const c = ohlcv.close[i];
|
|
293
|
+
return l !== void 0 && c !== void 0 ? (h + l + c) / 3 : NaN;
|
|
294
|
+
});
|
|
295
|
+
case "ohlc4":
|
|
296
|
+
return ohlcv.open.map((o, i) => {
|
|
297
|
+
const h = ohlcv.high[i];
|
|
298
|
+
const l = ohlcv.low[i];
|
|
299
|
+
const c = ohlcv.close[i];
|
|
300
|
+
return h !== void 0 && l !== void 0 && c !== void 0 ? (o + h + l + c) / 4 : NaN;
|
|
301
|
+
});
|
|
302
|
+
default:
|
|
303
|
+
return ohlcv.close;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// src/runtime/adapters/LightweightChartsAdapter.ts
|
|
308
|
+
var LightweightChartsAdapter = class {
|
|
309
|
+
chart;
|
|
310
|
+
mainSeries;
|
|
311
|
+
paneCount = 0;
|
|
312
|
+
/**
|
|
313
|
+
* Create a new LightweightChartsAdapter
|
|
314
|
+
* @param chart - The lightweight-charts chart instance
|
|
315
|
+
* @param mainSeries - Optional main price series (candlestick/line series)
|
|
316
|
+
*/
|
|
317
|
+
constructor(chart, mainSeries) {
|
|
318
|
+
this.chart = chart;
|
|
319
|
+
if (mainSeries) {
|
|
320
|
+
this.mainSeries = this.wrapSeries(mainSeries);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Wrap a lightweight-charts series to implement SeriesHandle
|
|
325
|
+
* @param lwcSeries - The lightweight-charts series
|
|
326
|
+
* @returns SeriesHandle wrapper
|
|
327
|
+
*/
|
|
328
|
+
wrapSeries(lwcSeries) {
|
|
329
|
+
return {
|
|
330
|
+
setData: (data) => {
|
|
331
|
+
lwcSeries.setData(data);
|
|
332
|
+
},
|
|
333
|
+
// Store reference for removal
|
|
334
|
+
_lwcSeries: lwcSeries
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Map series type string to lightweight-charts series definition
|
|
339
|
+
* @param type - Series type ('line', 'histogram', 'area')
|
|
340
|
+
* @returns Lightweight-charts series definition object
|
|
341
|
+
*/
|
|
342
|
+
getSeriesDefinition(type) {
|
|
343
|
+
switch (type) {
|
|
344
|
+
case "histogram":
|
|
345
|
+
return { type: "Histogram" };
|
|
346
|
+
case "area":
|
|
347
|
+
return { type: "Area" };
|
|
348
|
+
case "baseline":
|
|
349
|
+
return { type: "Baseline" };
|
|
350
|
+
case "bar":
|
|
351
|
+
return { type: "Bar" };
|
|
352
|
+
case "line":
|
|
353
|
+
default:
|
|
354
|
+
return { type: "Line" };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Convert OakScriptJS series options to lightweight-charts options
|
|
359
|
+
* @param options - OakScriptJS series options
|
|
360
|
+
* @returns Lightweight-charts compatible options
|
|
361
|
+
*/
|
|
362
|
+
convertOptions(options) {
|
|
363
|
+
if (!options) {
|
|
364
|
+
return {};
|
|
365
|
+
}
|
|
366
|
+
const lwcOptions = {};
|
|
367
|
+
if (options.color) {
|
|
368
|
+
lwcOptions.color = options.color;
|
|
369
|
+
}
|
|
370
|
+
if (options.lineWidth !== void 0) {
|
|
371
|
+
lwcOptions.lineWidth = options.lineWidth;
|
|
372
|
+
}
|
|
373
|
+
if (options.lineStyle !== void 0) {
|
|
374
|
+
lwcOptions.lineStyle = options.lineStyle;
|
|
375
|
+
}
|
|
376
|
+
if (options.priceScaleId) {
|
|
377
|
+
lwcOptions.priceScaleId = options.priceScaleId;
|
|
378
|
+
}
|
|
379
|
+
return lwcOptions;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Add a new series to the chart
|
|
383
|
+
* @param type - Series type ('line', 'histogram', 'area')
|
|
384
|
+
* @param options - Series options
|
|
385
|
+
* @returns SeriesHandle for the new series
|
|
386
|
+
*/
|
|
387
|
+
addSeries(type, options) {
|
|
388
|
+
const seriesDefinition = this.getSeriesDefinition(type);
|
|
389
|
+
const lwcOptions = this.convertOptions(options);
|
|
390
|
+
const lwcSeries = this.chart.addSeries(seriesDefinition, lwcOptions);
|
|
391
|
+
return this.wrapSeries(lwcSeries);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Remove a series from the chart
|
|
395
|
+
* @param series - SeriesHandle to remove
|
|
396
|
+
*/
|
|
397
|
+
removeSeries(series) {
|
|
398
|
+
const wrappedSeries = series;
|
|
399
|
+
if (wrappedSeries._lwcSeries) {
|
|
400
|
+
this.chart.removeSeries(wrappedSeries._lwcSeries);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Get the main price series
|
|
405
|
+
* @returns Main series handle or undefined
|
|
406
|
+
*/
|
|
407
|
+
getMainSeries() {
|
|
408
|
+
return this.mainSeries;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Create a new pane (if supported by the chart configuration)
|
|
412
|
+
* @returns Index of the new pane
|
|
413
|
+
*/
|
|
414
|
+
createPane() {
|
|
415
|
+
return ++this.paneCount;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
// src/runtime/adapters/SimpleInputAdapter.ts
|
|
420
|
+
var SimpleInputAdapter = class {
|
|
421
|
+
inputs = /* @__PURE__ */ new Map();
|
|
422
|
+
changeCallbacks = [];
|
|
423
|
+
/**
|
|
424
|
+
* Register an input configuration
|
|
425
|
+
* If already registered, returns current value without modifying config
|
|
426
|
+
* @param config - Input configuration
|
|
427
|
+
* @returns Current value (defval on first registration)
|
|
428
|
+
*/
|
|
429
|
+
registerInput(config) {
|
|
430
|
+
if (!this.inputs.has(config.id)) {
|
|
431
|
+
this.inputs.set(config.id, { config, value: config.defval });
|
|
432
|
+
}
|
|
433
|
+
return this.inputs.get(config.id).value;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Get current value of an input
|
|
437
|
+
* @param id - Input identifier
|
|
438
|
+
* @returns Current value or undefined if not registered
|
|
439
|
+
*/
|
|
440
|
+
getValue(id) {
|
|
441
|
+
return this.inputs.get(id)?.value;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Set value of an input with validation
|
|
445
|
+
* Validates against config constraints (min/max/step for numerics, options for strings)
|
|
446
|
+
* @param id - Input identifier
|
|
447
|
+
* @param value - New value
|
|
448
|
+
*/
|
|
449
|
+
setValue(id, value) {
|
|
450
|
+
const input = this.inputs.get(id);
|
|
451
|
+
if (!input) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const { config } = input;
|
|
455
|
+
let validatedValue = value;
|
|
456
|
+
if ((config.type === "int" || config.type === "float") && typeof value === "number") {
|
|
457
|
+
if (config.min !== void 0 && value < config.min) {
|
|
458
|
+
validatedValue = config.min;
|
|
459
|
+
}
|
|
460
|
+
if (config.max !== void 0 && value > config.max) {
|
|
461
|
+
validatedValue = config.max;
|
|
462
|
+
}
|
|
463
|
+
if (config.type === "int") {
|
|
464
|
+
validatedValue = Math.floor(validatedValue);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (config.type === "string" && config.options && typeof value === "string") {
|
|
468
|
+
if (!config.options.includes(value)) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (config.type === "source" && config.options && typeof value === "string") {
|
|
473
|
+
if (!config.options.includes(value)) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
input.value = validatedValue;
|
|
478
|
+
this.changeCallbacks.forEach((cb) => cb(id, validatedValue));
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Register a callback for input value changes
|
|
482
|
+
* @param callback - Function to call when any input value changes
|
|
483
|
+
*/
|
|
484
|
+
onInputChange(callback) {
|
|
485
|
+
this.changeCallbacks.push(callback);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Get all registered inputs (for UI rendering)
|
|
489
|
+
* @returns Map of input IDs to their configs and values
|
|
490
|
+
*/
|
|
491
|
+
getAllInputs() {
|
|
492
|
+
return new Map(this.inputs);
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Clear all registered inputs
|
|
496
|
+
* Useful for testing or resetting state
|
|
497
|
+
*/
|
|
498
|
+
clear() {
|
|
499
|
+
this.inputs.clear();
|
|
500
|
+
this.changeCallbacks = [];
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Remove a specific change callback
|
|
504
|
+
* @param callback - The callback to remove
|
|
505
|
+
*/
|
|
506
|
+
removeChangeCallback(callback) {
|
|
507
|
+
const index = this.changeCallbacks.indexOf(callback);
|
|
508
|
+
if (index !== -1) {
|
|
509
|
+
this.changeCallbacks.splice(index, 1);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
export {
|
|
514
|
+
LightweightChartsAdapter,
|
|
515
|
+
SimpleInputAdapter,
|
|
516
|
+
clearContext,
|
|
517
|
+
clearPlots,
|
|
518
|
+
disableAutoRecalculate,
|
|
519
|
+
enableAutoRecalculate,
|
|
520
|
+
getActivePlots,
|
|
521
|
+
getContext,
|
|
522
|
+
hline,
|
|
523
|
+
input_bool,
|
|
524
|
+
input_float,
|
|
525
|
+
input_int,
|
|
526
|
+
input_source,
|
|
527
|
+
input_string,
|
|
528
|
+
plot,
|
|
529
|
+
recalculate,
|
|
530
|
+
registerCalculate,
|
|
531
|
+
resetInputs,
|
|
532
|
+
setContext
|
|
533
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InputOptions } from './types';
|
|
2
|
+
export declare function enableAutoRecalculate(): void;
|
|
3
|
+
export declare function disableAutoRecalculate(): void;
|
|
4
|
+
export declare function resetInputs(): void;
|
|
5
|
+
export declare function input_int(defval: number, title?: string, options?: InputOptions): number;
|
|
6
|
+
export declare function input_float(defval: number, title?: string, options?: InputOptions): number;
|
|
7
|
+
export declare function input_bool(defval: boolean, title?: string): boolean;
|
|
8
|
+
export declare function input_string(defval: string, title?: string, options?: string[]): string;
|
|
9
|
+
export declare function input_source(defval: string, title?: string): number[];
|
|
10
|
+
//# sourceMappingURL=inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../src/runtime/inputs.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,SAAS,CAAC;AAYzD,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAKD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAMD,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AA4BD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAqCxF;AAUD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAkC1F;AASD,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CA6BnE;AAUD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CA8BvF;AASD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BrE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { OakScriptContext, SeriesHandle } from './types';
|
|
2
|
+
interface ActivePlot {
|
|
3
|
+
id: string;
|
|
4
|
+
series: SeriesHandle;
|
|
5
|
+
}
|
|
6
|
+
export declare function setContext(ctx: OakScriptContext): void;
|
|
7
|
+
export declare function clearContext(): void;
|
|
8
|
+
export declare function getContext(): OakScriptContext | null;
|
|
9
|
+
export declare function registerCalculate(fn: () => void): void;
|
|
10
|
+
export declare function recalculate(): void;
|
|
11
|
+
export declare function clearPlots(): void;
|
|
12
|
+
export declare function plot(series: number[], title?: string, color?: string, linewidth?: number, style?: string): string;
|
|
13
|
+
export declare function hline(price: number, title?: string, color?: string, linestyle?: string, linewidth?: number): string;
|
|
14
|
+
export declare function getActivePlots(): ReadonlyArray<ActivePlot>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAiB,MAAM,SAAS,CAAC;AAS7E,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;CACtB;AAYD,wBAAgB,UAAU,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAKtD;AAMD,wBAAgB,YAAY,IAAI,IAAI,CAKnC;AAMD,wBAAgB,UAAU,IAAI,gBAAgB,GAAG,IAAI,CAEpD;AAOD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAEtD;AAMD,wBAAgB,WAAW,IAAI,IAAI,CAMlC;AAMD,wBAAgB,UAAU,IAAI,IAAI,CAWjC;AAiDD,wBAAgB,IAAI,CAClB,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAkCR;AAWD,wBAAgB,KAAK,CACnB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CA4BR;AAOD,wBAAgB,cAAc,IAAI,aAAa,CAAC,UAAU,CAAC,CAE1D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Bar } from '../types';
|
|
2
|
+
export type SeriesExtractor = (bar: Bar, index: number, data: Bar[]) => number;
|
|
3
|
+
export declare class BarData {
|
|
4
|
+
private _bars;
|
|
5
|
+
private _version;
|
|
6
|
+
constructor(bars?: Bar[]);
|
|
7
|
+
get version(): number;
|
|
8
|
+
get bars(): Bar[];
|
|
9
|
+
get length(): number;
|
|
10
|
+
push(bar: Bar): void;
|
|
11
|
+
pop(): Bar | undefined;
|
|
12
|
+
set(index: number, bar: Bar): void;
|
|
13
|
+
updateLast(bar: Bar): void;
|
|
14
|
+
setAll(bars: Bar[]): void;
|
|
15
|
+
invalidate(): void;
|
|
16
|
+
at(index: number): Bar | undefined;
|
|
17
|
+
static from(bars: Bar[]): BarData;
|
|
18
|
+
}
|
|
19
|
+
export declare class Series {
|
|
20
|
+
private extractor;
|
|
21
|
+
private dataSource;
|
|
22
|
+
private cached;
|
|
23
|
+
private cachedVersion;
|
|
24
|
+
constructor(data: Bar[] | BarData, extractor: SeriesExtractor);
|
|
25
|
+
get bars(): Bar[];
|
|
26
|
+
get barData(): BarData;
|
|
27
|
+
static fromBars(bars: Bar[] | BarData, field: 'open' | 'high' | 'low' | 'close' | 'volume'): Series;
|
|
28
|
+
static constant(bars: Bar[] | BarData, value: number): Series;
|
|
29
|
+
static fromArray(bars: Bar[] | BarData, values: number[]): Series;
|
|
30
|
+
add(other: Series | number): Series;
|
|
31
|
+
sub(other: Series | number): Series;
|
|
32
|
+
mul(other: Series | number): Series;
|
|
33
|
+
div(other: Series | number): Series;
|
|
34
|
+
mod(other: Series | number): Series;
|
|
35
|
+
neg(): Series;
|
|
36
|
+
gt(other: Series | number): Series;
|
|
37
|
+
gte(other: Series | number): Series;
|
|
38
|
+
lt(other: Series | number): Series;
|
|
39
|
+
lte(other: Series | number): Series;
|
|
40
|
+
eq(other: Series | number): Series;
|
|
41
|
+
neq(other: Series | number): Series;
|
|
42
|
+
and(other: Series | number): Series;
|
|
43
|
+
or(other: Series | number): Series;
|
|
44
|
+
not(): Series;
|
|
45
|
+
iff(trueValue: Series | number, falseValue: Series | number): Series;
|
|
46
|
+
offset(offset: number): Series;
|
|
47
|
+
toArray(): number[];
|
|
48
|
+
materialize(): Series;
|
|
49
|
+
_invalidate(): void;
|
|
50
|
+
_compute(): number[];
|
|
51
|
+
get(index: number): number;
|
|
52
|
+
last(): number;
|
|
53
|
+
length(): number;
|
|
54
|
+
toTimeValuePairs(): Array<{
|
|
55
|
+
time: any;
|
|
56
|
+
value: number;
|
|
57
|
+
}>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=series.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../../src/runtime/series.ts"],"names":[],"mappings":"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"}
|