openpinescript 0.0.0-stage → 0.1.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/LICENSE +674 -0
- package/README.md +346 -2
- package/dist/cli.mjs +108686 -0
- package/dist/index.cjs +108670 -0
- package/dist/index.mjs +108624 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/parser/v1/generated/PineV1Lexer.d.ts +66 -0
- package/dist/types/parser/v1/generated/PineV1Parser.d.ts +555 -0
- package/dist/types/parser/v1/generated/PineV1ParserVisitor.d.ts +318 -0
- package/dist/types/parser/v1/index.d.ts +39 -0
- package/dist/types/parser/v2/generated/PineV2Lexer.d.ts +67 -0
- package/dist/types/parser/v2/generated/PineV2Parser.d.ts +568 -0
- package/dist/types/parser/v2/generated/PineV2ParserVisitor.d.ts +325 -0
- package/dist/types/parser/v2/index.d.ts +2 -0
- package/dist/types/parser/v3/generated/PineV3Lexer.d.ts +67 -0
- package/dist/types/parser/v3/generated/PineV3Parser.d.ts +568 -0
- package/dist/types/parser/v3/generated/PineV3ParserVisitor.d.ts +325 -0
- package/dist/types/parser/v3/index.d.ts +2 -0
- package/dist/types/parser/v4/generated/PineV4Lexer.d.ts +86 -0
- package/dist/types/parser/v4/generated/PineV4Parser.d.ts +673 -0
- package/dist/types/parser/v4/generated/PineV4ParserVisitor.d.ts +367 -0
- package/dist/types/parser/v4/index.d.ts +2 -0
- package/dist/types/parser/v5/generated/PineV5Lexer.d.ts +95 -0
- package/dist/types/parser/v5/generated/PineV5Parser.d.ts +964 -0
- package/dist/types/parser/v5/generated/PineV5ParserVisitor.d.ts +521 -0
- package/dist/types/parser/v5/index.d.ts +2 -0
- package/dist/types/parser/v6/generated/PineV6Lexer.d.ts +98 -0
- package/dist/types/parser/v6/generated/PineV6Parser.d.ts +984 -0
- package/dist/types/parser/v6/generated/PineV6ParserVisitor.d.ts +528 -0
- package/dist/types/parser/v6/index.d.ts +2 -0
- package/dist/types/runtime/v1/Series.d.ts +61 -0
- package/dist/types/runtime/v1/broker/Broker.d.ts +325 -0
- package/dist/types/runtime/v1/broker/index.d.ts +158 -0
- package/dist/types/runtime/v1/broker/val.d.ts +28 -0
- package/dist/types/runtime/v1/constDefault.d.ts +11 -0
- package/dist/types/runtime/v1/context.d.ts +1705 -0
- package/dist/types/runtime/v1/footprint.d.ts +32 -0
- package/dist/types/runtime/v1/index.d.ts +7 -0
- package/dist/types/runtime/v1/language-spec.d.ts +12 -0
- package/dist/types/runtime/v1/openTrades.d.ts +12 -0
- package/dist/types/runtime/v1/palette.d.ts +18 -0
- package/dist/types/runtime/v1/session.d.ts +482 -0
- package/dist/types/runtime/v1/sessions.d.ts +31 -0
- package/dist/types/runtime/v1/stateClone.d.ts +19 -0
- package/dist/types/runtime/v1/stdlib/alerts.d.ts +31 -0
- package/dist/types/runtime/v1/stdlib/arrays.d.ts +133 -0
- package/dist/types/runtime/v1/stdlib/barmerge.d.ts +27 -0
- package/dist/types/runtime/v1/stdlib/barstate.d.ts +79 -0
- package/dist/types/runtime/v1/stdlib/cast.d.ts +81 -0
- package/dist/types/runtime/v1/stdlib/chart.d.ts +283 -0
- package/dist/types/runtime/v1/stdlib/color.d.ts +51 -0
- package/dist/types/runtime/v1/stdlib/core.d.ts +162 -0
- package/dist/types/runtime/v1/stdlib/dataset.d.ts +36 -0
- package/dist/types/runtime/v1/stdlib/display.d.ts +50 -0
- package/dist/types/runtime/v1/stdlib/drawings.d.ts +407 -0
- package/dist/types/runtime/v1/stdlib/errors.d.ts +21 -0
- package/dist/types/runtime/v1/stdlib/font.d.ts +20 -0
- package/dist/types/runtime/v1/stdlib/footprint.d.ts +76 -0
- package/dist/types/runtime/v1/stdlib/format.d.ts +57 -0
- package/dist/types/runtime/v1/stdlib/index.d.ts +71 -0
- package/dist/types/runtime/v1/stdlib/input.d.ts +14 -0
- package/dist/types/runtime/v1/stdlib/inputs.d.ts +60 -0
- package/dist/types/runtime/v1/stdlib/late_members.d.ts +97 -0
- package/dist/types/runtime/v1/stdlib/logging.d.ts +31 -0
- package/dist/types/runtime/v1/stdlib/maps.d.ts +55 -0
- package/dist/types/runtime/v1/stdlib/math.d.ts +71 -0
- package/dist/types/runtime/v1/stdlib/matrix.d.ts +201 -0
- package/dist/types/runtime/v1/stdlib/metadata.d.ts +14 -0
- package/dist/types/runtime/v1/stdlib/mtf.d.ts +15 -0
- package/dist/types/runtime/v1/stdlib/renames.d.ts +117 -0
- package/dist/types/runtime/v1/stdlib/renames5.d.ts +113 -0
- package/dist/types/runtime/v1/stdlib/renames6.d.ts +81 -0
- package/dist/types/runtime/v1/stdlib/request.d.ts +207 -0
- package/dist/types/runtime/v1/stdlib/scale.d.ts +19 -0
- package/dist/types/runtime/v1/stdlib/session.d.ts +113 -0
- package/dist/types/runtime/v1/stdlib/sort_field.d.ts +12 -0
- package/dist/types/runtime/v1/stdlib/sources.d.ts +24 -0
- package/dist/types/runtime/v1/stdlib/str.d.ts +117 -0
- package/dist/types/runtime/v1/stdlib/strategy.d.ts +314 -0
- package/dist/types/runtime/v1/stdlib/syminfo.d.ts +209 -0
- package/dist/types/runtime/v1/stdlib/ta.d.ts +409 -0
- package/dist/types/runtime/v1/stdlib/time.d.ts +158 -0
- package/dist/types/runtime/v1/stdlib/trades.d.ts +108 -0
- package/dist/types/runtime/v1/stdlib/ui.d.ts +196 -0
- package/dist/types/runtime/v1/stdlib/v6_members.d.ts +68 -0
- package/dist/types/runtime/v1/timeframes.d.ts +139 -0
- package/dist/types/runtime/v1/zones.d.ts +30 -0
- package/dist/types/transpiler/common/index.d.ts +51 -0
- package/dist/types/transpiler/common/libraries.d.ts +29 -0
- package/dist/types/transpiler/common/parseErrors.d.ts +38 -0
- package/dist/types/transpiler/common/passes/ScopeAnalysis.d.ts +158 -0
- package/dist/types/transpiler/common/passes/TypeRules.d.ts +26 -0
- package/dist/types/transpiler/common/profiles/index.d.ts +96 -0
- package/dist/types/transpiler/common/version.d.ts +40 -0
- package/dist/types/transpiler/v1/ToJsVisitor.d.ts +720 -0
- package/dist/types/transpiler/v2/ToJsVisitor.d.ts +72 -0
- package/dist/types/transpiler/v3/ToJsVisitor.d.ts +87 -0
- package/dist/types/transpiler/v4/ToJsVisitor.d.ts +263 -0
- package/dist/types/transpiler/v5/ToJsVisitor.d.ts +1101 -0
- package/dist/types/transpiler/v6/ToJsVisitor.d.ts +237 -0
- package/dist/types/transpiler/v6/rules.d.ts +94 -0
- package/dist/types/utils/v2/common.d.ts +4 -0
- package/package.json +92 -4
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `font.*` — the two font families a label, box or table cell may ask for.
|
|
3
|
+
*
|
|
4
|
+
* Pine offers a choice of exactly two, and neither is a font NAME: they are
|
|
5
|
+
* requests for "the chart's usual typeface" and "something monospaced", which
|
|
6
|
+
* the platform resolves. This engine draws nothing, so it carries the constant
|
|
7
|
+
* through to the drawing record and no further.
|
|
8
|
+
*
|
|
9
|
+
* The values are the strings a renderer would want, so a host that does draw
|
|
10
|
+
* gets something usable rather than an opaque integer.
|
|
11
|
+
*
|
|
12
|
+
* v5-only: the registry split in ./index.ts keeps the namespace out of the
|
|
13
|
+
* v1–v4 views.
|
|
14
|
+
*/
|
|
15
|
+
export declare const font: {
|
|
16
|
+
/** The chart's default typeface. */
|
|
17
|
+
family_default: string;
|
|
18
|
+
/** A monospaced typeface — what a table of aligned numbers wants. */
|
|
19
|
+
family_monospace: string;
|
|
20
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `request.footprint()` and the `footprint` / `volume_row` types — v6,
|
|
3
|
+
* January 2026.
|
|
4
|
+
*
|
|
5
|
+
* Signature and semantics, from the user manual ("Other timeframes and data",
|
|
6
|
+
* request.footprint()):
|
|
7
|
+
*
|
|
8
|
+
* request.footprint(ticks_per_row, va_percent, imbalance_percent) → series footprint
|
|
9
|
+
*
|
|
10
|
+
* ticks_per_row "simple int": row size as a multiple of syminfo.mintick
|
|
11
|
+
* va_percent "simple float", default 70: share of total volume in the
|
|
12
|
+
* Value Area
|
|
13
|
+
* imbalance_percent "simple float", default 300: the buy/sell difference
|
|
14
|
+
* against an adjacent row that makes an imbalance
|
|
15
|
+
*
|
|
16
|
+
* "Returns a footprint ID, or na if no footprint is available for the bar."
|
|
17
|
+
* "Scripts can make only one request.footprint() call. Multiple calls cause a
|
|
18
|
+
* runtime error."
|
|
19
|
+
*
|
|
20
|
+
* ── Where the data comes from ──────────────────────────────────────────────
|
|
21
|
+
*
|
|
22
|
+
* Volume at price is not in an OHLCV bar, so the host supplies it, the way it
|
|
23
|
+
* supplies higher-timeframe candles: Context.provideFootprints, as volume per
|
|
24
|
+
* price LEVEL. This module groups levels into rows of `ticks_per_row` ticks and
|
|
25
|
+
* derives everything else — POC, Value Area, imbalances — from them.
|
|
26
|
+
*
|
|
27
|
+
* A script that requests footprints from a host that supplied none is refused,
|
|
28
|
+
* with the call that would fix it, which is the rule every other `request.*`
|
|
29
|
+
* here follows (./request.ts). A bar the host has no footprint for is `na`, as
|
|
30
|
+
* documented.
|
|
31
|
+
*
|
|
32
|
+
* ── Not documented, so chosen and stated ───────────────────────────────────
|
|
33
|
+
*
|
|
34
|
+
* Row bounds [k·size, (k+1)·size) — `down_price` is the row's floor and
|
|
35
|
+
* `up_price` its ceiling.
|
|
36
|
+
* POC tie the LOWER row, when two rows share the highest volume.
|
|
37
|
+
* Value Area grown one row at a time from the POC, taking whichever
|
|
38
|
+
* neighbour has more volume (the upper on a tie), until it
|
|
39
|
+
* holds `va_percent` of the bar's volume.
|
|
40
|
+
* Imbalance "exceeds ... by the given percentage" is read as a RATIO:
|
|
41
|
+
* 300 means at least three times the other row's volume, and
|
|
42
|
+
* a row with no volume on the relevant side is no imbalance.
|
|
43
|
+
*
|
|
44
|
+
* These want a TradingView-captured fixture before they are trusted for
|
|
45
|
+
* numbers.
|
|
46
|
+
*/
|
|
47
|
+
import { Context } from "../context.js";
|
|
48
|
+
import { type Row } from "../footprint.js";
|
|
49
|
+
export declare const request: {
|
|
50
|
+
/** See the header for the signature and for what is documented. */
|
|
51
|
+
footprint: (ctx: Context, ticks_per_row: any, va_percent?: any, imbalance_percent?: any) => any;
|
|
52
|
+
};
|
|
53
|
+
export declare const footprint: {
|
|
54
|
+
total_volume: (id: any) => number;
|
|
55
|
+
buy_volume: (id: any) => number;
|
|
56
|
+
sell_volume: (id: any) => number;
|
|
57
|
+
delta: (id: any) => number;
|
|
58
|
+
/** The row with the highest total volume — the Point of Control. */
|
|
59
|
+
poc: (id: any) => Row;
|
|
60
|
+
/** The Value Area High row. */
|
|
61
|
+
vah: (id: any) => Row;
|
|
62
|
+
/** The Value Area Low row. */
|
|
63
|
+
val: (id: any) => Row;
|
|
64
|
+
/** "Every row, sorted by ascending price." A copy, so a script cannot reorder the footprint. */
|
|
65
|
+
rows: (id: any) => Row[];
|
|
66
|
+
};
|
|
67
|
+
export declare const volume_row: {
|
|
68
|
+
up_price: (id: any) => number;
|
|
69
|
+
down_price: (id: any) => number;
|
|
70
|
+
buy_volume: (id: any) => number;
|
|
71
|
+
sell_volume: (id: any) => number;
|
|
72
|
+
total_volume: (id: any) => number;
|
|
73
|
+
delta: (id: any) => number;
|
|
74
|
+
has_buy_imbalance: (id: any) => boolean;
|
|
75
|
+
has_sell_imbalance: (id: any) => boolean;
|
|
76
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `format.*` — how a script's numbers are rendered.
|
|
3
|
+
*
|
|
4
|
+
* Two unrelated jobs share the namespace, which is why the values below are
|
|
5
|
+
* sentinels rather than anything computable:
|
|
6
|
+
*
|
|
7
|
+
* 1. `indicator(..., format = format.price, precision = 2)` — the price-axis
|
|
8
|
+
* and Data Window rendering of every plot the script makes.
|
|
9
|
+
*
|
|
10
|
+
* "The format parameter defines the type of formatting used for study
|
|
11
|
+
* values appearing on the price axis, in indicator values or in the Data
|
|
12
|
+
* Window, with possible values being: format.inherit, format.price and
|
|
13
|
+
* format.volume."
|
|
14
|
+
*
|
|
15
|
+
* "When format.price is used, the default precision will be '2', unless
|
|
16
|
+
* one is specified using precision=."
|
|
17
|
+
*
|
|
18
|
+
* "When format.volume is used, the format is equivalent to precision=0
|
|
19
|
+
* used in earlier versions of Pine, where '5183' becomes '5.183K'."
|
|
20
|
+
*
|
|
21
|
+
* 2. `str.tostring(value, format.mintick)` — round to tick precision, then
|
|
22
|
+
* stringify.
|
|
23
|
+
*
|
|
24
|
+
* "use str.tostring(myValue, format.mintick) to first round the number to
|
|
25
|
+
* tick precision and then return its string representation."
|
|
26
|
+
*
|
|
27
|
+
* ── Why the values are these strings ────────────────────────────────────────
|
|
28
|
+
*
|
|
29
|
+
* `str.tostring`'s second argument is EITHER one of these constants or a Pine
|
|
30
|
+
* number-format string like "#.##". The two have to be told apart at runtime,
|
|
31
|
+
* and a sentinel that reads back as its own name is the cheapest way to do it
|
|
32
|
+
* that also survives being printed: a script that puts `format.price` somewhere
|
|
33
|
+
* it does not belong sees `"format.price"` rather than `0` or `undefined`.
|
|
34
|
+
*
|
|
35
|
+
* Job (1) does not affect any number this engine computes. There is no price
|
|
36
|
+
* axis and no Data Window, so the constant is carried and ignored — the plot
|
|
37
|
+
* values are the same either way. That is a real difference from TradingView in
|
|
38
|
+
* what a user SEES, and none at all in what the script calculates.
|
|
39
|
+
*
|
|
40
|
+
* v5-only: the registry split in ./index.ts keeps the namespace out of the
|
|
41
|
+
* v1–v4 views. (v4 has a `format` argument on `study()` too, but spells its
|
|
42
|
+
* constants without the namespace.)
|
|
43
|
+
*/
|
|
44
|
+
/** The prefix every `format.*` sentinel carries, so they can be recognised. */
|
|
45
|
+
export declare const FORMAT_PREFIX = "format.";
|
|
46
|
+
export declare const format: {
|
|
47
|
+
/** Inherit the chart's own price formatting. The default. */
|
|
48
|
+
inherit: string;
|
|
49
|
+
/** Round to the instrument's tick size — `str.tostring`'s one live use. */
|
|
50
|
+
mintick: string;
|
|
51
|
+
/** Render as a percentage. */
|
|
52
|
+
percent: string;
|
|
53
|
+
/** Price formatting; implies `precision = 2` unless one is given. */
|
|
54
|
+
price: string;
|
|
55
|
+
/** Volume formatting: 5183 renders as "5.183K". */
|
|
56
|
+
volume: string;
|
|
57
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Context } from "../context.js";
|
|
2
|
+
import { StdlibEntry } from "./metadata.js";
|
|
3
|
+
/**
|
|
4
|
+
* The v1–v3 stdlib: everything generated, minus the namespaces that do not
|
|
5
|
+
* exist yet.
|
|
6
|
+
*
|
|
7
|
+
* The subtraction is what keeps `array.new_float`, `label.new` and `str.length`
|
|
8
|
+
* from resolving at v1 — they live in the ordinary stdlib source files, because
|
|
9
|
+
* the runtime is one implementation across versions, so nothing else would stop
|
|
10
|
+
* them.
|
|
11
|
+
*/
|
|
12
|
+
export declare const BASE_REGISTRY: Record<string, StdlibEntry>;
|
|
13
|
+
/** The v4-only names, kept aside so v4's view can add them back. */
|
|
14
|
+
export declare const V4_NAMESPACE_REGISTRY: Record<string, StdlibEntry>;
|
|
15
|
+
/** The v5-only names, kept aside so v5's view can add them back. */
|
|
16
|
+
export declare const V5_NAMESPACE_REGISTRY: Record<string, StdlibEntry>;
|
|
17
|
+
export declare const V4_REGISTRY: Record<string, StdlibEntry>;
|
|
18
|
+
export declare const V4_VIEW: Record<string, StdlibEntry>;
|
|
19
|
+
export declare const V5_REGISTRY: Record<string, StdlibEntry>;
|
|
20
|
+
/** What a v5 script may spell. */
|
|
21
|
+
export declare const V5_VIEW: Record<string, StdlibEntry>;
|
|
22
|
+
/**
|
|
23
|
+
* The v6-only names, kept out of every earlier view and added back here.
|
|
24
|
+
*
|
|
25
|
+
* Built from GENERATED rather than from a literal, so a name on the v6 list
|
|
26
|
+
* that nothing implements yet is simply absent — rather than a registry entry
|
|
27
|
+
* pointing at nothing, which would compile and then fail at run time.
|
|
28
|
+
*/
|
|
29
|
+
export declare const V6_REGISTRY: Record<string, StdlibEntry>;
|
|
30
|
+
/**
|
|
31
|
+
* What a v6 script may spell.
|
|
32
|
+
*
|
|
33
|
+
* v6 is the first version since v3 that renames nothing. Its registry delta is
|
|
34
|
+
* entirely SUBTRACTIVE plus a handful of new members, so this view is built
|
|
35
|
+
* the same way V5_VIEW is — remove, then add — with an empty rename table.
|
|
36
|
+
*
|
|
37
|
+
* The removals are the migration guide's: `transp` off the six plotting
|
|
38
|
+
* functions, `when` off the seven strategy functions. Those are PARAMETERS
|
|
39
|
+
* rather than registry keys, so they are enforced by the emitter, which can
|
|
40
|
+
* name the line; see transpiler/v6/ToJsVisitor.ts. Nothing v5 could spell as a
|
|
41
|
+
* NAME was taken away, which is why V6_REMOVED is empty rather than absent —
|
|
42
|
+
* an empty list that is spread is a statement that the question was asked.
|
|
43
|
+
*/
|
|
44
|
+
export declare const V6_VIEW: Record<string, StdlibEntry>;
|
|
45
|
+
/**
|
|
46
|
+
* Every name the RUNTIME can resolve, at any version.
|
|
47
|
+
*
|
|
48
|
+
* Deliberately the union. The runtime is shared across versions by design
|
|
49
|
+
* (docs/common/ARCHITECTURE.md ("Design rules")) and is not the gatekeeper — the
|
|
50
|
+
* transpiler decides what a given version may spell and refuses to emit
|
|
51
|
+
* anything else. A union here just means the sandbox can execute whatever the
|
|
52
|
+
* transpiler let through.
|
|
53
|
+
*
|
|
54
|
+
* ORDER MATTERS for the one key that means different things at different
|
|
55
|
+
* versions: `input.float` is a constant at v4 and a function at v5, and one
|
|
56
|
+
* sandbox holds one object per name. V5_NAMESPACE_REGISTRY comes after
|
|
57
|
+
* V4_REGISTRY so the FUNCTION wins, and ./inputs.ts gives that function a
|
|
58
|
+
* `valueOf` returning the v4 constant so both readings survive.
|
|
59
|
+
*/
|
|
60
|
+
export declare const REGISTRY: Record<string, StdlibEntry>;
|
|
61
|
+
/**
|
|
62
|
+
* The view a given version writes against.
|
|
63
|
+
*
|
|
64
|
+
* Used by `createStdlib` to settle the handful of keys that MEAN different
|
|
65
|
+
* things at different versions. It is not a gatekeeper — the transpiler decides
|
|
66
|
+
* what a version may spell, and this function is never consulted about whether
|
|
67
|
+
* a name is allowed, only about which of two meanings a name has.
|
|
68
|
+
*/
|
|
69
|
+
export declare function viewFor(version: number): Record<string, StdlibEntry>;
|
|
70
|
+
export declare function createStdlib(ctx: Context): Record<string, any>;
|
|
71
|
+
export { UNIMPLEMENTED_BUILTINS } from "./renames.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context } from "../context.js";
|
|
2
|
+
/**
|
|
3
|
+
* Pine Script input() function
|
|
4
|
+
* @returns series float (or int/bool depending on type)
|
|
5
|
+
*/
|
|
6
|
+
export declare function input(ctx: Context, defval: any, title?: any, type?: any, minval?: any, maxval?: any, confirm?: any, step?: any, options?: any, tooltip?: any, inline?: any, group?: any, display?: any, active?: any): any;
|
|
7
|
+
export declare const integer = "integer";
|
|
8
|
+
export declare const float = "float";
|
|
9
|
+
export declare const bool = "bool";
|
|
10
|
+
export declare const string = "string";
|
|
11
|
+
export declare const source = "source";
|
|
12
|
+
export declare const resolution = "resolution";
|
|
13
|
+
export declare const session = "session";
|
|
14
|
+
export declare const symbol = "symbol";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v5's TYPED input functions — `input.int()`, `input.float()`, `input.bool()`, …
|
|
3
|
+
*
|
|
4
|
+
* ── What changed at v5 ──────────────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* v1–v3 pass the type as a value: `input(14, type=integer)`.
|
|
7
|
+
* v4 moves those values into a namespace: `input(14, type=input.integer)`.
|
|
8
|
+
* v5 removes them as values and makes them FUNCTIONS: `input.int(14)`.
|
|
9
|
+
*
|
|
10
|
+
* Two of them also change name in the process — `integer` becomes `int` and
|
|
11
|
+
* `resolution` becomes `timeframe` (docs/common/VERSIONS.md §4c).
|
|
12
|
+
*
|
|
13
|
+
* ── Six of these names collide with v4's constants ──────────────────────────
|
|
14
|
+
*
|
|
15
|
+
* `float`, `bool`, `string`, `source`, `session` and `symbol` are live at BOTH
|
|
16
|
+
* v4 (as constants, holding the type name) and v5 (as the functions below), and
|
|
17
|
+
* the sandbox holds ONE object per name. Nothing in this file resolves that:
|
|
18
|
+
* `createStdlib` in ./index.ts binds each version's own meaning, reading the
|
|
19
|
+
* version off the Context.
|
|
20
|
+
*
|
|
21
|
+
* The alternative — one object that is callable AND stringifies to the v4
|
|
22
|
+
* constant — was tried and abandoned. It works for `input(1.0,
|
|
23
|
+
* type=input.float)`, which unwraps its argument, and leaks everywhere else:
|
|
24
|
+
* `x = input.float` at v4 binds a function that merely LOOKS like "float" to
|
|
25
|
+
* anything that asks it politely.
|
|
26
|
+
*
|
|
27
|
+
* `int`, `timeframe`, `color`, `time`, `price` and `text_area` have no v4
|
|
28
|
+
* constant of the same spelling, so they collide with nothing.
|
|
29
|
+
*/
|
|
30
|
+
import { Context } from "../context.js";
|
|
31
|
+
export declare const input: {
|
|
32
|
+
int: (ctx: Context, defval: any, title?: any, minval?: any, maxval?: any, step?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, options?: any, active?: any) => any;
|
|
33
|
+
float: (ctx: Context, defval: any, title?: any, minval?: any, maxval?: any, step?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, options?: any, active?: any) => any;
|
|
34
|
+
bool: (ctx: Context, defval: any, title?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
35
|
+
string: (ctx: Context, defval: any, title?: any, options?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
36
|
+
color: (ctx: Context, defval: any, title?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
37
|
+
/** v5's rename of v4's `input.resolution`. */
|
|
38
|
+
timeframe: (ctx: Context, defval: any, title?: any, options?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
39
|
+
session: (ctx: Context, defval: any, title?: any, options?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
40
|
+
symbol: (ctx: Context, defval: any, title?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
41
|
+
/** The chart series an indicator runs on — `close`, `hl2`, another plot. */
|
|
42
|
+
source: (ctx: Context, defval: any, title?: any, tooltip?: any, inline?: any, group?: any, display?: any, active?: any) => any;
|
|
43
|
+
time: (ctx: Context, defval: any, title?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
44
|
+
price: (ctx: Context, defval: any, title?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
45
|
+
text_area: (ctx: Context, defval: any, title?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
46
|
+
/**
|
|
47
|
+
* `input.enum(defaultValue, title, options, …)` — a dropdown of enum members.
|
|
48
|
+
*
|
|
49
|
+
* June 2024, with enums themselves: they "enable convenient dropdown input
|
|
50
|
+
* creation with the new input.enum() function", and "the input displays all
|
|
51
|
+
* enum field titles in its dropdown menu".
|
|
52
|
+
*
|
|
53
|
+
* The declared type is `enum` rather than `string` so a host rendering the
|
|
54
|
+
* inputs can list the right choices: `Context.enumMembers` holds every
|
|
55
|
+
* member of the enum the default belongs to, and `Context.enumTitles` turns
|
|
56
|
+
* each into the text the dropdown should show. A plain `string` input would
|
|
57
|
+
* offer a free-text box for a value that must be one of a fixed set.
|
|
58
|
+
*/
|
|
59
|
+
enum: (ctx: Context, defval: any, title?: any, options?: any, tooltip?: any, inline?: any, group?: any, confirm?: any, display?: any, active?: any) => any;
|
|
60
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Members whose NAMESPACE is older than they are.
|
|
3
|
+
*
|
|
4
|
+
* Most of `math.*`, `ta.*` and `ticker.*` is not written anywhere in that form.
|
|
5
|
+
* It is the v1–v4 FLAT names — `abs`, `sma`, `heikinashi` — which the v5 rename
|
|
6
|
+
* table moves under a namespace, so `math.ts`, `ta.ts` and `chart.ts` export
|
|
7
|
+
* flat functions and must keep doing so.
|
|
8
|
+
*
|
|
9
|
+
* The members below have no flat ancestor, and each one COLLIDES with a flat
|
|
10
|
+
* name that does:
|
|
11
|
+
*
|
|
12
|
+
* math.pi `math.ts` is the module named math; an object literal in it
|
|
13
|
+
* could not also be called `math`
|
|
14
|
+
* ta.max/min flat `max` and `min` are already taken — they are what become
|
|
15
|
+
* `math.max` and `math.min`
|
|
16
|
+
* ticker.modify flat `ticker` is already taken — it is the v1–v3 symbol name,
|
|
17
|
+
* a FUNCTION, and TypeScript will not let one name be both
|
|
18
|
+
*
|
|
19
|
+
* So they are declared here as object literals, which the registry generator
|
|
20
|
+
* turns straight into dotted keys, and `createStdlib` merges onto the flat
|
|
21
|
+
* function of the same name where there is one. Gated to v5 with the rest of
|
|
22
|
+
* their namespaces by V5_ONLY_NAMESPACES.
|
|
23
|
+
*/
|
|
24
|
+
import { Context } from "../context.js";
|
|
25
|
+
/** @returns {const float} */
|
|
26
|
+
export declare const math: {
|
|
27
|
+
/** The ratio of a circle's circumference to its diameter. */
|
|
28
|
+
pi: number;
|
|
29
|
+
/** Euler's number, the base of the natural logarithm. */
|
|
30
|
+
e: number;
|
|
31
|
+
/**
|
|
32
|
+
* The golden ratio, (1 + √5) / 2.
|
|
33
|
+
*
|
|
34
|
+
* Written out rather than hard-coded to its decimal expansion so it carries
|
|
35
|
+
* every bit of double precision — a Fibonacci retracement level computed from
|
|
36
|
+
* a truncated constant drifts from TradingView's by the last digits, which is
|
|
37
|
+
* exactly the kind of divergence this engine exists to avoid.
|
|
38
|
+
*/
|
|
39
|
+
phi: number;
|
|
40
|
+
/** The RECIPROCAL golden ratio, (√5 − 1) / 2 — `math.phi` minus one. */
|
|
41
|
+
rphi: number;
|
|
42
|
+
};
|
|
43
|
+
export declare const ta: {
|
|
44
|
+
/**
|
|
45
|
+
* The highest value `source` has held since the script began.
|
|
46
|
+
*
|
|
47
|
+
* `na` is SKIPPED rather than compared. A single absent bar would otherwise
|
|
48
|
+
* poison the record permanently — `NaN > x` is false and `x > NaN` is false,
|
|
49
|
+
* so the comparison never recovers — which is the same rule `ta.cum` follows
|
|
50
|
+
* and for the same reason.
|
|
51
|
+
*
|
|
52
|
+
* Undefined before the first finite value, which is `na`: a series that has
|
|
53
|
+
* never had a value has no maximum, and answering 0 would put a floor on
|
|
54
|
+
* every chart that plots it.
|
|
55
|
+
*
|
|
56
|
+
* @returns {series float} The all-time high, or na.
|
|
57
|
+
*/
|
|
58
|
+
max: (ctx: Context, source: any) => number;
|
|
59
|
+
/**
|
|
60
|
+
* The lowest value `source` has held since the script began.
|
|
61
|
+
* @returns {series float} The all-time low, or na.
|
|
62
|
+
*/
|
|
63
|
+
min: (ctx: Context, source: any) => number;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* `ticker.modify(tickerid, session, adjustment, …)` — August 2024.
|
|
67
|
+
*
|
|
68
|
+
* Rebuilds a ticker id with different session or adjustment settings, leaving
|
|
69
|
+
* the symbol alone: `ticker.modify(syminfo.tickerid, session.extended)` is the
|
|
70
|
+
* standard way to ask for extended hours without hard-coding the symbol.
|
|
71
|
+
*
|
|
72
|
+
* The result is a MARKED symbol string, exactly as `heikinashi()` returns one —
|
|
73
|
+
* `Context.getSecurityData` reads the marker when the candles are fetched, so
|
|
74
|
+
* the whole request pipeline is reused rather than duplicated. A host that
|
|
75
|
+
* ignores the marker gets regular-session data, which is what it has.
|
|
76
|
+
*/
|
|
77
|
+
export declare const ticker: {
|
|
78
|
+
/**
|
|
79
|
+
* `ticker.standard(symbol)` — the ticker id with any non-standard chart
|
|
80
|
+
* type removed ("heikinashi:", "renko:" …), so a request reads ordinary
|
|
81
|
+
* candles. A plain id is returned as it is.
|
|
82
|
+
*/
|
|
83
|
+
standard: (symbol?: any) => string;
|
|
84
|
+
/**
|
|
85
|
+
* `ticker.inherit(tickerid, from_tickerid)` — take another symbol's settings.
|
|
86
|
+
*
|
|
87
|
+
* Builds a ticker id for `tickerid` carrying whatever session, adjustment and
|
|
88
|
+
* chart-type modifiers `from_tickerid` was built with. The point is that the
|
|
89
|
+
* two requests then agree: comparing a symbol against an index is only
|
|
90
|
+
* meaningful if both are asked for on the same terms.
|
|
91
|
+
*
|
|
92
|
+
* The modifiers are the query string `ticker.modify` writes, so inheriting
|
|
93
|
+
* them is copying that half of the id onto a different symbol.
|
|
94
|
+
*/
|
|
95
|
+
inherit: (tickerid: any, from_tickerid: any) => string;
|
|
96
|
+
modify: (tickerid: any, session?: any, adjustment?: any, ..._rest: any[]) => string;
|
|
97
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pine Logs — the `log.*` namespace. v5 only.
|
|
3
|
+
*
|
|
4
|
+
* ── Why this matters more than it looks ─────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* `log.info()` is how this project collects golden data from TradingView
|
|
7
|
+
* without a PRO+ subscription. "Export chart data…" is a paid feature; Pine
|
|
8
|
+
* Logs are not, they run on HISTORICAL bars (unlike `alert()`, which only ever
|
|
9
|
+
* fires on realtime bars), and they retain the last 10,000 messages. Every
|
|
10
|
+
* harness in conformance/v5/golden ends by writing one CSV row per bar through
|
|
11
|
+
* `log.info`, and scripts/common/make-log-harness.ts generates them.
|
|
12
|
+
*
|
|
13
|
+
* So the engine must be able to RUN those harnesses, not merely compile them —
|
|
14
|
+
* otherwise the one artefact that proves the harness itself is well-formed
|
|
15
|
+
* cannot be produced locally before it is pasted into TradingView.
|
|
16
|
+
*
|
|
17
|
+
* ── The flat `log` collision ────────────────────────────────────────────────
|
|
18
|
+
*
|
|
19
|
+
* v1–v4 spell the natural logarithm as the bare function `log(x)`; v5 renames
|
|
20
|
+
* it to `math.log` and gives the word to this namespace. Both spellings exist
|
|
21
|
+
* in the RUNTIME registry at once, deliberately — the runtime is one
|
|
22
|
+
* implementation across versions, and the transpiler decides which spelling
|
|
23
|
+
* each version may write. `createStdlib` in ./index.ts merges a namespace onto
|
|
24
|
+
* a callable of the same name, which is what makes the two coexist.
|
|
25
|
+
*/
|
|
26
|
+
import { Context } from "../context.js";
|
|
27
|
+
export declare const log: {
|
|
28
|
+
info: (ctx: Context, message: any, ...args: any[]) => void;
|
|
29
|
+
warning: (ctx: Context, message: any, ...args: any[]) => void;
|
|
30
|
+
error: (ctx: Context, message: any, ...args: any[]) => void;
|
|
31
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pine Script maps — the `map.*` namespace. v5, August 2023.
|
|
3
|
+
*
|
|
4
|
+
* ── Representation ──────────────────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* A JavaScript `Map`, unwrapped. Same reasoning as arrays (see ./arrays.ts): a
|
|
7
|
+
* wrapper class would buy a type tag this engine does not model anywhere else,
|
|
8
|
+
* and cost interop with every iteration in the runtime.
|
|
9
|
+
*
|
|
10
|
+
* Keys are STORED UNWRAPPED. A Pine map key is a scalar, but the emitter hands
|
|
11
|
+
* the runtime a Series wherever the key came from a variable, and `Map` keys
|
|
12
|
+
* compare by identity — so putting `Series(3)` and later looking up `3` would
|
|
13
|
+
* miss, and worse, two writes of the same logical key would both be kept. Every
|
|
14
|
+
* entry point below therefore passes its key through `val` first.
|
|
15
|
+
*
|
|
16
|
+
* ── Insertion order is the documented order ─────────────────────────────────
|
|
17
|
+
*
|
|
18
|
+
* `map.keys()` and `map.values()` return arrays, and Pine specifies them as
|
|
19
|
+
* being in insertion order. `Map` iterates in insertion order, so nothing here
|
|
20
|
+
* has to sort — but a re-`put` of an existing key must not move it to the end,
|
|
21
|
+
* which is `Map.set`'s behaviour for an existing key and is why `put` does not
|
|
22
|
+
* delete-then-set.
|
|
23
|
+
*
|
|
24
|
+
* v5-only, which this file does not enforce: the registry split in ./index.ts
|
|
25
|
+
* keeps the namespace out of the v1–v4 views.
|
|
26
|
+
*/
|
|
27
|
+
export declare const map: {
|
|
28
|
+
/**
|
|
29
|
+
* `map.new<keyType, valueType>()`.
|
|
30
|
+
*
|
|
31
|
+
* The type arguments are parsed by the grammar and discarded by the
|
|
32
|
+
* emitter: this engine does not track element types anywhere, and a
|
|
33
|
+
* constructor that pretended to would be checking nothing.
|
|
34
|
+
*/
|
|
35
|
+
new: () => Map<any, any>;
|
|
36
|
+
/** Pine returns `na` for a missing key rather than raising. */
|
|
37
|
+
get: (id: any, k: any) => any;
|
|
38
|
+
contains: (id: any, k: any) => boolean;
|
|
39
|
+
size: (id: any) => number;
|
|
40
|
+
/**
|
|
41
|
+
* `map.put(id, key, value)` — returns the PREVIOUS value, or na.
|
|
42
|
+
*
|
|
43
|
+
* The return value is not decoration: `map.put` is how a script detects a
|
|
44
|
+
* first write, and dropping it would make that idiom silently impossible.
|
|
45
|
+
*/
|
|
46
|
+
put: (id: any, k: any, value: any) => any;
|
|
47
|
+
put_all: (id: any, id2: any) => void;
|
|
48
|
+
/** Returns the removed value, or na when the key was absent. */
|
|
49
|
+
remove: (id: any, k: any) => any;
|
|
50
|
+
clear: (id: any) => void;
|
|
51
|
+
keys: (id: any) => any[];
|
|
52
|
+
values: (id: any) => any[];
|
|
53
|
+
/** A shallow copy — the entries are shared, the map is not. */
|
|
54
|
+
copy: (id: any) => Map<any, any>;
|
|
55
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four maths built-ins TradingView added in Pine v4.
|
|
3
|
+
*
|
|
4
|
+
* ── Why they are FLAT functions here and not a `math` object ────────────────
|
|
5
|
+
*
|
|
6
|
+
* They were gated as v5-only, with a note claiming they had "no v1–v4 spelling
|
|
7
|
+
* to inherit from". That was wrong, and TradingView's own v4 release notes say
|
|
8
|
+
* so:
|
|
9
|
+
*
|
|
10
|
+
* "todegrees(radians) - returns an approximately equivalent angle in degrees
|
|
11
|
+
* from an angle measured in radians. toradians(degrees) - … random(min, max,
|
|
12
|
+
* seed) - returns a pseudo-random value. … Using the same value for the
|
|
13
|
+
* optional seed argument will produce a repeatable sequence."
|
|
14
|
+
*
|
|
15
|
+
* "New function was added: round_to_mintick(x) - returns the value rounded to
|
|
16
|
+
* the symbol's mintick …"
|
|
17
|
+
*
|
|
18
|
+
* All four are v4 built-ins that v5 moved under `math.` along with the rest of
|
|
19
|
+
* the maths library. So they belong here as flat names, gated to v4+ by
|
|
20
|
+
* V4_ONLY_NAMES, and aliased to `math.*` at v5 by V5_RENAMES — exactly the
|
|
21
|
+
* treatment `abs`, `sqrt` and `max` get. Declaring them as an object gave them
|
|
22
|
+
* `math.` keys directly, which made them unspellable at v4 (a v4 script calling
|
|
23
|
+
* `random(0, 255)` — as TradingView's own v4 documentation does — died with a
|
|
24
|
+
* ReferenceError) and left the flat v5 spelling un-removed.
|
|
25
|
+
*
|
|
26
|
+
* Source: https://www.tradingview.com/pine-script-docs/v4/release-notes/
|
|
27
|
+
*/
|
|
28
|
+
import { Context } from "../context.js";
|
|
29
|
+
/**
|
|
30
|
+
* `random(min, max, seed)` — uniform in [min, max).
|
|
31
|
+
*
|
|
32
|
+
* ── What `seed` does here, and what it does not ─────────────────────────────
|
|
33
|
+
*
|
|
34
|
+
* Pine documents `seed` as making the sequence REPEATABLE, and that is what it
|
|
35
|
+
* does here: a seeded call draws from a deterministic generator held on the
|
|
36
|
+
* Context, so two runs of the same script over the same bars produce the same
|
|
37
|
+
* numbers. That is the property a backtest needs.
|
|
38
|
+
*
|
|
39
|
+
* It is NOT the same sequence TradingView produces. Their generator is not
|
|
40
|
+
* published, so no local implementation can match it, and a seeded script will
|
|
41
|
+
* disagree with the chart value by value. Stated rather than hidden: the
|
|
42
|
+
* alternative — ignoring the seed — loses reproducibility as well as parity,
|
|
43
|
+
* which is strictly worse.
|
|
44
|
+
*
|
|
45
|
+
* Unseeded, it is `Math.random`, which is what an unseeded Pine call is.
|
|
46
|
+
*
|
|
47
|
+
* @returns {series float} A pseudo-random value in [min, max).
|
|
48
|
+
*/
|
|
49
|
+
export declare function random(ctx: Context, min?: any, max?: any, seed?: any): number;
|
|
50
|
+
/**
|
|
51
|
+
* Converts an angle measured in radians to an approximately equivalent angle
|
|
52
|
+
* measured in degrees.
|
|
53
|
+
* @returns {series float} The angle in degrees.
|
|
54
|
+
*/
|
|
55
|
+
export declare function todegrees(radians: any): number;
|
|
56
|
+
/**
|
|
57
|
+
* Converts an angle measured in degrees to an approximately equivalent angle
|
|
58
|
+
* measured in radians.
|
|
59
|
+
* @returns {series float} The angle in radians.
|
|
60
|
+
*/
|
|
61
|
+
export declare function toradians(degrees: any): number;
|
|
62
|
+
/**
|
|
63
|
+
* `round_to_mintick(x)` — round to the instrument's tick size.
|
|
64
|
+
*
|
|
65
|
+
* The tick comes from the Context rather than a constant: it is a property of
|
|
66
|
+
* the symbol being charted, and a script that draws a level at a price the
|
|
67
|
+
* exchange cannot quote is the thing this function exists to prevent.
|
|
68
|
+
*
|
|
69
|
+
* @returns {series float} `x` rounded to the nearest multiple of the mintick.
|
|
70
|
+
*/
|
|
71
|
+
export declare function round_to_mintick(ctx: Context, number: any): number;
|