An AI gave you a complete Pine Script in seconds. It looks professional, it has named inputs and comments, and you have no particular reason to distrust it. The problem is that the two failure modes that cost the most time, code that compiles but never triggers, and code that looks right because it is reading future data, both survive a casual read.
Short answer
Verify AI-generated Pine Script in seven passes: confirm the version annotation and namespaces, check that inputs are typed and bounded, confirm the script compiles in the Pine Editor, confirm every condition actually fires on the chart, test for repainting on higher-timeframe requests, check strategy defaults such as capital and margin, then test on multiple symbols and timeframes to expose runtime errors. Compilation only proves the code is structurally valid; it says nothing about whether the logic runs or whether the values are honest.
Key facts
- Compilation validates structure only. A script can compile, run without any error, and still draw nothing because a condition is never true or a value is na.
- Pine v6 introduced breaking changes from v5, including removal of implicit numeric-to-bool casting and removal of the when parameter from strategy order functions, so v5-shaped AI output reads correctly and fails to compile.
- Pine Script namespaces its built-ins: technical analysis functions under ta, math helpers under math, string helpers under str. A missing namespace is the most common compile failure in generated code.
- plot() must be declared in global scope, so generated code that plots inside an if block will not compile.
- Runtime errors depend on chart data and appear only when the script executes on bars, which is why testing on a single symbol and timeframe proves very little.
- TradingView's default initial capital for a strategy is 1,000,000, and TradingView notes you may need to increase it on certain symbols for trades to occur at all.
- In Pine v6 the default long and short margin percentage is 100 and strategies enforce position-size limits, so generated strategies can silently place fewer orders than expected.
- A higher-timeframe request configured with lookahead enabled can leak future data, producing historical results that cannot occur in realtime.
| Pass | What you are checking | Cost | Catches |
|---|---|---|---|
| 1. Version and namespaces | Read the source | Seconds | v5/v6 drift, missing ta or math |
| 2. Inputs | Read the source | Seconds | Unbounded values, wrong types |
| 3. Compile | Pine Editor | Seconds | Syntax, scope, type errors |
| 4. Conditions fire | Plot or log the boolean | Minutes | Logic that never triggers |
| 5. Repainting | Compare realtime and history | Minutes | Future leak, lookahead misuse |
| 6. Strategy defaults | Strategy Tester settings | Minutes | Capital, sizing, margin suppression |
| 7. Multiple charts | Several symbols/timeframes | Minutes | Runtime and buffer errors |
Read the source before you run it
Two problems are visible without leaving the text, so check them first. Start with the version annotation. If the script does not begin with //@version=6 and you intended v6, everything below it is suspect, because v5 and v6 differ in ways that change both compilation and behavior. Then scan the function calls for namespaces. Generated Pine very often contains sma(close, 20) or rsi(close, 14) without the ta prefix, which is the single most common compile failure in AI output.
Next, look at the inputs. A well-formed script uses the typed input functions, input.int, input.float, input.bool, input.string, and bounds the ones that matter with minval and maxval. This is not stylistic. An unbounded length input allows zero or a negative number to reach a function that requires a positive one, which becomes a runtime error on a specific bar rather than an obvious mistake at write time.
Finally, map requirements to lines. Take the request you actually made and find the code that implements each part of it. If you asked for two configurable lengths and a marker only on crossover bars, point at those four things. Anything present that you did not ask for, an alert, a strategy order, a second indicator, is the model filling in a gap, and unrequested features are where surprises live.
Compile, then make every condition visible
Compilation is a necessary gate and a weak one. It confirms names resolve, types are legal, and scopes are valid. It cannot tell you that a crossover condition never occurs on your dataset, or that a filter you added excludes every bar. Those scripts compile perfectly and do nothing, which is the failure that wastes an evening because there is no error to search for.
So convert each meaningful boolean into something you can see. Plot it as a shape and look for markers across the chart. Where a marker should exist and does not, you have found the problem in minutes rather than by re-reading logic. For values rather than conditions, use log.info() to print the number and the bar index to the Pine Logs pane. This is the single highest-return habit in reviewing generated code.
Be specific about what "it works" means before you look. If you expected markers on roughly a few dozen bars over two years and you see three thousand, the condition is far looser than intended even though it technically fires. If you see none, it is too strict or comparing the wrong things. Both are useful answers, and neither is available from reading the source.
//@version=6
indicator("Verify conditions", overlay = true)
fastLen = input.int(10, "Fast length", minval = 1)
slowLen = input.int(30, "Slow length", minval = 1)
fast = ta.sma(close, fastLen)
slow = ta.sma(close, slowLen)
longSignal = ta.crossover(fast, slow)
plot(fast, "Fast", color.blue)
plot(slow, "Slow", color.orange)
// Make the condition inspectable rather than assumed.
plotshape(longSignal, "Signal", shape.triangleup, location.belowbar)
if barstate.isconfirmed and longSignal
log.info("Signal on bar {0} at close {1}", bar_index, close)Delete the log line before you keep the script, but do not skip adding it. Confirming a condition fires, and roughly how often, is what separates a reviewed script from one you are hoping about.
The repainting check, which matters most
This is the check most likely to be skipped and the one with the largest consequences. A script that reads data it could not have known at the time will show clean historical signals that cannot be reproduced live. Generated code is particularly prone to this, because enabling lookahead on a higher-timeframe request makes historical output look better and a model optimizing for a plausible result has no reason to avoid it.
The practical test is comparison. Note where signals appear on recent historical bars, then watch the current forming bar during live updating and see whether markers appear and disappear as price moves. A marker that vanishes was never a confirmed signal. Separately, inspect any request.security() call and check what it does with lookahead and whether it uses confirmed values.
Also check the more mundane form of the same issue: a condition evaluated on an unconfirmed bar. A signal that is true mid-bar and false at close will look inconsistent in exactly the way that erodes trust in a script. Our repainting guide covers the five distinct kinds and how to prevent each, and it is worth reading before you rely on any generated multi-timeframe code.
For strategies, check the settings before the logic
Generated strategies bring an extra category of problem, because behavior depends on defaults you did not specify. TradingView's default initial capital is 1,000,000, and TradingView notes you may need to raise it further on some symbols for trades to occur. If the model left capital and sizing unspecified, the numbers in the Strategy Tester describe a scenario nobody chose.
Pine v6 adds two more. The default long and short margin percentage is 100 and strategies enforce position-size limits, so a generated strategy can quietly place fewer orders than its logic implies, and positions can be liquidated by margin calls if equity falls far enough. If the trade list is emptier than expected, check these before you touch the entry rule. Our guide on strategies that take no trades walks through the full ordering.
Then verify sizing arithmetically. Pick one trade from the List of Trades and confirm by hand that the quantity matches what the sizing rule should have produced. If quantity is derived from a stop distance, confirm a stop order is actually placed at that distance, because generated code frequently computes size from a stop it never places.
Test on several charts, not one
Runtime errors are data-dependent. Pine reserves a limited historical buffer for each variable, and a request beyond it stops execution with a message about the historical offset exceeding the buffer limit. Whether that happens depends on the symbol, the timeframe, and how much history is available, so a single successful chart tells you almost nothing about robustness.
Use three charts deliberately: a liquid daily chart, an intraday chart, and a symbol with a short trading history. Between them they expose warm-up problems, buffer problems, and assumptions about data availability. Scroll to the earliest bars on each, since that is where indicators have not warmed up and collections are still empty, and check that the script degrades sensibly instead of failing.
Watch for the red exclamation icon beside the script name, which is how TradingView reports a runtime error, and read the bar index it gives you. A plot that stops partway across the chart is the same signal in visual form. Neither appears in the editor, which is precisely why this pass cannot be skipped.
Make the review cheaper next time
Ask for small scripts. A request for two inputs, one calculation, and one output produces something you can fully verify in a few minutes. A request for a complete system produces something you will approve without reading, which defeats the purpose. Build in verified layers: inputs and one calculation, compile, add outputs, compile, add alerts or orders last.
Keep a known-good baseline. Save the version that passed review before requesting the next change, so you always have something to compare against. This is what makes a full-file regeneration survivable: without a baseline, you cannot tell what moved.
And write the acceptance criteria down before you generate. "Two integer inputs with minimums, ta.sma for both, both plots global, marker only on crossover bars, no orders, no alerts" is a checklist you can run in under a minute. Vague intent produces vague review, which is how unverified code ends up on a live chart.
Where the tooling can do part of this for you
Several passes above are mechanical, and mechanical work is what tooling should absorb. Version drift, missing namespaces, and plots in local scope are all detectable from the source, and a workflow that reads its own lint output can resolve them before you ever see the script. That does not replace the judgment passes, conditions firing, repainting, sizing, but it removes the tedious ones.
PineScripter is our product, and it is built around this division of labor. It retrieves the Pine Script v5 and v6 manuals as context while writing, which addresses version drift at the source rather than after the fact. Its in-app lint findings can be routed through an AI correction loop, so structural problems are handled inside the workspace. And its edits are line-level with a Code Changes diff, which keeps the review surface small enough that checking a change is realistic rather than aspirational.
The parts it cannot do are the parts that matter most, and we would rather say so. No tool can confirm that your condition means what you intended, that a higher-timeframe value is honest, or that a risk rule suits your instrument. Runtime behavior depends on chart data, so the Pine Editor stays the final authority. Use tooling to make passes one to three nearly free, and spend your attention on four to seven.
Frequently asked questions
How do I know if AI-generated Pine Script is correct?
Run seven checks: confirm the version annotation and built-in namespaces, confirm inputs are typed and bounded, compile in the Pine Editor, plot or log each condition to confirm it actually fires, test for repainting on any higher-timeframe request, check strategy defaults such as initial capital and margin, and test on several symbols and timeframes to expose runtime errors. Compilation alone only proves the code is structurally valid.
Can Pine Script compile and still be wrong?
Yes, and this is the most common outcome with generated code. Compilation validates structure, not behavior. A script can compile and draw nothing because a condition is never true or a value is na, or it can produce clean historical signals only because a higher-timeframe request is leaking future data.
What is the fastest way to check whether a condition ever triggers?
Plot the boolean as a shape with plotshape() and look for markers across the dataset, and print it with log.info() including the bar index. Decide beforehand roughly how often you expect it to fire: no markers means the condition is too strict or comparing the wrong values, and far too many means it is looser than intended.
How do I check AI-generated Pine Script for repainting?
Note where signals appear on recent historical bars, then watch the current forming bar during live updating to see whether markers appear and disappear as price moves; a marker that vanishes was never confirmed. Separately inspect every request.security() call for lookahead settings and whether it uses confirmed values, because enabling lookahead makes historical output look better while leaking future data.
What should I check first in an AI-generated strategy?
Check the settings before the logic. Confirm the initial capital, order sizing, and margin, since TradingView defaults capital to 1,000,000 and Pine v6 defaults long and short margin to 100 percent while enforcing position-size limits. Those defaults alone can make a strategy place far fewer orders than its entry rules suggest.
Why should I test a generated script on more than one chart?
Runtime errors depend on available data. Pine reserves a limited historical buffer per variable, so a lookback that fits on a daily chart can exceed the buffer on an intraday chart or on a symbol with a short history. Testing a liquid daily chart, an intraday chart, and a short-history symbol exposes most warm-up and buffer problems.
The practical takeaway
Treat generated Pine Script the way you would treat a pull request from someone you do not know well: assume competence, verify anyway, and check the things that fail silently first. The structural passes are cheap and can be automated. The judgment passes, does the condition fire, is the higher-timeframe value honest, does the sizing match the rule, are yours, and they are where the real risk sits.
The mechanical passes are the ones tooling should absorb, which is what we built PineScripter to do: retrieved Pine manuals to prevent version drift at the source, and an in-app lint loop for the structural errors. The judgment passes stay yours.
Sources
- TradingView Pine Script v6 documentation
- TradingView Pine Script documentation: errors overview
- TradingView Help Center: strategy properties
- TradingView Pine Script documentation: other timeframes and data
Related reading: repainting explained, runtime errors on the chart, why a strategy takes no trades, what AI can realistically do for Pine Script.
Disclaimer: PineScripter is a coding tool for Pine Script development. It does not provide financial advice and does not guarantee trading profits. Always backtest strategies thoroughly and understand the risks before live trading.