Documentation

Documentation

5. v0.5.0 — Pine Script Engine

Created
Jun 16, 2026
Updated
Jun 16, 2026

Released 2026-06-16. This release integrates a full Pine Script v6 engine (piner) into Fractal Chart, replacing the previous TypeScript strategy engine and dramatically expanding what custom indicators and strategies can do. Pine is now the default authoring language for both indicators and backtesting strategies. See the Authoring guide.

Added

Pine Script v6 engine

  • Full Pine Script v6 indicator compute. Indicators written in Pine Script v6 run end-to-end: plot(), plotshape(), plotchar(), plotarrow(), plotbar(), plotcandle(), fill(), bgcolor(), barcolor(), hline(), and all plot styles. Compute is extracted into a clean headless-compute module that runs synchronously on the render path and is also usable in background and worker contexts.
  • All drawing families. Pine drawings render on-chart with full style support: line.new, label.new, box.new, polyline.new, linefill.new, and table.new/table.cell. Multi-line labels, text.align_*, label.size.*, color=na transparency, and extend.* line caps all work. Two-point overloads for line.new and box.new are supported.
  • request.security — cross-symbol and higher-timeframe data. Pine indicators can pull data from any symbol or a higher timeframe using request.security. The host fetches and injects the bars; security requests are provider-bound with encodeURIComponent sanitization.
  • request.security_lower_tf — intrabar data seam. Lower-timeframe intrabars can be fetched and injected for Pine indicators that need intrabar resolution.
  • Pine alerting bridge. alert(), alertcondition(), and log.info/warning/error inside Pine indicators are bridged into Fractal's alerting system. Live-bar alerts route through the same notification channels (toast, browser notification, sound, webhook) as price alerts. See Alerts.
  • input.string and input.source controls. Indicators that declare input.string or input.source parameters now render the correct controls in the indicator settings dialog (a text field and a source selector, respectively).
  • Pine strategy backtesting. Strategies written in Pine Script v6 run in a sandboxed Web Worker with a 20-second hard timeout. Fractal's broker configuration (initial capital, commission, slippage, position sizing, pyramiding, process_orders_on_close) bridges cleanly into piner. Results are returned as a BacktestResult with full stats parity (net profit, equity curve, drawdown, Sharpe/Sortino, CAGR, per-trade list). Pine starter templates are included in the strategy picker alongside the existing TypeScript templates.

Indicator legend

  • On-chart indicator legend. A collapsible legend panel overlays each chart pane showing the active indicators, their current values (or OHLCV for the main series), and per-indicator action buttons. The collapse state is persisted to localStorage.
  • Standalone settings dialog. Clicking the settings icon in the legend opens a full indicator settings dialog — same dialog available from the indicator picker — without navigating away from the chart.

Dependency

  • @heyphat/piner from GitHub Packages. The Pine engine is published as a private package under @heyphat/piner and consumed via "piner": "npm:@heyphat/piner@^0.1.0". Install requires a NODE_AUTH_TOKEN with read:packages (see README.md). The vendor/piner submodule is kept as a reference copy and for local publishing.

Changed

  • Pine is the default indicator authoring language. The indicator editor opens Pine Script v6 by default; TypeScript indicators continue to work and can be selected explicitly.
  • Strategy engine is Pine-only. The previous TypeScript strategy execution engine has been removed and replaced by the Pine strategy worker. Existing TypeScript strategy drafts are preserved and can still be viewed, but new runs use the Pine path. Old drafts with kind: 'ts' are handled gracefully (they open without error and prompt a migration note).
  • Backtest stats module unified. Net profit, equity, drawdown, Sharpe/Sortino, and CAGR calculations are shared between the native and Pine backtesting paths via engine/stats.ts. Commission and slippage units bridge correctly (×100 for percent-based commission).

Fixed

  • Multi-line label rendering. Pine label.new with \n in the text renders as multiple lines on the chart.
  • Label size and color. label.size.* constants are respected; color=na on a line renders transparent (not the default blue).
  • Color picker 8-digit hex. The color picker correctly handles 8-digit #RRGGBBAA hex values from Pine.
  • Top-left overlay stacking. The indicator legend and other top-left chart overlays no longer overlap each other — they are stacked correctly with pointer-events set appropriately.
  • Indicator scroll performance. Comparison-hover bar lookups are cached; indicator rendering during scroll is optimized to avoid redundant recomputes.
  • pineSecurityBars re-render. Cross-symbol request.security data arriving as a new prop now correctly triggers an indicator-layer re-render via a dedicated effect, rather than waiting for the next streaming tick.

Notes

  • Pine indicators run synchronously on the main thread. Compute is guarded by piner's internal loop-iteration budget. A future release will move indicator compute off the main thread once the render-synchronization challenge (avoiding stale intermediate frames) is solved.
  • Cross-symbol fetch volume is currently uncapped. A Pine indicator can request many symbols; a cap will be added in a follow-up. Avoid running indicators with very large request.security fan-outs on slow/closed-market charts.
  • Alert routing. alert() and alertcondition() in a Pine indicator route to the same global channels as price alerts. Per-indicator opt-in for webhook routing will be added in a follow-up.

Next steps

Back to the release list.

Next: Release Notes