cd /news/ai-tools/we-transpiled-pinescript-v6-to-c-so-… Β· home β€Ί topics β€Ί ai-tools β€Ί article
[ARTICLE Β· art-23510] src=dev.to pub= topic=ai-tools verified=true sentiment=↑ positive

We Transpiled PineScript v6 to C++ So Backtests Are Actually Reproducible

A developer built PineForge, a transpiler that converts TradingView's PineScript v6 source code into C++ for offline backtesting on any OHLCV CSV data. The system achieved trade-for-trade parity with TradingView on 245 out of 246 reference strategies, validating over 375,000 trades with zero engine bugs. The single failing strategy was traced to a confirmed TradingView-side anomaly in bar-close ordering for a multi-timeframe edge case.

read4 min publishedJun 6, 2026

TradingView's PineScript is the most widely used language for writing trading strategies. Millions of scripts. One problem: you can't run them anywhere except TradingView.

That means:

We built PineForge to fix this. The core idea: transpile PineScript v6 source to C++, compile it, run it offline on any OHLCV CSV.

Here's how the pipeline works and what we learned building it.

PineScript v6 source
        β”‚
        β–Ό
    Lexer / Tokenizer
        β”‚
        β–Ό
    Parser β†’ AST
        β”‚
        β–Ό
    Semantic Analyzer
    (type inference, series detection, scope resolution)
        β”‚
        β–Ό
    Codegen
        β”‚
        β–Ό
    C++ class (extends BacktestEngine)
        β”‚
        β–Ό
    g++ / clang++ β†’ native binary

Each Pine script becomes a C++ class that extends our BacktestEngine

base. TA call-sites (ta.sma

, ta.rsi

, ta.crossover

, etc.) resolve to inlined C++ implementations. Pine's series[]

type β€” which is really a lazy reverse-index into a rolling buffer β€” becomes a fixed-size ring buffer with bounds checking.

The trickiest part wasn't the TA functions. It was Pine's execution model.

Pine evaluates top-to-bottom on every bar, with implicit state accumulation. There's no explicit loop β€” the runtime loops over bars for you, and every var

-prefixed declaration persists across bars.

//@version=6
strategy("Example")

var float cumulative = 0.0
cumulative += close

sma20 = ta.sma(close, 20)

if ta.crossover(close, sma20)
    strategy.entry("Long", strategy.long)

In C++, this becomes something like:

class ExampleStrategy : public BacktestEngine {
    float cumulative = 0.0f;  // var β†’ class member, initialized once

    void onBar() override {
        cumulative += close();  // series access via method

        float sma20 = ta_sma(close_series, 20);

        if (ta_crossover(close_series, sma20_series)) {
            strategy_entry("Long", Direction::LONG);
        }
    }
};

var

declarations become class members. Non-var

locals get re-initialized every bar. Series lookbacks (close[1]

, close[5]

) become ring buffer accesses with automatic history tracking.

Writing a transpiler is one thing. Making it match TradingView trade-for-trade is another.

We built a corpus of 246 reference strategies β€” everything from classic MACD crossovers to multi-timeframe trend followers with complex entry/exit logic. For each:

Current result: 245/246 strategies at strict parity. 375,000+ trades validated. Zero engine bugs.

The one failing strategy hits a confirmed TradingView-side anomaly (their bar-close ordering in a specific multi-timeframe edge case). We've documented it; it's not our bug.

Getting from "mostly works" to 245/246 required fixing:

strategy.close_all

timingcalc_on_every_tick

modebarstate.isconfirmed

semanticsbarstate.islast

in historical replayrequest.security

bar alignmentTradingView's "Bar Magnifier" (premium feature) lets you simulate limit fills inside a bar. We implemented this with six distribution modes:

Mode Description
uniform
Equal probability across the bar range
cosine
Bell-shaped, price spends more time near midpoint
triangle
Linear taper from open to close
endpoints
Bimodal, price near open/close
front_loaded
Higher probability near open
back_loaded
Higher probability near close

All modes support optional volume weighting. A limit order at $100 inside a $95–$105 bar fills at exactly $100 if the simulated path crosses it β€” no last-tick approximation.

Pine strategies have parameters. Finding good ones via grid search is slow. We wired in Optuna with a custom objective interface:

def objective(trades):
    returns = [t.pnl_pct for t in trades]
    sharpe = mean(returns) / std(returns) * sqrt(252)
    max_dd = compute_max_drawdown(trades)
    return sharpe - 2.0 * max_dd  # penalize drawdown heavily

TPE sampler, pruning via MedianPruner, parallel trials via n_jobs

. The optimizer calls the compiled C++ binary directly β€” no Python overhead on the hot path.

One Docker container. No API key. No account.

docker run --rm -v $(pwd):/workspace pineforge/engine:latest \
  transpile --input /workspace/my_strategy.pine --output /workspace/out/

docker run --rm -v $(pwd):/workspace pineforge/engine:latest \
  backtest \
    --strategy /workspace/out/my_strategy \
    --data /workspace/BTCUSDT_1h.csv \
    --from 2022-01-01 --to 2024-01-01

Output: JSON trade list, equity curve, summary stats. Pipe it anywhere.

.so

binaries; buyers tune exposed inputs, never see source. AES-256-GCM encrypted, Ed25519-signed, machine-bound licenses.The engine is open-core (Apache 2.0). The codegen is on GitHub. The 246-strategy parity corpus is public.

If you've ever hit TradingView's runtime ceiling β€” wrong fills, irreproducible results, locked data β€” this is the escape hatch.

Questions about the transpiler architecture, parity methodology, or the optimizer integration? Ask in the comments.

Worth being explicit about this since it trips people up.

** pineforge-engine** β€” Apache 2.0. The C++ runtime, the backtest engine, the ABI-stable

.so

interface. Full open source. CI runs on Ubuntu + macOS, 93.06% line coverage, 16 ctest binaries on every commit. Free to audit, fork, deploy.** pineforge-codegen** β€” the Python transpiler package β€” is source-available under

Short version: the engine is fully open. The transpiler is free for personal trading, source-available, paid for commercial use.

── more in #ai-tools 4 stories Β· sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/we-transpiled-pinesc…] indexed:0 read:4min 2026-06-06 Β· β€”