oakscriptjs 0.13.2 → 0.14.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/AGENTS.md +6 -1
- package/README.md +1 -1
- package/bin/oakscript.mjs +5 -0
- package/dist/cjs/check/checks.d.ts +78 -0
- package/dist/cjs/check/checks.d.ts.map +1 -0
- package/dist/cjs/check/checks.js +109 -0
- package/dist/cjs/check/checks.js.map +7 -0
- package/dist/cjs/check/format.d.ts +26 -0
- package/dist/cjs/check/format.d.ts.map +1 -0
- package/dist/cjs/check/format.js +106 -0
- package/dist/cjs/check/format.js.map +7 -0
- package/dist/cjs/check/harness.d.ts +94 -0
- package/dist/cjs/check/harness.d.ts.map +1 -0
- package/dist/cjs/check/harness.js +302 -0
- package/dist/cjs/check/harness.js.map +7 -0
- package/dist/cjs/check/index.d.ts +253 -0
- package/dist/cjs/check/index.d.ts.map +1 -0
- package/dist/cjs/check/index.js +466 -0
- package/dist/cjs/check/index.js.map +7 -0
- package/dist/cjs/check/node.d.ts +53 -0
- package/dist/cjs/check/node.d.ts.map +1 -0
- package/dist/cjs/check/node.js +318 -0
- package/dist/cjs/check/node.js.map +7 -0
- package/dist/cjs/check/spec.d.ts +44 -0
- package/dist/cjs/check/spec.d.ts.map +1 -0
- package/dist/cjs/check/spec.js +199 -0
- package/dist/cjs/check/spec.js.map +7 -0
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/runtime/series.d.ts +6 -0
- package/dist/cjs/runtime/series.d.ts.map +1 -1
- package/dist/cjs/runtime/series.js +15 -0
- package/dist/cjs/runtime/series.js.map +2 -2
- package/dist/cjs/script/constants.d.ts +200 -0
- package/dist/cjs/script/constants.d.ts.map +1 -0
- package/dist/cjs/script/constants.js +217 -0
- package/dist/cjs/script/constants.js.map +7 -0
- package/dist/cjs/script/drawing-args.d.ts +25 -0
- package/dist/cjs/script/drawing-args.d.ts.map +1 -0
- package/dist/cjs/script/drawing-args.js +203 -0
- package/dist/cjs/script/drawing-args.js.map +7 -0
- package/dist/cjs/script/globals.d.ts +127 -0
- package/dist/cjs/script/globals.d.ts.map +1 -0
- package/dist/cjs/script/globals.js +17 -0
- package/dist/cjs/script/globals.js.map +7 -0
- package/dist/cjs/script/index.d.ts +504 -166
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +236 -96
- package/dist/cjs/script/index.js.map +3 -3
- package/dist/esm/check/checks.d.ts +78 -0
- package/dist/esm/check/checks.d.ts.map +1 -0
- package/dist/esm/check/checks.js +95 -0
- package/dist/esm/check/checks.js.map +1 -0
- package/dist/esm/check/format.d.ts +26 -0
- package/dist/esm/check/format.d.ts.map +1 -0
- package/dist/esm/check/format.js +105 -0
- package/dist/esm/check/format.js.map +1 -0
- package/dist/esm/check/harness.d.ts +94 -0
- package/dist/esm/check/harness.d.ts.map +1 -0
- package/dist/esm/check/harness.js +317 -0
- package/dist/esm/check/harness.js.map +1 -0
- package/dist/esm/check/index.d.ts +253 -0
- package/dist/esm/check/index.d.ts.map +1 -0
- package/dist/esm/check/index.js +470 -0
- package/dist/esm/check/index.js.map +1 -0
- package/dist/esm/check/node.d.ts +53 -0
- package/dist/esm/check/node.d.ts.map +1 -0
- package/dist/esm/check/node.js +347 -0
- package/dist/esm/check/node.js.map +1 -0
- package/dist/esm/check/spec.d.ts +44 -0
- package/dist/esm/check/spec.d.ts.map +1 -0
- package/dist/esm/check/spec.js +198 -0
- package/dist/esm/check/spec.js.map +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/runtime/series.d.ts +6 -0
- package/dist/esm/runtime/series.d.ts.map +1 -1
- package/dist/esm/runtime/series.js +14 -0
- package/dist/esm/runtime/series.js.map +1 -1
- package/dist/esm/script/constants.d.ts +200 -0
- package/dist/esm/script/constants.d.ts.map +1 -0
- package/dist/esm/script/constants.js +151 -0
- package/dist/esm/script/constants.js.map +1 -0
- package/dist/esm/script/drawing-args.d.ts +25 -0
- package/dist/esm/script/drawing-args.d.ts.map +1 -0
- package/dist/esm/script/drawing-args.js +171 -0
- package/dist/esm/script/drawing-args.js.map +1 -0
- package/dist/esm/script/globals.d.ts +127 -0
- package/dist/esm/script/globals.d.ts.map +1 -0
- package/dist/esm/script/globals.js +28 -0
- package/dist/esm/script/globals.js.map +1 -0
- package/dist/esm/script/index.d.ts +504 -166
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +256 -83
- package/dist/esm/script/index.js.map +1 -1
- package/package.json +31 -1
- package/skills/oakscript/SKILL.md +62 -26
- package/skills/oakscript/examples/ma-cross.js +2 -2
- package/skills/oakscript/examples/mtf-trend-filter.js +3 -3
- package/skills/oakscript/reference/check.md +150 -0
- package/skills/oakscript/reference/errors.md +31 -7
- package/skills/oakscript/reference/pine-differences.md +17 -16
- package/skills/oakscript/reference/plotting.md +25 -19
- package/skills/oakscript/reference/script-structure.md +34 -17
- package/skills/oakscript/reference/timeframes-symbols.md +5 -1
- package/skills/oakscript/spec.schema.json +199 -0
- package/src/check/checks.ts +175 -0
- package/src/check/format.ts +117 -0
- package/src/check/harness.ts +372 -0
- package/src/check/index.ts +708 -0
- package/src/check/node.ts +368 -0
- package/src/check/spec.ts +200 -0
- package/src/index.ts +1 -1
- package/src/runtime/series.ts +19 -0
- package/src/script/constants.ts +169 -0
- package/src/script/drawing-args.ts +179 -0
- package/src/script/globals.ts +129 -0
- package/src/script/index.ts +462 -81
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Runs a script source the way a host app runs a script written in its editor: the source is the body
|
|
3
|
+
* of the script, with every value export of `oakscriptjs/script` but `executeScript` as an implicit global, on
|
|
4
|
+
* deterministic synthetic bars (or given bars), with a chart context and, for a strategy, a small order engine.
|
|
5
|
+
* Used by {@link checkScript}, the `oakscript check` command and the tests of the agent guide.
|
|
6
|
+
*
|
|
7
|
+
* @module check/harness
|
|
8
|
+
*/
|
|
9
|
+
import * as lib from '../index.js';
|
|
10
|
+
import * as api from '../script/index.js';
|
|
11
|
+
import { executeScript, } from '../script/index.js';
|
|
12
|
+
/** The implicit globals of a script: every value export of the script API but the host entry. */
|
|
13
|
+
export const SCRIPT_GLOBALS = Object.keys(api).filter((k) => k !== 'default' && k !== 'executeScript' && /^[A-Za-z_$][\w$]*$/.test(k));
|
|
14
|
+
/** Name of the parameter that receives the `oakscriptjs` module in a compiled script (its `import` statements). */
|
|
15
|
+
export const LIBRARY_PARAMETER = '__oakscriptjs';
|
|
16
|
+
/** The values of {@link SCRIPT_GLOBALS}, then the `oakscriptjs` module, in the order of the compiled parameters. */
|
|
17
|
+
export function scriptArguments() {
|
|
18
|
+
return [...SCRIPT_GLOBALS.map((k) => api[k]), lib];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Rewrites the `import { a, b as c } from "oakscriptjs"` statements of a script into `const { a, b: c } = ...` on the
|
|
22
|
+
* same lines (the line numbers of the source do not change). Throws on an import of another module: a script runs
|
|
23
|
+
* self-contained.
|
|
24
|
+
*/
|
|
25
|
+
export function rewriteImports(source) {
|
|
26
|
+
return source.replace(/^([ \t]*)import\s*(\{[^}]*\}|\*\s+as\s+[A-Za-z_$][\w$]*)\s*from\s*(['"])([^'"]+)\3\s*;?/gm, (all, indent, what, _q, from) => {
|
|
27
|
+
if (from !== 'oakscriptjs' && from !== 'oakscriptjs/script') {
|
|
28
|
+
throw new SyntaxError(`A script can only import from "oakscriptjs" (found "${from}").`);
|
|
29
|
+
}
|
|
30
|
+
const lines = all.split('\n').length - 1;
|
|
31
|
+
const binding = what.startsWith('*')
|
|
32
|
+
? what.replace(/^\*\s+as\s+/, '')
|
|
33
|
+
: what.replace(/\s+as\s+/g, ': ').replace(/\s+/g, ' ');
|
|
34
|
+
return `${indent}const ${binding} = ${LIBRARY_PARAMETER};${'\n'.repeat(lines)}`;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Start and end of the function the script source is wrapped in. The globals are the parameters of an outer function
|
|
39
|
+
* and the source is the body of an inner one, so a script can declare a name of a global (`const size = 2`), as in an
|
|
40
|
+
* app that imports the globals at the top of a module. The start goes on the first line of the source.
|
|
41
|
+
*/
|
|
42
|
+
export const SCRIPT_PREFIX = '"use strict"; return (function () { ';
|
|
43
|
+
export const SCRIPT_SUFFIX = '\n})();';
|
|
44
|
+
/** The source of the function body of a compiled script (imports rewritten, lines kept). */
|
|
45
|
+
export function wrapSource(source) {
|
|
46
|
+
return SCRIPT_PREFIX + rewriteImports(source) + SCRIPT_SUFFIX;
|
|
47
|
+
}
|
|
48
|
+
/** Compiles a script source into a body for executeScript(); throws a SyntaxError on invalid code. */
|
|
49
|
+
export function compileScript(source) {
|
|
50
|
+
const fn = new Function(...SCRIPT_GLOBALS, LIBRARY_PARAMETER, wrapSource(source));
|
|
51
|
+
const values = scriptArguments();
|
|
52
|
+
return () => fn(...values);
|
|
53
|
+
}
|
|
54
|
+
const HOUR = 3600;
|
|
55
|
+
/** 2024-01-01 00:00 UTC, in seconds. */
|
|
56
|
+
const START = 1704067200;
|
|
57
|
+
/** Deterministic synthetic bars: two waves, a slow trend and seeded noise. `step`: seconds between bars. */
|
|
58
|
+
export function syntheticBars(count, step = HOUR, seed = 1) {
|
|
59
|
+
let s = seed >>> 0 || 1;
|
|
60
|
+
const rand = () => {
|
|
61
|
+
s = (Math.imul(s, 1664525) + 1013904223) >>> 0;
|
|
62
|
+
return s / 2 ** 32;
|
|
63
|
+
};
|
|
64
|
+
const scale = Math.sqrt(step / HOUR);
|
|
65
|
+
const bars = [];
|
|
66
|
+
let prev = 100;
|
|
67
|
+
for (let i = 0; i < count; i++) {
|
|
68
|
+
const t = (i * step) / HOUR;
|
|
69
|
+
const close = 100 + 12 * Math.sin(t / 60) + 4 * Math.sin(t / 11) + t * 0.004 + (rand() - 0.5) * 1.5 * scale;
|
|
70
|
+
const open = prev;
|
|
71
|
+
const high = Math.max(open, close) + rand() * 0.8 * scale;
|
|
72
|
+
const low = Math.min(open, close) - rand() * 0.8 * scale;
|
|
73
|
+
bars.push({ time: START + i * step, open, high, low, close, volume: Math.round(1000 + rand() * 4000) });
|
|
74
|
+
prev = close;
|
|
75
|
+
}
|
|
76
|
+
return bars;
|
|
77
|
+
}
|
|
78
|
+
/** Seconds of a timeframe string ("1", "60", "240", "D", "1D", "W", "M"); NaN when it is not one. */
|
|
79
|
+
export function timeframeSeconds(timeframe) {
|
|
80
|
+
const m = /^(\d*)([SDWM]?)$/.exec(timeframe.trim().toUpperCase());
|
|
81
|
+
if (!m)
|
|
82
|
+
return NaN;
|
|
83
|
+
const n = m[1] ? Number(m[1]) : 1;
|
|
84
|
+
const unit = { '': 60, S: 1, D: 86400, W: 7 * 86400, M: 30 * 86400 }[m[2]];
|
|
85
|
+
return n * unit;
|
|
86
|
+
}
|
|
87
|
+
/** The timeframe of bars from the most common spacing of their times ("60", "D", "W"...); "60" for fewer than 2 bars. */
|
|
88
|
+
export function inferTimeframe(bars) {
|
|
89
|
+
const counts = new Map();
|
|
90
|
+
for (let i = 1; i < bars.length; i++) {
|
|
91
|
+
const d = bars[i].time - bars[i - 1].time;
|
|
92
|
+
if (d > 0)
|
|
93
|
+
counts.set(d, (counts.get(d) ?? 0) + 1);
|
|
94
|
+
}
|
|
95
|
+
let step = 0;
|
|
96
|
+
let best = 0;
|
|
97
|
+
for (const [d, c] of counts)
|
|
98
|
+
if (c > best)
|
|
99
|
+
[step, best] = [d, c];
|
|
100
|
+
if (!step)
|
|
101
|
+
return '60';
|
|
102
|
+
if (step >= 28 * 86400)
|
|
103
|
+
return 'M';
|
|
104
|
+
if (step >= 7 * 86400)
|
|
105
|
+
return 'W';
|
|
106
|
+
if (step >= 86400)
|
|
107
|
+
return 'D';
|
|
108
|
+
if (step < 60)
|
|
109
|
+
return `${step}S`;
|
|
110
|
+
return String(Math.round(step / 60));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Chart context of the test runs: a 24x7 symbol in UTC. Higher timeframes of the chart symbol are resampled from the
|
|
114
|
+
* chart bars by the library; other symbols get synthetic bars of their own (seeded by the symbol name).
|
|
115
|
+
*/
|
|
116
|
+
export function testChart(bars, options = {}) {
|
|
117
|
+
const timezone = options.timezone ?? 'Etc/UTC';
|
|
118
|
+
const session = options.session ?? '24x7';
|
|
119
|
+
const chartStep = timeframeSeconds(options.timeframe ?? '60') || HOUR;
|
|
120
|
+
const span = bars.length ? bars[bars.length - 1].time - bars[0].time + chartStep : 0;
|
|
121
|
+
return {
|
|
122
|
+
tickerid: options.tickerid ?? 'TEST:SYN',
|
|
123
|
+
timeframe: options.timeframe ?? '60',
|
|
124
|
+
timezone,
|
|
125
|
+
session,
|
|
126
|
+
mintick: 0.01,
|
|
127
|
+
pointvalue: 1,
|
|
128
|
+
mincontract: 1,
|
|
129
|
+
currency: 'USD',
|
|
130
|
+
bars: (symbol, timeframe) => {
|
|
131
|
+
const step = timeframeSeconds(timeframe);
|
|
132
|
+
if (!step)
|
|
133
|
+
return [];
|
|
134
|
+
// a run on zero bars (the declaration run of a host) gets one empty bar: no bars at all is an invalid symbol
|
|
135
|
+
if (!bars.length)
|
|
136
|
+
return [{ time: 0, open: 0, high: 0, low: 0, close: 0, volume: 0 }];
|
|
137
|
+
const first = bars[0].time;
|
|
138
|
+
return syntheticBars(Math.ceil(span / step), step, symbol.length + 7).map((b) => ({
|
|
139
|
+
...b,
|
|
140
|
+
time: first + (b.time - START),
|
|
141
|
+
}));
|
|
142
|
+
},
|
|
143
|
+
symbolInfo: () => ({ timezone, session, mintick: 0.01, currency: 'USD' }),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* A small order engine for checks and tests (the library does not fill orders). Market entries and closes fill at the
|
|
148
|
+
* next bar open; `strategy.exit` stop / limit levels are checked inside each bar (stop first when both are hit).
|
|
149
|
+
* Entry limit / stop prices, pyramiding and process_orders_on_close are not simulated.
|
|
150
|
+
*/
|
|
151
|
+
export class TestEngine {
|
|
152
|
+
setup;
|
|
153
|
+
closed = [];
|
|
154
|
+
open = null;
|
|
155
|
+
pendingEntry = null;
|
|
156
|
+
pendingClose = false;
|
|
157
|
+
exits = new Map();
|
|
158
|
+
net = 0;
|
|
159
|
+
bar = 0;
|
|
160
|
+
constructor(setup) {
|
|
161
|
+
this.setup = setup;
|
|
162
|
+
}
|
|
163
|
+
get bars() {
|
|
164
|
+
return this.setup.bars;
|
|
165
|
+
}
|
|
166
|
+
equity(price) {
|
|
167
|
+
return this.setup.properties.initial_capital + this.net + this.openProfit(price);
|
|
168
|
+
}
|
|
169
|
+
openProfit(price) {
|
|
170
|
+
return this.open ? (price - this.open.entry_price) * this.open.size : 0;
|
|
171
|
+
}
|
|
172
|
+
commission(value) {
|
|
173
|
+
const p = this.setup.properties;
|
|
174
|
+
return p.commission_type === 'percent' ? (Math.abs(value) * p.commission_value) / 100 : 0;
|
|
175
|
+
}
|
|
176
|
+
closeAt(price, exitId) {
|
|
177
|
+
const t = this.open;
|
|
178
|
+
if (!t)
|
|
179
|
+
return;
|
|
180
|
+
const commission = t.commission + this.commission(price * t.size);
|
|
181
|
+
const profit = (price - t.entry_price) * t.size - commission;
|
|
182
|
+
this.net += profit;
|
|
183
|
+
this.closed.push({
|
|
184
|
+
...t,
|
|
185
|
+
commission,
|
|
186
|
+
profit,
|
|
187
|
+
profit_percent: (profit / Math.abs(t.entry_price * t.size)) * 100,
|
|
188
|
+
exit_id: exitId,
|
|
189
|
+
exit_price: price,
|
|
190
|
+
exit_bar_index: this.bar,
|
|
191
|
+
exit_time: this.bars[this.bar].time * 1000,
|
|
192
|
+
});
|
|
193
|
+
this.open = null;
|
|
194
|
+
this.exits.clear();
|
|
195
|
+
}
|
|
196
|
+
/** The open trade, if any. */
|
|
197
|
+
get openTradeNow() {
|
|
198
|
+
return this.open;
|
|
199
|
+
}
|
|
200
|
+
processBar(bar) {
|
|
201
|
+
this.bar = bar;
|
|
202
|
+
const b = this.bars[bar];
|
|
203
|
+
if (this.pendingClose)
|
|
204
|
+
this.closeAt(b.open, 'Close');
|
|
205
|
+
this.pendingClose = false;
|
|
206
|
+
const e = this.pendingEntry;
|
|
207
|
+
this.pendingEntry = null;
|
|
208
|
+
if (e && !(this.open && Math.sign(this.open.size) === (e.direction === 'long' ? 1 : -1))) {
|
|
209
|
+
if (this.open)
|
|
210
|
+
this.closeAt(b.open, e.id);
|
|
211
|
+
const p = this.setup.properties;
|
|
212
|
+
const equity = this.equity(b.open);
|
|
213
|
+
const qty = e.qty ??
|
|
214
|
+
(p.default_qty_type === 'fixed'
|
|
215
|
+
? p.default_qty_value
|
|
216
|
+
: p.default_qty_type === 'cash'
|
|
217
|
+
? p.default_qty_value / b.open
|
|
218
|
+
: (equity * p.default_qty_value) / 100 / b.open);
|
|
219
|
+
const size = e.direction === 'long' ? qty : -qty;
|
|
220
|
+
this.open = {
|
|
221
|
+
entry_id: e.id,
|
|
222
|
+
entry_price: b.open,
|
|
223
|
+
entry_bar_index: bar,
|
|
224
|
+
entry_time: b.time * 1000,
|
|
225
|
+
size,
|
|
226
|
+
profit: 0,
|
|
227
|
+
profit_percent: 0,
|
|
228
|
+
commission: this.commission(b.open * size),
|
|
229
|
+
max_runup: 0,
|
|
230
|
+
max_runup_percent: 0,
|
|
231
|
+
max_drawdown: 0,
|
|
232
|
+
max_drawdown_percent: 0,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
const t = this.open;
|
|
236
|
+
if (!t)
|
|
237
|
+
return;
|
|
238
|
+
for (const [id, x] of this.exits) {
|
|
239
|
+
if (x.from_entry !== undefined && x.from_entry !== t.entry_id)
|
|
240
|
+
continue;
|
|
241
|
+
const long = t.size > 0;
|
|
242
|
+
if (x.stop !== undefined && (long ? b.low <= x.stop : b.high >= x.stop)) {
|
|
243
|
+
this.closeAt(long ? Math.min(b.open, x.stop) : Math.max(b.open, x.stop), id);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (x.limit !== undefined && (long ? b.high >= x.limit : b.low <= x.limit)) {
|
|
247
|
+
this.closeAt(long ? Math.max(b.open, x.limit) : Math.min(b.open, x.limit), id);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
processClose() { }
|
|
253
|
+
entry(id, direction, options) {
|
|
254
|
+
this.pendingEntry = { id, direction, qty: options.qty };
|
|
255
|
+
}
|
|
256
|
+
order(id, direction, options) {
|
|
257
|
+
this.entry(id, direction, options);
|
|
258
|
+
}
|
|
259
|
+
exit(id, options) {
|
|
260
|
+
this.exits.set(id, options);
|
|
261
|
+
}
|
|
262
|
+
close(id, _options) {
|
|
263
|
+
if (this.open?.entry_id === id)
|
|
264
|
+
this.pendingClose = true;
|
|
265
|
+
}
|
|
266
|
+
close_all() {
|
|
267
|
+
if (this.open)
|
|
268
|
+
this.pendingClose = true;
|
|
269
|
+
}
|
|
270
|
+
cancel(id) {
|
|
271
|
+
this.exits.delete(id);
|
|
272
|
+
if (this.pendingEntry?.id === id)
|
|
273
|
+
this.pendingEntry = null;
|
|
274
|
+
}
|
|
275
|
+
cancel_all() {
|
|
276
|
+
this.exits.clear();
|
|
277
|
+
this.pendingEntry = null;
|
|
278
|
+
}
|
|
279
|
+
rules = [];
|
|
280
|
+
risk(rule) {
|
|
281
|
+
this.rules.push(rule);
|
|
282
|
+
}
|
|
283
|
+
get(variable) {
|
|
284
|
+
const price = this.bars[this.bar]?.close ?? NaN;
|
|
285
|
+
const wins = this.closed.filter((t) => t.profit > 0).length;
|
|
286
|
+
const values = {
|
|
287
|
+
position_size: this.open?.size ?? 0,
|
|
288
|
+
position_avg_price: this.open?.entry_price ?? NaN,
|
|
289
|
+
initial_capital: this.setup.properties.initial_capital,
|
|
290
|
+
equity: this.equity(price),
|
|
291
|
+
netprofit: this.net,
|
|
292
|
+
openprofit: this.openProfit(price),
|
|
293
|
+
opentrades: this.open ? 1 : 0,
|
|
294
|
+
closedtrades: this.closed.length,
|
|
295
|
+
wintrades: wins,
|
|
296
|
+
losstrades: this.closed.length - wins,
|
|
297
|
+
account_currency: 'USD',
|
|
298
|
+
};
|
|
299
|
+
return values[variable];
|
|
300
|
+
}
|
|
301
|
+
openTrade(index) {
|
|
302
|
+
return index === 0 && this.open ? this.open : undefined;
|
|
303
|
+
}
|
|
304
|
+
closedTrade(index) {
|
|
305
|
+
return this.closed[index];
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/** Runs a script source on `bars` with the test chart context and, for a strategy, the test engine. */
|
|
309
|
+
export function runScript(source, bars, inputs = {}, options = {}) {
|
|
310
|
+
let engine;
|
|
311
|
+
const body = (options.compile ?? compileScript)(source);
|
|
312
|
+
const run = executeScript(body, bars, inputs, testChart(bars, options), {
|
|
313
|
+
strategyEngine: (setup) => (engine = new TestEngine(setup)),
|
|
314
|
+
});
|
|
315
|
+
return { run, engine };
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../src/check/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Checks a script source: runs it like a host (a declaration run on zero bars, then a run on bars) and
|
|
3
|
+
* returns a report an agent or a host can act on: what the script declares (inputs, outputs, strategy), what its outputs
|
|
4
|
+
* contain (values, warm-up, ranges, signal counts, trades), warnings for the mistakes that give no error (an empty plot,
|
|
5
|
+
* a signal on every bar or never, an input that changes nothing...), and the result of a spec (the expected inputs,
|
|
6
|
+
* outputs and signals) and of a reference (expected values per bar). The `oakscript check` command prints it.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { checkScript } from 'oakscriptjs/check';
|
|
10
|
+
* const report = checkScript(source, { spec: { overlay: true, outputs: ['Fast', 'Slow'] } });
|
|
11
|
+
* report.ok; report.errors; report.warnings; report.spec?.items;
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @module check
|
|
15
|
+
*/
|
|
16
|
+
import type { Bar } from '../types/index.js';
|
|
17
|
+
import type { InputConfig } from '../runtime/types.js';
|
|
18
|
+
import { type TestChartOptions } from './harness.js';
|
|
19
|
+
import { type CheckContext, type CheckItem } from './checks.js';
|
|
20
|
+
export { validateSpec, specJsonSchema, SPEC_FIELDS, SPEC_FILE_FIELDS } from './spec.js';
|
|
21
|
+
export { runChecks, signalBars, type CheckContext, type CheckItem, type CheckPlot, type CheckSignal, type SignalBars } from './checks.js';
|
|
22
|
+
export { formatReport, assertCheck } from './format.js';
|
|
23
|
+
export { compileScript, inferTimeframe, rewriteImports, runScript, scriptArguments, syntheticBars, testChart, timeframeSeconds, LIBRARY_PARAMETER, SCRIPT_GLOBALS, SCRIPT_PREFIX, SCRIPT_SUFFIX, TestEngine, wrapSource, type RunScriptOptions, type ScriptRun, type TestChartOptions, } from './harness.js';
|
|
24
|
+
/** Expected count of a signal (a shape, character, arrow, alert condition, background or bar colour) over the bars. */
|
|
25
|
+
export interface SignalSpec {
|
|
26
|
+
/** At least this many bars with the signal. */
|
|
27
|
+
min?: number;
|
|
28
|
+
/** At most this many bars with the signal. */
|
|
29
|
+
max?: number;
|
|
30
|
+
/** At least this share of the bars (0 to 1). */
|
|
31
|
+
minShare?: number;
|
|
32
|
+
/** At most this share of the bars (0 to 1). */
|
|
33
|
+
maxShare?: number;
|
|
34
|
+
}
|
|
35
|
+
/** Expected values of a plot. */
|
|
36
|
+
export interface PlotSpec {
|
|
37
|
+
/** Every value is at least this. */
|
|
38
|
+
min?: number;
|
|
39
|
+
/** Every value is at most this. */
|
|
40
|
+
max?: number;
|
|
41
|
+
/** The first value comes at this bar index or before (the warm-up). */
|
|
42
|
+
warmup?: number;
|
|
43
|
+
}
|
|
44
|
+
/** Expected input: the keys are compared when given. */
|
|
45
|
+
export interface InputSpec {
|
|
46
|
+
type?: InputConfig['type'];
|
|
47
|
+
defval?: unknown;
|
|
48
|
+
title?: string;
|
|
49
|
+
min?: number;
|
|
50
|
+
max?: number;
|
|
51
|
+
options?: string[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* What the user asked for, written before the script: each given entry is checked. Inputs, plots and signals are
|
|
55
|
+
* found by id or title (case insensitive).
|
|
56
|
+
*/
|
|
57
|
+
export interface CheckSpec {
|
|
58
|
+
kind?: 'indicator' | 'strategy';
|
|
59
|
+
title?: string;
|
|
60
|
+
overlay?: boolean;
|
|
61
|
+
/** Inputs that must exist, with the expected type, default... */
|
|
62
|
+
inputs?: Record<string, InputSpec>;
|
|
63
|
+
/** Outputs that must exist (a title, or a title and a kind: plot, shape, char, arrow, candle, bar, hline, bgcolor, barcolor, alertcondition). */
|
|
64
|
+
outputs?: Array<string | {
|
|
65
|
+
title: string;
|
|
66
|
+
kind?: string;
|
|
67
|
+
}>;
|
|
68
|
+
/** Value checks per plot. */
|
|
69
|
+
plots?: Record<string, PlotSpec>;
|
|
70
|
+
/** Count checks per signal. */
|
|
71
|
+
signals?: Record<string, SignalSpec>;
|
|
72
|
+
/** Number of closed trades of a strategy. */
|
|
73
|
+
trades?: {
|
|
74
|
+
min?: number;
|
|
75
|
+
max?: number;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** Expected values per bar, e.g. the outputs of the Pine script a port follows, on the same bars. */
|
|
79
|
+
export interface CheckReference {
|
|
80
|
+
/** Bar times (UNIX seconds). */
|
|
81
|
+
times: number[];
|
|
82
|
+
/** Expected values per plot id or title, aligned with `times` (NaN or null: na). */
|
|
83
|
+
columns: Record<string, Array<number | null>>;
|
|
84
|
+
/** Equal when |a - b| <= tolerance * max(1, |a|, |b|) (default 1e-10), or both na. */
|
|
85
|
+
tolerance?: number;
|
|
86
|
+
/** A column without a plot of that id or title is listed as ignored instead of failing (a chart export holds other columns). */
|
|
87
|
+
ignoreUnknown?: boolean;
|
|
88
|
+
}
|
|
89
|
+
/** A run on edge-case bars (`scenarios: true`): a short history, daily bars, flat prices, no volume, a gap. */
|
|
90
|
+
export interface CheckScenario {
|
|
91
|
+
name: string;
|
|
92
|
+
description: string;
|
|
93
|
+
timeframe: string;
|
|
94
|
+
bars: () => Bar[];
|
|
95
|
+
}
|
|
96
|
+
export interface CheckOptions extends TestChartOptions {
|
|
97
|
+
/** Bars of the run (default: 1,500 deterministic synthetic bars of the timeframe). */
|
|
98
|
+
bars?: Bar[];
|
|
99
|
+
/** Input values by id (default: the defaults). */
|
|
100
|
+
inputs?: Record<string, unknown>;
|
|
101
|
+
spec?: CheckSpec;
|
|
102
|
+
reference?: CheckReference;
|
|
103
|
+
/** Compiles the source (default: `new Function`; the CLI compiles with the file name for error lines). */
|
|
104
|
+
compile?: (source: string) => () => void;
|
|
105
|
+
/** Wraps each run (the CLI stops a run that takes too long). */
|
|
106
|
+
run?: <T>(fn: () => T) => T;
|
|
107
|
+
/** File name of the source, to read the error lines from the stack (`<file>:line:column`). */
|
|
108
|
+
filename?: string;
|
|
109
|
+
/** Re-run with each input changed to find inputs that change no output (default true). */
|
|
110
|
+
inputSweep?: boolean;
|
|
111
|
+
/** Behaviour checks: called with the outputs of the run per bar (see {@link CheckContext}); their results join the spec items. */
|
|
112
|
+
checks?: (t: CheckContext) => void;
|
|
113
|
+
/** Also run on the edge-case bars of {@link SCENARIOS} (or the given ones): their errors fail the check. */
|
|
114
|
+
scenarios?: boolean | CheckScenario[];
|
|
115
|
+
}
|
|
116
|
+
export type CheckStage = 'syntax' | 'types' | 'declaration' | 'run' | 'timeout' | 'spec' | 'reference' | 'scenario';
|
|
117
|
+
export interface CheckError {
|
|
118
|
+
stage: CheckStage;
|
|
119
|
+
message: string;
|
|
120
|
+
line?: number;
|
|
121
|
+
column?: number;
|
|
122
|
+
/** TypeScript error code (stage "types"). */
|
|
123
|
+
code?: string;
|
|
124
|
+
}
|
|
125
|
+
export interface CheckWarning {
|
|
126
|
+
code: 'empty-plot' | 'constant-plot' | 'late-start' | 'signal-never' | 'signal-everywhere' | 'one-colour' | 'unused-input' | 'input-error' | 'no-trades' | 'no-output';
|
|
127
|
+
message: string;
|
|
128
|
+
/** Output or input title (or id). */
|
|
129
|
+
target?: string;
|
|
130
|
+
}
|
|
131
|
+
export interface PlotSummary {
|
|
132
|
+
id: string;
|
|
133
|
+
title: string;
|
|
134
|
+
/** Bars with a value (not na). */
|
|
135
|
+
values: number;
|
|
136
|
+
/** Bar index of the first value (-1: none). */
|
|
137
|
+
firstBar: number;
|
|
138
|
+
min: number | null;
|
|
139
|
+
max: number | null;
|
|
140
|
+
/** Values of the last 5 bars (null: na). */
|
|
141
|
+
last: Array<number | null>;
|
|
142
|
+
/** Distinct per-bar colours (0: the plot colour is the same on every bar). */
|
|
143
|
+
colours: number;
|
|
144
|
+
}
|
|
145
|
+
export interface SignalSummary {
|
|
146
|
+
kind: 'shape' | 'char' | 'arrow' | 'alertcondition' | 'bgcolor' | 'barcolor';
|
|
147
|
+
id: string;
|
|
148
|
+
title: string;
|
|
149
|
+
/** Bars with the signal. */
|
|
150
|
+
count: number;
|
|
151
|
+
/** count / number of bars. */
|
|
152
|
+
share: number;
|
|
153
|
+
firstBar: number;
|
|
154
|
+
lastBar: number;
|
|
155
|
+
}
|
|
156
|
+
export interface TradeSummary {
|
|
157
|
+
entry: string;
|
|
158
|
+
direction: 'long' | 'short';
|
|
159
|
+
entryBar: number;
|
|
160
|
+
entryPrice: number;
|
|
161
|
+
exitBar: number | null;
|
|
162
|
+
exitPrice: number | null;
|
|
163
|
+
profit: number;
|
|
164
|
+
}
|
|
165
|
+
export interface CheckReport {
|
|
166
|
+
/** No error, no failed spec or reference check. Warnings do not change it. */
|
|
167
|
+
ok: boolean;
|
|
168
|
+
bars: {
|
|
169
|
+
count: number;
|
|
170
|
+
first: number | null;
|
|
171
|
+
last: number | null;
|
|
172
|
+
timeframe: string;
|
|
173
|
+
synthetic: boolean;
|
|
174
|
+
};
|
|
175
|
+
errors: CheckError[];
|
|
176
|
+
warnings: CheckWarning[];
|
|
177
|
+
declaration?: {
|
|
178
|
+
kind: 'indicator' | 'strategy';
|
|
179
|
+
title: string;
|
|
180
|
+
shortTitle?: string;
|
|
181
|
+
overlay: boolean;
|
|
182
|
+
inputs: Array<Pick<InputConfig, 'id' | 'type' | 'defval' | 'title' | 'min' | 'max' | 'options'>>;
|
|
183
|
+
outputs: Array<{
|
|
184
|
+
kind: string;
|
|
185
|
+
id: string;
|
|
186
|
+
title: string;
|
|
187
|
+
}>;
|
|
188
|
+
strategy?: Record<string, unknown>;
|
|
189
|
+
};
|
|
190
|
+
plots: PlotSummary[];
|
|
191
|
+
signals: SignalSummary[];
|
|
192
|
+
drawings: {
|
|
193
|
+
labels: number;
|
|
194
|
+
lines: number;
|
|
195
|
+
boxes: number;
|
|
196
|
+
tables: number;
|
|
197
|
+
polylines: number;
|
|
198
|
+
linefills: number;
|
|
199
|
+
};
|
|
200
|
+
/** alert() calls of the script (all bars). */
|
|
201
|
+
alertCalls: number;
|
|
202
|
+
strategy?: {
|
|
203
|
+
closedTrades: number;
|
|
204
|
+
openTrade: boolean;
|
|
205
|
+
netProfit: number;
|
|
206
|
+
wins: number;
|
|
207
|
+
first: TradeSummary[];
|
|
208
|
+
};
|
|
209
|
+
/** Spec items and behaviour checks. */
|
|
210
|
+
spec?: {
|
|
211
|
+
passed: number;
|
|
212
|
+
failed: number;
|
|
213
|
+
items: CheckItem[];
|
|
214
|
+
};
|
|
215
|
+
reference?: Array<{
|
|
216
|
+
column: string;
|
|
217
|
+
output?: string;
|
|
218
|
+
/** No plot of this id or title, and `ignoreUnknown` is set. */
|
|
219
|
+
ignored?: boolean;
|
|
220
|
+
equal: number;
|
|
221
|
+
total: number;
|
|
222
|
+
firstMismatch?: {
|
|
223
|
+
bar: number;
|
|
224
|
+
time: number;
|
|
225
|
+
expected: number | null;
|
|
226
|
+
actual: number | null;
|
|
227
|
+
};
|
|
228
|
+
}>;
|
|
229
|
+
/** Runs on edge-case bars: their errors (also in `errors`, stage "scenario") and the plots with no value the main run does not have. */
|
|
230
|
+
scenarios?: Array<{
|
|
231
|
+
name: string;
|
|
232
|
+
description: string;
|
|
233
|
+
bars: number;
|
|
234
|
+
errors: CheckError[];
|
|
235
|
+
warnings: CheckWarning[];
|
|
236
|
+
}>;
|
|
237
|
+
}
|
|
238
|
+
/** Line and column of a script error, from `error.scriptLine` or the `<filename>:line:column` frames of its stack. */
|
|
239
|
+
export declare function errorLocation(error: unknown, filename?: string): {
|
|
240
|
+
line?: number;
|
|
241
|
+
column?: number;
|
|
242
|
+
};
|
|
243
|
+
/** Default number of synthetic bars of a check. */
|
|
244
|
+
export declare const CHECK_BARS = 1500;
|
|
245
|
+
/** The edge-case bars of `scenarios: true`. */
|
|
246
|
+
export declare const SCENARIOS: readonly CheckScenario[];
|
|
247
|
+
/**
|
|
248
|
+
* Checks a script source (the body of a script, as a host runs it): compiles it, runs it on zero bars (the
|
|
249
|
+
* declarations) and on the bars, and reports its declarations, outputs, warnings and the spec / reference results.
|
|
250
|
+
* Never throws for a script error: the errors are in the report.
|
|
251
|
+
*/
|
|
252
|
+
export declare function checkScript(source: string, options?: CheckOptions): CheckReport;
|
|
253
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/check/index.ts"],"names":[],"mappings":"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"}
|