Why an LLM writes v5 under a v6 header
Ask a chat model for a Pine v6 strategy and you will usually get
//@version=6 on line one and v5 habits underneath it. The version line is a
string the model has learned to put there. The syntax below it comes from the
much larger body of published Pine that predates v6.
That mismatch would be harmless if it failed loudly. The problem is the shape of what survives.
Compiling it filters out the wrong half
The v5-to-v6 changes divide in two. Some stop the script — those you find in ten seconds, because the editor lists them. The rest let it compile and change what it returns [1].
A model producing v5 patterns will trip both kinds. But you only notice one, because the check most people run on AI-generated code is "does it compile" — and that check passes everything in the second group. The failures you can see are the cheap ones. The expensive ones look like working code.
Here is what gets through, all of it documented [1]:
| v5 habit the model reproduces | What v6 does instead | Compiles? |
|---|---|---|
ta.* call inside an and chain | short-circuits, so the call is skipped on some bars and its history breaks | yes |
relying on margin_long = 0 | defaults to 100, so entries needing more money than available do not open | yes |
timeframe.period == "D" | returns "1D", so the comparison is never true | yes |
integer division like length / 2 | two ints that do not divide evenly now give a fraction | yes |
a bool expected to be na | booleans can no longer be na; such expressions return false | yes |
for i = 0 to n where n changes | the bound is re-evaluated before every iteration | yes |
The first row is the one that matters most, because it does not change a number — it corrupts an indicator's internal state, and there is nothing in the source to look at. A model will write it constantly, since putting the indicator call inline reads more naturally than hoisting it.
The two that do stop the script, and why they mislead
int and float are no longer implicitly cast to bool [1], and na(),
nz() and fixnan() no longer accept bool [1]. These do error, which is
good — but they set a trap: the model fixes the error you paste back to it, you
see the script compile, and you conclude it is now correct. It is now
compiling. Those are different claims.
Where the model is most confidently wrong
Two patterns, both worth naming because they look like expertise:
It gives you an indicator when you asked for a strategy. indicator() has
no orders, no equity, and no Strategy Tester. It is the single most common
mismatch between what was asked for and what arrived, and it is instantly
visible on line two.
It invents built-ins that read plausibly. A function named the way a Pine function would be named, with sensible arguments, that does not exist. This one does raise a compile error, so it is cheap — the reason to expect it is that it tells you the model is completing a pattern rather than recalling an API, and that same mechanism is what produces the silent errors above.
A six-step check for AI-written Pine
Compiling is step five, not step one. Four of these checks find things the compiler cannot, and they are all text searches — you do not need to read the script fluently to run them.
1. Read line two
Does it say strategy( or indicator(? If you asked for something
backtestable and got indicator(), stop here. There is nothing to fix; it is
the wrong kind of script.
2. Search for and and or, and look to their right
This is the check with no substitute. For every and or or in the file, is
there a ta. call to the right of it?
// the pattern to look for — ta.rsi() is skipped on bars where
// close <= open, so its internal history stops being continuous
if close > open and ta.rsi(close, 14) > 50
The fix is to hoist the call so it runs on every bar:
rsiVal = ta.rsi(close, 14)
if close > open and rsiVal > 50
Same for ta.crossover, ta.crossunder, ta.pivothigh, ta.pivotlow and
ta.valuewhen — anything that keeps state between bars. A model writes these
inline because it reads better, and v6 short-circuits and [1], so they do not
all run.
3. Compare every ta. name against the reference manual
Not "does it look right" — look it up [2]. A plausible-sounding function that does not exist is a normal output, and so is a real function called with the wrong argument order. The reference manual is the only authority here; a model's confidence about its own API is not evidence.
4. Read the strategy() declaration for costs
No commission_value, no slippage, and the backtest you are about to admire
is of a market that charges nothing. Models routinely omit both, because most
published example code omits both. Details in
the cost parameters.
5. Now compile it
Paste, save, and read every message rather than just the first. Then — and this
is the step people skip — re-run steps 2 to 4 on the corrected version. When
you paste an error back and the model rewrites the script, it rewrites more than
the error: inlined ta. calls come back, and costs disappear again.
6. Check the trade list against the chart
Add it to a chart, open the List of Trades, pick three trades, and find them. Does each fill price correspond to a price that bar actually traded at? This catches future leak, a non-standard chart type, and a misread tick size, and it is the only step that tests the strategy rather than the source.
What this procedure cannot tell you
Whether the strategy is any good. Six passing checks mean the script does what it appears to do — not that what it does is profitable. A model that produces clean, compiling, honestly-costed Pine has given you a correct implementation of an idea it had no way to evaluate.
The more useful division of labour is to let the model explain fields and diagnose errors, and to let something deterministic emit the file. That is the argument in AI generator versus visual builder, and it is the reason our own exports come from a code generator rather than from a prompt.
Tactix AI on this workflow
AlfaTactix includes Tactix AI: use Tactix Studio to describe your idea in plain language and draft timeframes, signals, filters, and risk into the same six-step Strategy Builder form — or open Tactix Guide on any step when you only need a field explained. Review every value, then export MQL5 or Pine Script from Code Generator (form-first — not untested prompt-to-code).

