WhitmanTrading

How to Write a Pine Script

To write a Pine script, state the rule in plain English first, then declare the script as an indicator or a strategy. Compute each value as a named variable and plot it, so the output can be checked against the chart by eye. Nothing acts until its marks match your reading.

The language is deliberately small, which means the constraint is almost never syntax. It is having a rule specific enough to code, and most scripts that never work were never that.

Before you start

One rule stated in plain English before any code is written. “Mark every bar that closes above the highest close of the previous twenty bars.” If you cannot write that sentence, the script has nothing to express.

A decision about whether you are building an indicator or a strategy, because they are different objects. An indicator draws on the chart; a strategy simulates entries and exits.

A chart you already understand, so the output can be checked by eye. The first test of any script is whether its marks land where you expected on bars you can see.

The steps

1. Write the rule as a sentence, then translate it

Every condition in the sentence becomes one line. If a condition has no clear translation, the sentence was vaguer than it looked, which is worth finding out before coding.

2. Declare the script type on the first line

An indicator can overlay price or sit in its own pane. A strategy carries entries, exits and a simulated account. Converting between them later means rewriting most of the file.

3. Compute your values as named variables

Give every step a name rather than nesting four calls into one line. The compiler does not care and you will, the first time a value comes out wrong.

4. Plot everything, including the intermediates

While developing, plot each computed value. Remove the extra plots at the end. Debugging a script whose internals are invisible is guessing.

5. Check the marks against bars you can see

Scroll to a section you understand and confirm the script marks the bars you would have marked. A script that disagrees with you there disagrees everywhere.

6. Make every condition read a closed bar

A condition evaluated on the current, still-moving bar can be true now and false at the close. That is where repainting comes from, and it makes a backtest describe a history that never happened.

7. Add costs before believing any strategy output

A long-horizon view of a tested rule.
A costless test is not a test. Illustrative chart - not real market data.

Commission and slippage go in the strategy declaration. Say $0.01 a share each way plus a tick of slippage per fill: a rule that trades 200 times a year pays that 400 times, on every entry and every exit.

How to tell it worked

The rule exists as 1 written sentence, and every line of code maps to part of it.

Every condition reads a closed bar, so the script cannot change its marks retrospectively.

The marks match your own reading on at least 20 bars you checked by eye.

And any strategy declaration includes costs, so its output is comparable to a real account.

What the language cannot do for you

It does not know what a good rule is. The compiler will happily accept a rule fitted to one stretch of history, and it produces exactly the same green checkmark as one that generalizes.

Simulated orders always fill. In a thin instrument the price your script transacted at is a price nobody was offering, and the equity curve is built entirely out of those.

The two bugs everyone writes

Reading the current bar. Any condition on a bar still in progress can flip before the close. The chart then redraws its own history, which is why a script can look excellent and produce nothing.

Comparing a value to itself one bar late. Off-by-one on the historical reference is the second most common fault, and it usually looks like a rule that is almost right — signals in the correct places, one bar early or late throughout.

Both are invisible without plotted intermediates, which is the whole argument for step 4.

The original data

Of the 24,971 unique videos in this site’s search study, 272 mention this language in the title, at a median of 543 views across 127 channels, and 63% of those titles are instruction-shaped. Automated trading appears in 27 at 10,749 and trading bots in 93 at 10,655.

272 videos at a 543 median — the lowest of any subject in this entire ranking. Coding a rule has substantial coverage and almost no audience, while the promise of an automated result has a third of the coverage and twenty times the audience per video.

A smooth equity curve is a warning rather than a result. A real price history spends most of its life below its last high: the S&P 500 closed under its record on 93% of days since 1950, and after the October 2007 peak it took until March 2013, about 5.5 years, to close above it again. A simulated curve without that texture is usually describing fills that were never available, costs that were never charged, or a rule fitted to the bars it was tested on.

When it fails

The failure is a script that repaints, and it is convincing right up until it is traded. The historical chart shows the signal at the ideal bar every time, because the condition was evaluated on a bar that had not finished moving. Live, the same script marks a bar and then unmarks it. Nothing in the editor warns about this and the backtest reports it as a success.

The second failure is coding before stating the rule. The code then becomes the search.

A third is nesting everything into one expression. A fault in it has nowhere to be seen.

A fourth is a strategy declared without costs. The result is not comparable to an account.

A fifth is trusting simulated fills in a thin instrument. They were never offered.

And a sixth is fixing a script by adding conditions until the curve improves. That is fitting, and it has no stopping rule.

Pine Script covers the language itself and what it can express. Strategy tester is how the output gets read. And backtesting is the discipline that decides whether the result means anything.

What I actually do

Plot every intermediate value, not just the final signal. When a script does something odd, the fault is almost always three lines before the part you are looking at, and a plotted intermediate makes that visible in one glance instead of an afternoon.

— Michael Whitman

This page is educational, not financial advice. Test every idea on your own charts before risking money.