Releases

Release Notes

kScript release history: features, fixes, and breaking changes, listed newest first with anchor links into full entries.

All notable changes to kScript are recorded here. Releases are sorted with the latest first.

Latest release

v3.0.67: Foreign-domain panes, perps backtesting, tape sources

July 2026 · Engine @orangecharts/kscript 3.0.67 (rolls up the 3.0.62–3.0.66 interim releases into the current build; each bullet notes the version that introduced it). Scripts can now emit foreign-domain panes: plotMatrix() (categorical grid), plotCurve() (numeric-X function pane), and plotTiles() (KPI card dashboard) render whole offchart panes whose X domain is pane-private instead of the shared time axis, including computed text tiles, valueFormat, hideLegendValues, and caps enforced as named errors. The strategy engine gains perps mode (instrument="perps": leveraged sizing on isolated margin, maker/taker fees, funding, a liquidation model with onLiquidation, and a set of new stats). Two array-celled tape sources (trades, trade_volume_by_size) bring real order-flow reading to scripts, plotHistogram() draws baseline-grown columns, array.sort() accepts a comparator, and the malformed-import error finally speaks human.

Added

  • Foreign-domain panes: plotMatrix / plotCurve / plotTiles (3.0.67). Three builtins that emit whole offchart PANES exempt from time pan/zoom and the crosshair. Ground rules, enforced at compile time with named errors: the script's define must be position: "offchart" (plotMatrix requires define(position="offchart") ...), a script can emit only one foreign pane (Only one foreign-domain pane output per script ...), and the builtin is called once with the finished dataset from an isLastBar block (accumulate per-bar state in static arrays first).
    • plotMatrix(data, rowLabels, colLabels, format?, summary?, highlight?, gridHeight?): categorical grid of [rowIdx, colIdx, value] cells. format="percent" renders 0.047 as +4.7%; up to 5 pinned summary rows sit under the grid (an na summary value renders blank); highlight emphasizes a row and/or column.
    • plotCurve(data, series?, style?, color?, fill?, markers?, valueFormat?, gridHeight?): numeric-X pane of [x, v1, ...vn] rows, up to 6 series. na series values are gaps, not zeros; rows must be strictly ascending in x (unsorted or duplicate x is a validation error). Vertical markers accept the literal x: 'spot', which tracks the main series' last close live. valueFormat ("number" | "currency" | "percent" | "compact") formats the Y axis and the hover card from one formatter, so they can never disagree.
    • plotTiles(tiles, data, texts?, columns?, gridHeight?): KPI cards. Card structure (labels, captions, formats, accents) is settings; card values arrive as [tileIndex, value] data rows. Computed text tiles (wire v1.2): texts = [{ tile, text }] sets a format: "text" tile's displayed string at run time, with the static text setting as the fallback; a texts entry targeting a non-text tile is an error. accent: "auto" colors by value sign; an na value drops the row and the tile renders as awaiting data.
    • hideLegendValues (boolean) is accepted by all three builtins. Caps are validated at the source as named errors, never silent truncation, for example: plotMatrix.rowLabels must have at most 64 entries, got 65, plotCurve supports at most 6 series, data[0] carries 7, plotTiles.tiles must have at most 24 entries, got 25, plotMatrix.data has duplicate cell (0, 0).
  • Perps strategy mode (3.0.63). strategy(...) accepts instrument="spot" | "perps" plus leverage (> 0), maintenanceMarginPercent, makerFeePercent, takerFeePercent, funding="data" | "off", and onLiquidation="continue" | "halt"; all are echoed in output.strategy.declared. With instrument="perps": every accepted entry commits isolated margin (notional / leverage), fees route maker/taker per fill, funding="data" consumes host-supplied settlement events (bars where a position is open but no funding data is available are counted in stats.fundingUnavailableCount instead of silently zeroed; funding="off" is an exact no-op), and an implicit liquidation exit closes the position when adverse movement erodes the committed margin (trade exitReason: "liquidation"). onLiquidation="halt" latches after the first liquidation and rejects every later entry. New stats: makerFeesPaid, takerFeesPaid, fundingPaid, fundingEventsApplied, fundingUnavailableCount, liquidationCount, liquidationHalted, bankruptcyDeficit, plus two perps-only bar-aligned series in output.strategy: committedMarginSeries and fundingPaidSeries. Invalid declarations fail loudly (strategy(): 'leverage' must be a number literal > 0). See Strategies.
  • Tape sources: trade_volume_by_size and trades (3.0.66). Two array-celled source types for tape reading. trade_volume_by_size(symbol, exchange) delivers cells [bucketId, buyVolUsd, sellVolUsd, buyCount, sellCount] over fixed USD order-size bands (bucket ids 1..7), so whale CVD comes from real order sizes instead of candle-geometry proxies. trades(symbol, exchange, minSize?) delivers each chart bar's individual trades as cells [offsetMs, price, size, side] with side +1 (buy) or -1 (sell); it is engine-complete but platform serving of wide raw-tape windows on liquid markets is still being rolled out, so the documented path today is the bucket source. Rows are dense: a quiet bar simply has zero cells. Both types count as 2 sources against the per-script source budget (the budget error spells it out: trades sources count as 2 each), and unknown params are rejected (Unknown argument 'minSize' for 'trade_volume_by_size'). See Data Sources.
  • buy_sell_volume gains a currency param (3.0.66). source("buy_sell_volume", symbol, exchange, currency="USD") returns quote-notional (USD) volume; omitting currency keeps the base-coin default, so CVD scripts can match production magnitude without in-script * close pricing. See Data Sources.
  • plotHistogram(value, base?, colors?, colorIndex?, width?) (3.0.66). Single-value columns grown from a base baseline (default 0), with the standard dynamic styling (colors + per-bar colorIndex, width) for MACD-style delta and pressure histograms. Arrays are rejected (plotHistogram takes a single value series; use plotBar for [low, high] ranges) and it cannot be batched (plotBatches: 'plotHistogram' is not supported inside a plotBatches callback yet). See Plotting.
  • array.sort() comparator (3.0.67). sort((a, b) => ...) is accepted alongside the argless numeric sort (.sort((a, b) => b - a) sorts descending). The comparator must return a finite number: a comparator that statically returns a non-number is a compile error (Array method 'sort' comparator must return a number, got string), and one that returns na at run time is a named runtime error (Array method 'sort' comparator must return a finite number), never a silent no-op. See Collections.

