Pine Script v6: What Changed and Why It Matters for Your Trading Bot
Back to Blog
TutorialMay 18, 202611 min read

Pine Script v6: What Changed and Why It Matters for Your Trading Bot

PF

PineForge Team

Automated Trading Platform

Pine Script v6 is the biggest language update TradingView has shipped since v5 in 2021. Stronger type system, dynamic security requests, redesigned strategy functions, and meaningful execution speed-ups. If you're still on v5, your scripts work — but you're missing capabilities that change how strategies can be structured.

This guide covers what changed, what broke, what's worth migrating for, and how to move v5 strategies to v6 without surprise behavioural shifts. PineForge runs v6 natively, so anything you write here runs in both the backtest engine and live bots without modification.

A glowing Pine Script v6 code editor showing new syntax features with version-6 labels highlighted in emerald — dark IDE aesthetic with futuristic fintech overlay
A glowing Pine Script v6 code editor showing new syntax features with version-6 labels highlighted in emerald — dark IDE aesthetic with futuristic fintech overlay

What is Pine Script v6?

Pine Script v6 is the sixth major version of TradingView's strategy and indicator language, released in early 2026. The headline changes:

  • Dynamic security requests: — `request.security()` can now take a runtime symbol expression
  • Stronger type system: — user-defined types are now first-class with methods
  • Redesigned strategy() parameters: — clearer sizing semantics, better commission handling
  • Map and matrix improvements: — faster, with new methods
  • Plot performance: — significant rendering speed-ups
  • Strict mode: — catches more bugs at compile time
  • The version is set in the first non-comment line: //@version=6. Scripts default to v5 in the editor for now, so the version change is opt-in.

    The breaking changes you'll hit first

    Most v5 scripts compile under v6 with minor edits. A handful of patterns break outright.

    Dynamic request.security() requires explicit type

    In v5, you could call request.security(syminfo.tickerid, "1D", close) and Pine inferred everything. In v6, dynamic symbol expressions need an explicit type hint:

    //@version=6

    my_symbol = input.symbol("XAUUSD")

    daily_close = request.security(my_symbol, "1D", close, lookahead=barmerge.lookahead_off)

    The compiler enforces this because mixing dynamic symbols with implicit types caused subtle backtest-vs-live divergence in v5.

    strategy() parameter renames

    Several strategy() parameters changed names for clarity:

  • `default_qty_value` → still works, but `default_qty` is the canonical name in v6
  • `commission_type` and `commission_value` are unchanged
  • New parameter: `process_orders_on_close` defaults to `false` — important for matching live behaviour
  • If your v5 strategy used process_orders_on_close=true to match live fills, you need to set it explicitly in v6. Otherwise your backtest will fill orders on the next bar's open instead of the close that signaled the trade.

    Type inference is stricter

    Pine v6 will refuse to compile code that v5 silently coerced:

    //@version=6

    my_value = na // type: any — error if used

    my_value := close // now bound to float

    my_value := "hello" // ERROR: cannot assign string to float

    In v5, this would have worked. In v6, you declare types up front or get errors. The fix is usually one line — declare the type explicitly with var float my_value = na.

    What's actually better in v6

    The changes that justify migration aren't the renames. They're the new capabilities.

    User-defined types with methods

    v5 had user-defined types but they were value-only. v6 lets you attach methods:

    //@version=6

    type Trade

    float entry_price

    float stop_price

    int direction

    method risk(this) =>

    math.abs(this.entry_price - this.stop_price)

    t = Trade.new(entry_price=close, stop_price=close - ta.atr(14)*2, direction=1)

    plot(t.risk())

    This makes strategies with complex order management dramatically cleaner. Instead of parallel arrays of entry prices, stop prices, and directions, you have one array of Trade objects with methods that compute derived properties.

    Map.foreach and matrix operations

    Iterating over maps required boilerplate in v5. In v6:

    //@version=6

    positions = map.new<string, float>()

    map.put(positions, "EURUSD", 1.0850)

    map.put(positions, "XAUUSD", 2340.50)

    map.foreach(positions, (key, value) =>

    label.new(bar_index, value, key + ": " + str.tostring(value))

    )

    For portfolio-style strategies tracking multiple symbols or positions, this collapses dozens of lines of v5 boilerplate.

    Faster execution

    TradingView's release notes claim 20–40% faster script execution. In practice, the speed-up is most noticeable on strategies with many request.security() calls or large user-defined-type collections. Indicator-heavy scripts see smaller gains.

    For backtesting on PineForge, v6 scripts complete roughly 25% faster than the equivalent v5 on identical data ranges. Not transformative, but meaningful when running large parameter sweeps.

    Should I migrate my v5 strategies to v6?

    For a working v5 strategy with no planned changes, no — leave it alone. v5 is still fully supported and v6 doesn't add capabilities that change profitability for a finished strategy.

    Migrate when:

  • You're rewriting the strategy anyway
  • You need dynamic symbol requests (e.g., scanning multiple pairs)
  • The strategy uses complex order management that would benefit from typed methods
  • You're seeing backtest-vs-live divergence and want v6's stricter execution model
  • Don't migrate just because v6 is newer. Pine Script doesn't have the JavaScript-ecosystem churn problem — older versions stay supported indefinitely.

    How do you migrate Pine Script v5 to v6?

    The mechanical migration is four steps:

  • Change `//@version=5` to `//@version=6` at the top of the script
  • Run the script in the Pine Editor — compiler errors will pinpoint the breaks
  • Fix type assignments — add explicit type declarations where the compiler complains
  • Verify `process_orders_on_close` matches your live execution expectation — set explicitly
  • For most strategies under 300 lines, total migration time is 10–30 minutes. For larger strategies with custom helper functions, expect an hour or two.

    After migration, run a backtest on the same date range as your v5 version and compare equity curves. They should be nearly identical. Any divergence usually points to one of:

  • Subtle order-filling behaviour difference (the `process_orders_on_close` issue)
  • An implicit type coercion that v6 now handles differently
  • A bug in v5 that v6 surfaces
  • If you're running the strategy on PineForge, upload both versions, backtest each on the same parameters, and compare the trade lists. Differences will be obvious within the first ten trades.

    What about Pine Script v4 and earlier?

    v4 is technically still supported but receives no new features. v3 and earlier are deprecated — they still load but the editor flags them. If you've inherited a v3 or v4 script and want to keep it running, migrate directly to v6, not to v5. The total work is similar, and you skip an upgrade cycle.

    Pine Script v6 and live trading bots

    For PineForge live bots, v6 is the recommended target. The platform's interpreter is v6-native, which means the live execution semantics match TradingView's reference implementation exactly. v5 scripts still work and are translated transparently, but anything new should ship as v6.

    The practical impact: v6's stricter execution model reduces the gap between backtest results and live trading results. Slippage and broker latency remain real costs, but the script-level execution model is no longer a source of divergence.

    If you're seeing your bot underperform its backtest by more than slippage and commission can explain, migrating to v6 and re-running the backtest often closes the gap. See our piece on strategy decay detection for the broader diagnostic process.

    Common v6 mistakes to avoid

    Three patterns we see repeatedly in support requests after v6 migration:

  • Mixing `var` and non-`var` declarations for the same name. v6 enforces this strictly. If a variable is var in one place, it must be var everywhere.
  • Assuming `request.security()` is free. Dynamic requests are powerful but each one costs execution time. A v6 strategy that makes 20 dynamic security calls per bar will be slower than a v5 strategy with hard-coded symbols.
  • Forgetting that `process_orders_on_close` defaults changed. If your v5 backtest matched live behaviour and your v6 backtest doesn't, this parameter is the first thing to check.
  • Conclusion

    Pine Script v6 is worth learning but not worth a panic migration. The headline features — dynamic security requests, typed methods, faster execution — matter most for new strategies you're building from scratch. Existing strategies that work should stay on v5 unless you have a specific reason to move.

    For new builds in 2026, target v6 from the start. The cleaner type system catches bugs early, dynamic requests enable strategy patterns that were awkward in v5, and the execution speedup adds up across long backtests. The Pine Script reference documentation is the authoritative source for syntax details.

    Build your v6 strategy, backtest it on PineForge across years of real market data, and deploy it as a live bot when the numbers justify it. The language is stable; the strategy work is yours.

    pinescript
    //@version=6
    my_symbol = input.symbol("XAUUSD")
    daily_close = request.security(my_symbol, "1D", close, lookahead=barmerge.lookahead_off)
    pinescript
    //@version=6
    my_value = na           // type: any — error if used
    my_value := close       // now bound to float
    my_value := "hello"     // ERROR: cannot assign string to float
    pinescript
    //@version=6
    type Trade
        float entry_price
        float stop_price
        int direction
        method risk(this) =>
            math.abs(this.entry_price - this.stop_price)
    
    t = Trade.new(entry_price=close, stop_price=close - ta.atr(14)*2, direction=1)
    plot(t.risk())
    pinescript
    //@version=6
    positions = map.new<string, float>()
    map.put(positions, "EURUSD", 1.0850)
    map.put(positions, "XAUUSD", 2340.50)
    
    map.foreach(positions, (key, value) =>
        label.new(bar_index, value, key + ": " + str.tostring(value))
    )

    Start Trading Smarter

    Build, backtest, and deploy your strategies with PineForge. No coding experience required.