@hoox-sh/pynets 0.1.0 → 0.2.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.
- package/CHANGELOG.md +20 -0
- package/README.md +5 -3
- package/dist/browser.js +90 -34
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4441 -411
- package/package.json +1 -1
- package/src/cli/rich.ts +4 -3
- package/src/cli.ts +29 -7
- package/src/index.ts +21 -0
- package/src/runtime/compile/collections.ts +339 -0
- package/src/runtime/compile/draw.ts +181 -0
- package/src/runtime/compile/emit.ts +1164 -0
- package/src/runtime/compile/emit_call.ts +1406 -0
- package/src/runtime/compile/emit_udf.ts +326 -0
- package/src/runtime/compile/engine.ts +265 -0
- package/src/runtime/compile/helpers.ts +140 -0
- package/src/runtime/compile/index.ts +33 -0
- package/src/runtime/compile/runtime.ts +297 -0
- package/src/runtime/compile/strategy.ts +169 -0
- package/src/runtime/compile/types.ts +125 -0
- package/src/runtime/compile/udt_runtime.ts +50 -0
- package/src/runtime/interpret.ts +192 -10
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2024-2026 jango_blockchained
|
|
3
|
+
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
*
|
|
5
|
+
* Compile-path types. TS compile is JS emit (Python object-mode analog).
|
|
6
|
+
* No Numba / nopython backend.
|
|
7
|
+
*/
|
|
8
|
+
import type { Call, FunctionDef, expr, stmt } from "../../ast/nodes.ts";
|
|
9
|
+
|
|
10
|
+
export type CompileBackend = "js";
|
|
11
|
+
|
|
12
|
+
export type RuntimeMode = "interpret" | "compile" | "auto";
|
|
13
|
+
|
|
14
|
+
export interface CompilePlotMeta {
|
|
15
|
+
title: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CompileEligibility {
|
|
19
|
+
ok: boolean;
|
|
20
|
+
reason?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class CompileError extends Error {
|
|
24
|
+
constructor(message: string) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "CompileError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class CompileEmitError extends CompileError {
|
|
31
|
+
constructor(message: string) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "CompileEmitError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class CompileLoadError extends CompileError {
|
|
38
|
+
constructor(message: string) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = "CompileLoadError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class CompileIneligibleError extends CompileError {
|
|
45
|
+
constructor(message: string) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.name = "CompileIneligibleError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Visitor state while lowering a Script to JS. */
|
|
52
|
+
export interface EmitCtx {
|
|
53
|
+
arrays: Set<string>;
|
|
54
|
+
plots: CompilePlotMeta[];
|
|
55
|
+
varNames: Set<string>;
|
|
56
|
+
functions: string[];
|
|
57
|
+
userFuncs: Set<string>;
|
|
58
|
+
usesStrategy: boolean;
|
|
59
|
+
nextSite: number;
|
|
60
|
+
errors: string[];
|
|
61
|
+
/** Pine UDF name currently being emitted (null at script scope). */
|
|
62
|
+
currentFunc: string | null;
|
|
63
|
+
/** Formal names of the current UDF. */
|
|
64
|
+
currentParamNames: Set<string>;
|
|
65
|
+
/** Current UDF formals that must be passed as full series arrays. */
|
|
66
|
+
currentSeriesParams: Set<string>;
|
|
67
|
+
/** Pine UDF name → series formal names (call-site packing). */
|
|
68
|
+
funcSeriesParams: Map<string, Set<string>>;
|
|
69
|
+
/** Pine UDF name → formal order. */
|
|
70
|
+
funcParamNames: Map<string, string[]>;
|
|
71
|
+
/** Persistent `__st_*` arrays allocated in the bar-loop frame. */
|
|
72
|
+
stArrays: Set<string>;
|
|
73
|
+
/** type name → field order + default JS exprs. */
|
|
74
|
+
udtTypes: Map<string, { fields: string[]; defaults: Record<string, string> }>;
|
|
75
|
+
usesDrawings: boolean;
|
|
76
|
+
/** enum name → member names. */
|
|
77
|
+
enumTypes: Map<string, string[]>;
|
|
78
|
+
/** Method names collected from TypeDef FunctionDefs. */
|
|
79
|
+
udtMethodNames: Set<string>;
|
|
80
|
+
needsHeikinashi: boolean;
|
|
81
|
+
importAliases: Set<string>;
|
|
82
|
+
getLibrary?: (namespace: string, name: string, version: number) => string | null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface EmitFns {
|
|
86
|
+
visit(node: expr | stmt | null | undefined): string;
|
|
87
|
+
visitStmt(node: stmt): string;
|
|
88
|
+
emitCall(node: Call): string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type VisitFn = (node: expr | stmt | null | undefined) => string;
|
|
92
|
+
|
|
93
|
+
export type EmitCallFn = (ctx: EmitCtx, node: Call, visit: VisitFn) => string;
|
|
94
|
+
|
|
95
|
+
export type EmitUdfFn = (ctx: EmitCtx, node: FunctionDef, visitStmt: (s: stmt) => string) => void;
|
|
96
|
+
|
|
97
|
+
/** Generated module entry: arrays in, titled plot series out. */
|
|
98
|
+
export type ExecuteCompiled = (
|
|
99
|
+
open: Array<number | null>,
|
|
100
|
+
high: Array<number | null>,
|
|
101
|
+
low: Array<number | null>,
|
|
102
|
+
close: Array<number | null>,
|
|
103
|
+
volume: Array<number | null>,
|
|
104
|
+
time: Array<number | null>,
|
|
105
|
+
) => Record<string, Array<number | null>>;
|
|
106
|
+
|
|
107
|
+
export interface CompiledScript {
|
|
108
|
+
readonly source: string;
|
|
109
|
+
readonly plots: CompilePlotMeta[];
|
|
110
|
+
readonly backend: CompileBackend;
|
|
111
|
+
run(
|
|
112
|
+
open: ArrayLike<number | null | undefined>,
|
|
113
|
+
high: ArrayLike<number | null | undefined>,
|
|
114
|
+
low: ArrayLike<number | null | undefined>,
|
|
115
|
+
close: ArrayLike<number | null | undefined>,
|
|
116
|
+
volume?: ArrayLike<number | null | undefined> | null,
|
|
117
|
+
time?: ArrayLike<number | null | undefined> | null,
|
|
118
|
+
extras?: { inputs?: Record<string, number | string | boolean> },
|
|
119
|
+
): Record<string, Array<number | null>>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface CompileCacheStats {
|
|
123
|
+
source_entries: number;
|
|
124
|
+
source_max: number;
|
|
125
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2024-2026 jango_blockchained
|
|
3
|
+
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
*
|
|
5
|
+
* Compile-path UDT helpers: dict-like instances (`__type__` + fields).
|
|
6
|
+
*/
|
|
7
|
+
import { UdtInstance, UdtType } from "../udt.ts";
|
|
8
|
+
|
|
9
|
+
const types = new Map<string, UdtType>();
|
|
10
|
+
|
|
11
|
+
export function udtRegister(name: string, fields: string[], defaults?: Record<string, unknown>): void {
|
|
12
|
+
types.set(
|
|
13
|
+
name,
|
|
14
|
+
new UdtType(
|
|
15
|
+
name,
|
|
16
|
+
fields.map((f) => ({ name: f, default: defaults?.[f] ?? null })),
|
|
17
|
+
),
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function udtNew(name: string, overrides?: Record<string, unknown>): UdtInstance | Record<string, unknown> {
|
|
22
|
+
let t = types.get(name);
|
|
23
|
+
if (t == null) {
|
|
24
|
+
const fields = overrides != null ? Object.keys(overrides) : [];
|
|
25
|
+
t = new UdtType(name, fields.map((f) => ({ name: f, default: null })));
|
|
26
|
+
types.set(name, t);
|
|
27
|
+
}
|
|
28
|
+
return t.newInstance(overrides);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function udtGet(obj: unknown, field: string): unknown {
|
|
32
|
+
if (obj instanceof UdtInstance) return obj.get(field);
|
|
33
|
+
if (obj != null && typeof obj === "object") {
|
|
34
|
+
const rec = obj as Record<string, unknown>;
|
|
35
|
+
return rec[field] ?? null;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function udtSet(obj: unknown, field: string, value: unknown): unknown {
|
|
41
|
+
if (obj instanceof UdtInstance) {
|
|
42
|
+
obj.set(field, value);
|
|
43
|
+
return obj;
|
|
44
|
+
}
|
|
45
|
+
if (obj != null && typeof obj === "object") {
|
|
46
|
+
(obj as Record<string, unknown>)[field] = value;
|
|
47
|
+
return obj;
|
|
48
|
+
}
|
|
49
|
+
return obj ?? null;
|
|
50
|
+
}
|
package/src/runtime/interpret.ts
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* arrays, color/str, strategy events + position series, input*, math.*,
|
|
8
8
|
* request.security, UDF FunctionDef, matrix.*, extra TA, drawings/alert,
|
|
9
9
|
* derived prices, calendar, Pine na-compare.
|
|
10
|
-
* Not a port of runtime/host.py — same public envelope
|
|
10
|
+
* Not a port of runtime/host.py — same public envelope.
|
|
11
|
+
* Compile is JS emit in ./compile/ (mode compile|auto).
|
|
11
12
|
*/
|
|
12
13
|
import { parse } from "../ast/helper.ts";
|
|
13
14
|
import type {
|
|
@@ -141,6 +142,12 @@ import { StrategyBook, type BrokerSettings, type StrategyEvent, type StrategySum
|
|
|
141
142
|
import { PineMap } from "./map.ts";
|
|
142
143
|
import { PineMatrix } from "./matrix.ts";
|
|
143
144
|
import { TaEngine } from "./ta.ts";
|
|
145
|
+
import {
|
|
146
|
+
CompileError,
|
|
147
|
+
compileEligible,
|
|
148
|
+
compileScript,
|
|
149
|
+
} from "./compile/index.ts";
|
|
150
|
+
import type { RuntimeMode } from "./compile/types.ts";
|
|
144
151
|
|
|
145
152
|
export type { DrawingEvent };
|
|
146
153
|
|
|
@@ -162,6 +169,8 @@ export interface RuntimeOptions {
|
|
|
162
169
|
broker?: BrokerSettings;
|
|
163
170
|
timeframe?: string | null;
|
|
164
171
|
libraries?: LibraryRegistry;
|
|
172
|
+
/** interpret (default) | compile (JS emit) | auto (compile, fallback interpret). */
|
|
173
|
+
mode?: RuntimeMode;
|
|
165
174
|
}
|
|
166
175
|
|
|
167
176
|
export interface RuntimeFill {
|
|
@@ -180,7 +189,9 @@ export interface RuntimeResult {
|
|
|
180
189
|
count: number;
|
|
181
190
|
script_name: string | null;
|
|
182
191
|
script_type: string;
|
|
183
|
-
mode: "interpret";
|
|
192
|
+
mode: "interpret" | "compile";
|
|
193
|
+
auto_backend?: "interpret" | "compile";
|
|
194
|
+
compile_fallback_reason?: string;
|
|
184
195
|
events?: StrategyEvent[];
|
|
185
196
|
fills?: RuntimeFill[];
|
|
186
197
|
drawings?: DrawingEvent[];
|
|
@@ -290,6 +301,7 @@ export class Runtime {
|
|
|
290
301
|
readonly broker: BrokerSettings;
|
|
291
302
|
readonly timeframe: string | null;
|
|
292
303
|
readonly libraries: LibraryRegistry;
|
|
304
|
+
readonly mode: RuntimeMode;
|
|
293
305
|
|
|
294
306
|
constructor(
|
|
295
307
|
public readonly symbol = "AAPL",
|
|
@@ -299,6 +311,7 @@ export class Runtime {
|
|
|
299
311
|
this.broker = options?.broker ?? {};
|
|
300
312
|
this.timeframe = options?.timeframe ?? null;
|
|
301
313
|
this.libraries = options?.libraries ?? new LibraryRegistry();
|
|
314
|
+
this.mode = options?.mode ?? "interpret";
|
|
302
315
|
}
|
|
303
316
|
|
|
304
317
|
/** Store Pine source for `import namespace/name/version`. */
|
|
@@ -328,14 +341,23 @@ export class Runtime {
|
|
|
328
341
|
};
|
|
329
342
|
}
|
|
330
343
|
const extraOpts = extra && !isPlainInputs(extra) ? extra : undefined;
|
|
344
|
+
const mode = extraOpts?.mode ?? this.mode;
|
|
345
|
+
const inputs = mergeInputs(this.inputs, extra);
|
|
346
|
+
const host = {
|
|
347
|
+
symbol: this.symbol,
|
|
348
|
+
inputs,
|
|
349
|
+
broker: extraOpts?.broker ?? this.broker,
|
|
350
|
+
timeframe: extraOpts?.timeframe ?? this.timeframe,
|
|
351
|
+
libraries: extraOpts?.libraries ?? this.libraries,
|
|
352
|
+
};
|
|
353
|
+
if (mode === "compile") {
|
|
354
|
+
return runCompiled(source, ohlcv, host);
|
|
355
|
+
}
|
|
356
|
+
if (mode === "auto") {
|
|
357
|
+
return runAuto(source, tree, ohlcv, host);
|
|
358
|
+
}
|
|
331
359
|
try {
|
|
332
|
-
return interpretTree(tree, ohlcv,
|
|
333
|
-
symbol: this.symbol,
|
|
334
|
-
inputs: mergeInputs(this.inputs, extra),
|
|
335
|
-
broker: extraOpts?.broker ?? this.broker,
|
|
336
|
-
timeframe: extraOpts?.timeframe ?? this.timeframe,
|
|
337
|
-
libraries: extraOpts?.libraries ?? this.libraries,
|
|
338
|
-
});
|
|
360
|
+
return interpretTree(tree, ohlcv, host);
|
|
339
361
|
} catch (err) {
|
|
340
362
|
return {
|
|
341
363
|
series: {},
|
|
@@ -1865,7 +1887,167 @@ function formatRunError(err: unknown): string {
|
|
|
1865
1887
|
}
|
|
1866
1888
|
|
|
1867
1889
|
function isPlainInputs(extra: RuntimeOptions | InputOverrides): extra is InputOverrides {
|
|
1868
|
-
return
|
|
1890
|
+
return (
|
|
1891
|
+
!("inputs" in extra) &&
|
|
1892
|
+
!("broker" in extra) &&
|
|
1893
|
+
!("timeframe" in extra) &&
|
|
1894
|
+
!("libraries" in extra) &&
|
|
1895
|
+
!("mode" in extra)
|
|
1896
|
+
);
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
function emptyCompileResult(
|
|
1900
|
+
n: number,
|
|
1901
|
+
error: string,
|
|
1902
|
+
extra?: Pick<RuntimeResult, "auto_backend" | "compile_fallback_reason">,
|
|
1903
|
+
): RuntimeResult {
|
|
1904
|
+
return {
|
|
1905
|
+
series: {},
|
|
1906
|
+
plots: [],
|
|
1907
|
+
plot_meta: [],
|
|
1908
|
+
count: n,
|
|
1909
|
+
script_name: null,
|
|
1910
|
+
script_type: "indicator",
|
|
1911
|
+
mode: "compile",
|
|
1912
|
+
error,
|
|
1913
|
+
error_kind: "compile",
|
|
1914
|
+
...extra,
|
|
1915
|
+
};
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
function barsToColumns(ohlcv: OHLCVBar[]): {
|
|
1919
|
+
open: Array<number | null>;
|
|
1920
|
+
high: Array<number | null>;
|
|
1921
|
+
low: Array<number | null>;
|
|
1922
|
+
close: Array<number | null>;
|
|
1923
|
+
volume: Array<number | null>;
|
|
1924
|
+
time: Array<number | null>;
|
|
1925
|
+
} {
|
|
1926
|
+
const n = ohlcv.length;
|
|
1927
|
+
const open: Array<number | null> = new Array(n);
|
|
1928
|
+
const high: Array<number | null> = new Array(n);
|
|
1929
|
+
const low: Array<number | null> = new Array(n);
|
|
1930
|
+
const close: Array<number | null> = new Array(n);
|
|
1931
|
+
const volume: Array<number | null> = new Array(n);
|
|
1932
|
+
const time: Array<number | null> = new Array(n);
|
|
1933
|
+
for (let i = 0; i < n; i++) {
|
|
1934
|
+
const b = ohlcv[i]!;
|
|
1935
|
+
const c = b.close ?? null;
|
|
1936
|
+
close[i] = c;
|
|
1937
|
+
open[i] = b.open ?? c;
|
|
1938
|
+
high[i] = b.high ?? c;
|
|
1939
|
+
low[i] = b.low ?? c;
|
|
1940
|
+
volume[i] = b.volume ?? 1;
|
|
1941
|
+
time[i] = b.time ?? i * 60_000;
|
|
1942
|
+
}
|
|
1943
|
+
return { open, high, low, close, volume, time };
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
function packCompiled(
|
|
1947
|
+
source: string,
|
|
1948
|
+
ohlcv: OHLCVBar[],
|
|
1949
|
+
inputs?: InputOverrides,
|
|
1950
|
+
libraries?: LibraryRegistry,
|
|
1951
|
+
): RuntimeResult {
|
|
1952
|
+
const compiled = compileScript(source, {
|
|
1953
|
+
getLibrary: (ns, name, ver) => libraries?.getSource(ns, name, ver) ?? null,
|
|
1954
|
+
});
|
|
1955
|
+
const cols = barsToColumns(ohlcv);
|
|
1956
|
+
// compileScript().run() is the raw dict (engine CompileHostResult may already strip).
|
|
1957
|
+
const raw = compiled.run(cols.open, cols.high, cols.low, cols.close, cols.volume, cols.time, {
|
|
1958
|
+
inputs,
|
|
1959
|
+
}) as Record<
|
|
1960
|
+
string,
|
|
1961
|
+
unknown
|
|
1962
|
+
> & {
|
|
1963
|
+
__events?: StrategyEvent[];
|
|
1964
|
+
__fills?: Array<{ bar: number; id: string; side: "buy" | "sell"; qty: number; price: number; type?: "fill" }>;
|
|
1965
|
+
__position_size?: number;
|
|
1966
|
+
__netprofit?: number;
|
|
1967
|
+
__equity?: number;
|
|
1968
|
+
__strategy?: StrategySummary;
|
|
1969
|
+
__drawings?: DrawingEvent[];
|
|
1970
|
+
__logs?: LogRecord[];
|
|
1971
|
+
};
|
|
1972
|
+
const events = raw.__events;
|
|
1973
|
+
const fillsIn = raw.__fills;
|
|
1974
|
+
const strategy = raw.__strategy;
|
|
1975
|
+
const drawings = raw.__drawings;
|
|
1976
|
+
const logs = raw.__logs;
|
|
1977
|
+
const series: Record<string, Array<number | null>> = {};
|
|
1978
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
1979
|
+
if (key.startsWith("__")) continue;
|
|
1980
|
+
series[key] = value as Array<number | null>;
|
|
1981
|
+
}
|
|
1982
|
+
const plot_meta = compiled.plots;
|
|
1983
|
+
const first = plot_meta[0]?.title;
|
|
1984
|
+
return {
|
|
1985
|
+
series,
|
|
1986
|
+
plots: first != null ? (series[first] ?? []) : [],
|
|
1987
|
+
plot_meta,
|
|
1988
|
+
count: ohlcv.length,
|
|
1989
|
+
script_name: null,
|
|
1990
|
+
script_type: events != null || strategy != null ? "strategy" : "indicator",
|
|
1991
|
+
mode: "compile",
|
|
1992
|
+
...(events != null ? { events } : {}),
|
|
1993
|
+
...(fillsIn != null
|
|
1994
|
+
? {
|
|
1995
|
+
fills: fillsIn.map((f) =>
|
|
1996
|
+
f.type === "fill" ? (f as RuntimeFill) : { type: "fill" as const, ...f },
|
|
1997
|
+
),
|
|
1998
|
+
}
|
|
1999
|
+
: {}),
|
|
2000
|
+
...(strategy != null ? { strategy } : {}),
|
|
2001
|
+
...(drawings != null ? { drawings } : {}),
|
|
2002
|
+
...(logs != null ? { logs } : {}),
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
function runCompiled(
|
|
2007
|
+
source: string,
|
|
2008
|
+
ohlcv: OHLCVBar[],
|
|
2009
|
+
host: { inputs?: InputOverrides; libraries?: LibraryRegistry },
|
|
2010
|
+
): RuntimeResult {
|
|
2011
|
+
const elig = compileEligible(source);
|
|
2012
|
+
if (!elig.ok) return emptyCompileResult(ohlcv.length, elig.reason ?? "ineligible");
|
|
2013
|
+
try {
|
|
2014
|
+
return packCompiled(source, ohlcv, host.inputs, host.libraries);
|
|
2015
|
+
} catch (err) {
|
|
2016
|
+
const msg = err instanceof CompileError ? err.message : formatRunError(err);
|
|
2017
|
+
return emptyCompileResult(ohlcv.length, msg);
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
function runAuto(
|
|
2022
|
+
source: string,
|
|
2023
|
+
tree: AST,
|
|
2024
|
+
ohlcv: OHLCVBar[],
|
|
2025
|
+
host: {
|
|
2026
|
+
symbol?: string;
|
|
2027
|
+
inputs?: InputOverrides;
|
|
2028
|
+
broker?: BrokerSettings;
|
|
2029
|
+
timeframe?: string | null;
|
|
2030
|
+
libraries?: LibraryRegistry;
|
|
2031
|
+
},
|
|
2032
|
+
): RuntimeResult {
|
|
2033
|
+
const elig = compileEligible(source);
|
|
2034
|
+
if (elig.ok) {
|
|
2035
|
+
try {
|
|
2036
|
+
const compiled = packCompiled(source, ohlcv, host.inputs, host.libraries);
|
|
2037
|
+
compiled.auto_backend = "compile";
|
|
2038
|
+
return compiled;
|
|
2039
|
+
} catch (err) {
|
|
2040
|
+
const reason = err instanceof CompileError ? err.message : formatRunError(err);
|
|
2041
|
+
const out = interpretTree(tree, ohlcv, host);
|
|
2042
|
+
out.auto_backend = "interpret";
|
|
2043
|
+
out.compile_fallback_reason = reason;
|
|
2044
|
+
return out;
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
const out = interpretTree(tree, ohlcv, host);
|
|
2048
|
+
out.auto_backend = "interpret";
|
|
2049
|
+
out.compile_fallback_reason = elig.reason;
|
|
2050
|
+
return out;
|
|
1869
2051
|
}
|
|
1870
2052
|
|
|
1871
2053
|
function mergeInputs(
|