Changed

  • Human import-name diagnostic (3.0.64). A malformed library name in import no longer prints raw regexes. It now reads: Invalid library name in import. Names are lowercase letters, digits, and underscores, starting with a letter, with an optional @x.y.z version pin. Examples: import "my_lib", import "@owner/my_lib", import "@owner/my_lib@1.2.0". A well-formed name that simply is not registered still fails as Unknown library 'my_lib'. See Libraries.
  • Version-header verdict. //@version=2 and //@version=3 are interchangeable: the engine routes both to the same modern dialect, and every v3 feature runs under either line. //@version=3 is the canonical header for new scripts; there is no downgrade. A missing marker or //@version=1 routes to the deprecated legacy v1 engine. See Migration (v2 vs v3).

Previous releases

v3.0.61 — Strategy backtesting framework

July 2026 · Engine @orangecharts/kscript 3.0.61 ships the strategy backtesting framework: strategy(...) script headers, strategy.* order methods against a deterministic lookahead-free broker emulator (market/limit/stop entries, bracket exits with trailing stops and OCA, sizing modes, commission and slippage), and output.strategy on the wire with trades, equity, drawdown, and locked performance stats. Results render in the Strategy Tester panel. See Strategies for the full guide.

v3.0.54 — Statistics rows, sparse source alignment, and canonical registry release

July 2026 · Engine @orangecharts/kscript 3.0.54 is the canonical public build for the post-mini-chart engine line. It includes per-bar statistics rows through plotStatRow(), aligns sparse flow sources onto the candle timeline so missing buckets read as zero after coverage begins, and publishes the merged 3.0.52/3.0.53 work under one registry version for frontend, backend, alerts, and docs to consume.

Added

  • plotStatRow(value, title?, format?, polarity?, priority?, colors?): adds a compact row to the per-bar statistics strip under the price pane. Use it for volume, delta, funding, liquidation totals, range, or custom scores without drawing a new series or owning a pane. Docs

Fixed

  • Sparse flow-source alignment: sources that declare missing buckets as zero now align to the chart timeline before scripts read them. Missing post-coverage buckets become 0; bars before the source's first real row stay na.
  • plotMiniChartGrid() signature lockstep: editor metadata and runtime signatures agree on the same tooltip-capable argument set.

v3.0.49 — Viewport mini-charts, pinned request anchors & panel styling

July 2026 · Engine @orangecharts/kscript 3.0.49 (rolls up the unpublished 3.0.27–3.0.48 internal releases into one npm version). Scripts can now render viewport-pinned mini-chart dashboards: plotMiniChartGrid() draws a grid of small OHLC panels that stays at a fixed screen position while the chart pans, fed by requestBars(..., { bars, anchor: "latest" }) so every panel tracks the newest market bars — historical panning never changes them, and they update live as bars form and close. Panels take five looks (candleStyle: candles, hollow, OHLC bars, line, area), an optional per-panel % change badge (showChange) and a volume strip (showVolume), plus fast/slow MAs and full color control. requestBars also gains composed intervals ("2h", "3h", "12h", "2d" — aggregated from the largest natively-served divisor) and the explicit anchor: "window" default. See Mini-chart grids and Multi-source.

Added

  • plotMiniChartGrid(panels, ...): viewport-anchored grid (up to 12 panels × 100 bars) with layout (position, columns, panelWidth/panelHeight/gap), colors, MA overlays, candleStyle, showChange, showVolume. Render-only — costs no source budget. Docs
  • requestBars(..., { anchor: "latest" | "window" }): "latest" pins the returned rows to the newest native bars regardless of pan position or execution window; "window" spells the default. The literal must be static; an anchored and a window-relative request of the same symbol/timeframe are two distinct sources. Docs
  • Composed intervals in requestBars: "2h", "3h", "12h", "2d", "45m" and similar now return true bars at the requested timeframe, UTC-bucket-aggregated from the largest natively-served divisor (previously these silently fell back to chart-interval rows).

v3.0.26 — Calendar timeframes & per-source deep HTF

June 2026 · Engine @orangecharts/kscript 3.0.26. Higher-timeframe htf() and request() gain calendar-period tokens 1D/1W/1M/1Q/1Y (uppercase, UTC-anchored: 1W = Monday week, 1M/1Q/1Y = calendar month/quarter/year), distinct from rolling Nm/Nh/Nd epoch-floor buckets, and case-significant (1m minute vs 1M month). Multi-count calendar tokens (2W) are rejected. An opts object { mode?, offset?, bars? } adds mode: "developing" (current forming period), offset: N (N completed periods back, confirmed-only), and request-only bars: N (exact fetch depth); a bare opts object in the type/exchange slot is coerced to opts. Correction: a coarser-timeframe request() now fetches its own deep history scaled by the requested interval (daily/weekly/monthly/yearly levels resolve on a 1m chart), superseding the earlier "bounded by the chart's loaded window" behavior. Day/week/month aggregate from a deep daily backing source; quarter/year from a weekly one (quarter/year open/close can be off by up to ~1 week). See Multi-Timeframe.

Added

  • requestBars(symbol, timeframe, type?, exchange?, { bars }): returns the last N native bars of a symbol at a coarse interval as a plain [time, open, high, low, close, volume] array (oldest first), draw-only and independent of maxBarsBack. The drawing counterpart to request(): iterate the rows and draw (last N daily highs/lows, weekly ranges) instead of feeding a chart-aligned, TA-chainable series. Docs

v3.0.15 — Deep-history anchoring & plot-label rules

June 2026 · Engine @orangecharts/kscript 3.0.15. define(..., maxBarsBack=N) opt-in deep-history declaration: the host preloads up to N bars (capped at 20000, and per viewer tier on the chart) so cumulative and anchored VWAPs stay fixed as the chart pans instead of re-anchoring to the newest loaded bar. Plot labels are now required and unique at publish, while desc is optional and no longer validated. A coarser-timeframe request() fetches that interval natively. (At 3.0.15 a higher-timeframe request() was still bounded by the chart's loaded window; engine 3.0.26 changed this so each higher-timeframe request fetches its own deep history. See the 3.0.26 entry above.)

Older releases

v3.2.0 — Ergonomics & precision

June 2026 · Named streams on multi-output indicators (bands.upper, macd.signal[1]), calendar-anchored VWAP (vwap(anchor="day") — stable under history loading, honest na for partial sessions), and methods on user-defined types (func in type blocks with this, instances stay clone-safe plain data).

Full notes →

v3.0.7 — v2 compatibility hardening

June 2026 · Engine patch release (@orangecharts/kscript 3.0.7). No new features: v2 conveniences restored (plotText alignment synonyms, plotShape shape aliases incl. star, bare NaN as an alias of na) and two runtime sandbox ceilings raised to installed-base reality (data sources 8 → 20, output objects 20,000 → 50,000).

Full notes →

v3.1.0 — Multi-source & data policy

June 2026 · Multi-symbol and multi-venue scripts get first-class tooling: request() (one-call other-symbol/HTF data), ltf() (lower-timeframe bars as cells on your chart's bars), a per-script source budget, machine-readable source catalog, and aggregation patterns (cross-exchange CVD, weighted OI) documented end to end.

Full notes →

v3.0.0 — The flexibility release

June 2026 · Collections + lambdas, user-defined types, real na, stateful drawing objects with handles, multi-timeframe htf() (no-repaint by default), a reference-validated TA library (~40 indicators), value-driven styling, typed inputs (incl. source re-targeting), and importable libraries with versioning and hot reload.

Full notes →

All releases

VersionDateHighlightsBreaking changes
v3.0.67Jul 2026Foreign-domain panes (plotMatrix/plotCurve/plotTiles incl. computed text tiles, valueFormat, hideLegendValues, source-validated caps), perps strategy mode (isolated margin, maker/taker fees, funding, liquidation + new stats), tape sources (trades, trade_volume_by_size, buy_sell_volume currency), plotHistogram, array.sort comparator, human import diagnostic (rolls up 3.0.62–3.0.66)None (additive)
v3.0.61Jul 2026Strategy backtesting framework: strategy(...) headers, strategy.* orders, deterministic lookahead-free broker emulator, output.strategy trades/equity/statsNone (additive)
v3.0.54Jul 2026plotStatRow per-bar statistics strip rows, sparse flow-source zero alignment, canonical registry release for the 3.0.52/3.0.53 workNone
v3.0.49Jul 2026Viewport mini-chart grids (plotMiniChartGrid with candleStyle/showChange/showVolume), requestBars anchor: "latest"/"window", composed intervals (2h, 3h, 12h, 2d)None (additive; omitted options render identically)
v3.0.7Jun 2026v2 compatibility hardening: plotText/plotShape enum synonyms restored (case-insensitive, star maps to diamond), bare NaN accepted as an alias of na, runtime source budget raised 8 → 20, output-object ceiling raised 20,000 → 50,000None (strictly widening)
v3.2.0Jun 2026Named streams on multi-output TA (.upper/.signal/.k/.line + history indexing), vwap(anchor) calendar sessions, struct methods (func + this in type blocks), fillBetween works end to end on named streamsNone (additive; unanchored vwap() and positional access unchanged)
v3.1.0Jun 2026request() sugar, ltf() lower-timeframe cells, per-script runtime source budget (8 at release, 20 since v3.0.7), source catalog, multi-venue aggregation docs (cross-exchange CVD, weighted OI), feed eviction hardeningNone (additive; ltf() requires a platform data-service update)
v3.0.0Jun 2026Collections + lambdas/reducers, type structs, na/isna/nz, color type, drawing objects (line.new...table.new + handles), htf() MTF, ~40 reference-validated TA builtins, switch/persist/defaults/format, typed inputs, library()/import, sandbox limits manifestTwo corrections: 8 TA builtins to textbook formulas + strict sma warmup (early-bar values change; see Migration (v2 vs v3))
v2.2.0Jun 2026plotPie per-bar pie chart (auto-normalized slices, display text mode, batchable with per-element radius/colors); documented volume_profile row structure + raw bucket accessNone (additive within v2)
v2.1.0May 2026plotPriceLabel builtin, glow halo on chart-shape plots, lineStyle (solid/dashed/dotted), opacity on plotShape/plotTextNone (additive within v2)
v2.0.0Sep 2025Per-bar execution model, kwargs, stronger compiler, dedicated data subscriptions, scalars from indicators, func + loops, extended plotsYes (relative to v1; see Migration (v1 vs v2))

v3.0.7 — June 2026

Engine patch release (@orangecharts/kscript 3.0.7), focused on v2 compatibility hardening after the v3 rollout. Nothing here is a new feature: call forms that were legal on v2 are accepted again, and two sandbox ceilings move up to match how scripts are actually used.

Restored

  • plotText alignment synonymsyAlign accepts CENTER/ABOVE/BELOW again, case-insensitively, normalized to middle/top/bottom.
  • plotShape shape aliases — shape names are case-insensitive and the v2 aliases are accepted, including star (maps to diamond).
  • Bare NaN — accepted again as an alias of na.

Raised

  • Source budget — runtime MAX_SOURCES_PER_SCRIPT moved 8 → 20 distinct data sources per script. Engine 3.0.11 unified the editor and runtime budgets at 20, so a 6-20 source aggregation script now passes both.
  • Output objects — 20,000 → 50,000 per run (MAX_OUTPUT_OBJECTS).

Compatibility

  • None breaking; every change strictly widens what is accepted. Scripts written against the stricter v3.0.0 surface run unchanged.

v3.2.0 — June 2026

Three quality-of-life walls came down: multi-output indicators grew names, VWAP grew anchors, and types grew methods.

Added

  • Named streams. bb/keltner expose .basis/.upper/.lower, macd exposes .macd/.signal/.histogram (alias .hist), stoch exposes .k/.d, supertrend exposes .line/.direction. Streams support history indexing (macd.signal[1] > macd.signal[2]) and feed fillBetween(bands.upper, bands.lower, ...) directly. Unknown stream names are compile errors listing the valid ones.
  • Anchored VWAP. vwap(anchor="day"|"week"|"month") (or raw milliseconds) resets at UTC calendar boundaries. Anchored values are stable when older history lazy-loads (each session is self-contained); a leading partial session emits na instead of a wrong line. vwap() with no anchor keeps the cumulative behavior unchanged.
  • Struct methods. func declarations inside type blocks, dispatched from the type with this bound to the receiver (this.field = x mutates the struct). Instances remain plain clone-safe data; methods never collide with globals; library-exported types carry their methods.

Compatibility

  • Fully additive: positional stream access, unanchored vwap(), and field-only types behave byte-identically to v3.1.

v3.1.0 — June 2026

The data layer opened up: one script can now combine symbols, venues, and data types with proper guard rails, and the docs gained a dedicated Multi-Source & Aggregation guide.

Added

  • request(symbol, timeframe?, type?, exchange?) — one call for the most common multi-symbol need; sugar over source() + htf() with the same no-repaint guarantee. Docs
  • ltf(interval, ...) — lower-timeframe bars delivered as cells on the chart's own bars (ltf("15m").cells on a 1h chart = each bar's four 15m bars), composing with reducers and structs like any order-flow source. Requires the matching platform data-service update; intervals are literal strings, strictly finer than the chart.
  • Source budget — at most 8 distinct data sources per script at release (identical calls dedupe; htf()/derived series free), joining the sandbox manifest with the usual loud line:column error and tier override. Raised to 20 in v3.0.7.
  • Source catalog — the platform now serves a machine-readable catalog of which source types and venues exist, and unavailable requests fail with the list of what does.
  • Aggregation patterns documented — cross-exchange CVD, venue-weighted open interest, dominance ratios, and HTF views of aggregates, all on the new multi-source page.

Changed

  • Live feeds for non-OHLCV secondary sources (funding, open interest, ratios) now merge ticks by their real data shape on the backend; secondary series on live charts become correct where they were previously merged as candles.
  • Idle feed eviction hardened platform-side (streams with zero registered consumers unsubscribe within one scan; failures keep streams alive rather than dropping them).

Compatibility

  • Fully additive language-side. ltf() errors clearly until the platform data services ship the matching update.

v3.0.0 — June 2026

The largest upgrade kScript has had: the language grows from "indicator scripting" to a full charting language with data structures, your own types, stateful drawings, multi-timeframe access, and shareable libraries. Existing v2 scripts run unchanged (two narrow numeric corrections aside; see below). Full guides for everything here are linked throughout the docs; the migration page has the adoption path.

Added

  • Collections — first-class arrays and maps with method-call syntax (book.push(x), levels.get("poc")), negative tail indexing, insertion-ordered maps, and compile-time element-type checking. Docs
  • Lambdas & reducers(x) => ... with closures; map/filter/reduce/forEach/find/some/every replace most loops. Docs
  • User-defined typestype Zone { top: number, bottom: number }, Zone.new(top=...), defaults, nesting, collections of structs, all field access compile-checked. Docs
  • Real na — falsy, propagating, structurally equal; isna()/nz(); a compiler warning on direct na-comparison; events never fire on na. Docs
  • color type — validated color.rgb(r, g, b, a?); strings remain valid everywhere.
  • Multi-timeframehtf(source, "4h") base-aligned views with a no-repaint default (provably causal), developing mode, offset, scalar and footprint resampling. Docs
  • Stateful drawing objectsline.new, box.new, label.new, polyline.new, linefill.new, table.new return mutable handles: move, restyle, delete(); store handles in collections and structs. Docs
  • Drawing primitives — 10 plotShape shapes with location placement and char markers; barcolor(); fillBetween(); per-cell styled tables. Docs
  • Styling — size tiers, tooltips on every output, unified alignment, zOrder, palette(), and value-driven per-element gradients/opacity/glow. Docs
  • Control flow & ergonomicsswitch (no fallthrough), compound assignment, persist (the clearer spelling of static), default parameters, format()/tostring()/tonumber(). Docs
  • TA library — ~40 indicators each validated bar-for-bar against independent textbook references (1e-6), including multi-output bb, keltner, stoch, supertrend, macd; uniform warmup and forward-fill conventions; everything composes (including over order-flow series). Docs
  • Typed inputsint, float, source, timeframe, session, symbol; constraints enforced (never silently clamped); group/tooltip/inline; settings changes apply with zero refetches; source inputs can point an indicator at microstructure data. Docs
  • Librarieslibrary("name", "1.0.0") + import "name" as ta, version pinning, script-wins precedence with warnings, hot reload in the playground. Docs
  • Sandbox limits manifest — every ceiling named and documented with exact numbers; all failures report line:column; runaway scripts are interrupted mid-loop. Docs

Changed

  • Eight TA builtins corrected to textbook formulas (ema, rsi, macd, psar, adx, highest, lowest, plus strict sma warmup): early-bar/warmup values change versus v2 (honest na warmup instead of fabricated early values; convergent thereafter). stddev and rma keep their legacy semantics, documented as such. Details and reasoning: Migration (v2 vs v3).

Compatibility

  • No new reserved words (type, switch, persist, import are contextual).
  • Script-defined functions always beat same-named new builtins.
  • Legacy call forms (positional inputs, scalar table cells, static, string colors, uppercase alignment) all keep working.

v2.2.0 — June 2026

Pie plots and clearer volume-profile access: a new proportional pie builtin, plus first-class documentation of the volume_profile row structure and raw price-level bucket access.

Added

  • plotPie(value, price, radius?, colors?, opacity?, display?) — per-bar pie chart drawn as a proportional circle anchored to a price.
    • value is an array of slice magnitudes, normalized automatically ([60, 40] → 60% / 40%; [3, 1] → 75% / 25%).
    • price sets the vertical anchor; radius (px), colors (per slice), and opacity (0–1) control appearance.
    • display — per-slice text mode: "percent" (default), "value", or "none". This is a single mode string, not the label=[...]/desc=[...] series-label arrays the other plots take.
    • Batchable — works inside plotBatches, so you can draw one pie per price level (e.g. buy/sell split at every volume_profile bucket). Each batched pie carries its own radius, colors, and opacity.

Documented

  • volume_profile data structure — each bar is a row shaped [timestamp, [priceLow, priceHigh, buyVol, sellVol], …]: slot 0 is the timestamp and every later slot is one price-level bucket. The bucket count varies per bar.
  • Raw bucket access — alongside the scalar vp* accessors, you can iterate buckets directly: vpa[0] is the current row and vpa[0][i + 1] is the i-th bucket. Pairs naturally with vpBucketCount + plotBatches (e.g. a pie per bucket).
  • Accessor functionsvpBuy, vpSell, vpDelta, vpTotal, vpPoc, vpPocVolume, vpBucketCount, vpPriceHigh, vpPriceLow documented with parameter tables and examples.

Reference

  • PlottingplotPie parameter table and examples.
  • Volume Profile Functions — data structure, raw bucket access, and the full vp* accessor reference.
  • Backward-compatible within v2; no migration required.

v2.1.0 — May 2026

Plotting refresh: a new per-bar label builtin and richer styling kwargs across the existing chart-shape plots.

Added

  • plotPriceLabel(price, text?, type?, position?, ...) — per-bar decorative label anchored at a price level. Three visual modes:
    • "callout" (default): text box with a leader line and dot
    • "simple": centered text box
    • "icon-only": SVG path or image URL, with iconSize, anchorX, anchorY controls
    • Text styling kwargs: color, backgroundColor, fontFamily, fontWeight (clamped 100–800), size (clamped 1–30), opacity (clamped 0–1)
    • tooltip for hover text (supports \n for line breaks)
    • icon-only URLs support animated GIFs and WebP, so labels can render looping or animated icons
  • glow kwarg on plotLine, plotBar, plotCandle, plotShape, and plot — soft halo around the stroke. true enables a default blur in the series color; a number sets the blur radius in pixels (clamped 0–30, 0 disables).
  • lineStyle kwarg on plotLine and plot"solid" (default), "dashed", or "dotted". No effect on bar / candle / point types.
  • opacity kwarg on plotShape — overall element opacity (0–1, clamped).
  • fontWeight and opacity kwargs on plotText — text weight 100–800 (clamped, rounded to nearest 100) and overall opacity 0–1 (clamped).

Changed

  • plotShape shape catalog clarified"circle", "triangle", "cross", and "diamond" are all supported. The reference previously documented circle-only.

Reference

  • Plotting — full parameter tables, including the new entries.
  • This release is backward-compatible within v2; no migration required.

v2.0.0 — September 2025

Major release of kScript v3 on the OpenMarket platform: new execution model, language features, and standard library—with intentional breaking differences from v1 for long-term ergonomics and performance.

Added

  • Per-bar execution with clear phases for initialization, calculation, and plotting—see Execution model.
  • Keyword arguments on builtins for clearer, order-independent calls (Keyword arguments).
  • func user-defined functions and for / while loops (with the documented var restrictions) (User functions).
  • Dedicated data subscriptions: ohlcv(...), trades(...), orderbook(...) replacing the generic v1-only source(...) pattern in v2 docs.
  • Reverse index access on time series (ts[0] = latest bar) as described in the v1→v2 transition material.
  • Extended plotting: plotCandle, plotShape, and richer styling kwargs alongside existing line/bar plots (Plotting).

Changed

  • Technical indicator helpers now resolve to scalar values per bar instead of returning full composite series that required manual alignment in typical v1 usage.
  • Compiler performs stronger static analysis (syntax, scope, types) so more issues surface at edit time rather than at runtime.
  • OHLCV field access standardized via accessors such as ohlcvTs.close, ohlcvTs.volume, etc.

Fixed

  • Class of issues where v1 scripts could run without obvious errors yet mis-align series or misuse full-series returns; v2’s model and compile checks reduce this failure mode.

Breaking changes

  • Scripts written for kScript v1 are not source-compatible with v2 without migration (execution model, subscriptions, indicator return shapes, and keyword-only ergonomics). Use the v1 vs v2 migration guide together with this entry when porting.
  • Removal of reliance on buildTimeseries / mergeTimeseries / matchTimestamp-style manual alignment in favor of engine-driven per-bar evaluation for typical indicators.