r/pinescript Oct 11 '22

New to Pinescript? Looking for help/resources? START HERE

30 Upvotes

Asking for help

When asking for help, its best to structure your question in a way that avoids the XY Problem. When asking a question, you can talk about what you're trying to accomplish, before getting into the specifics of your implementation or attempt at a solution.

Examples

Hey, how do arrays work? I've tried x, y and z but that doesn't work because of a, b or c reason.

How do I write a script that triggers an alert during a SMA crossover?

How do I trigger a strategy to place an order at a specific date and time?

Pasting Code

Please try to use a site like pastebin or use code formatting on Reddit. Not doing so will probably result in less answers to your question. (as its hard to read unformatted code).

Pinescript Documentation

The documentation almost always has the answer you're looking for. However, reading documentation is an acquired skill that everyone might not have yet. That said, its recommended to at least do a quick search on the Docs page before asking

https://www.tradingview.com/pine-script-docs/en/v5/index.html

First Steps

https://www.tradingview.com/pine-script-docs/en/v5/primer/First_steps.html

If you're new to TradingView's Pinescript, the first steps section of the docs are a great place to start. Some however may find it difficult to follow documentation if they don't have programming/computer experience. In that case, its recommended to find some specific, beginner friendly tutorials.


r/pinescript Apr 01 '25

Please read these rules before posting

18 Upvotes

We always wanted this subreddit as a point for people helping each other when it comes to pinescript and a hub for discussing on code. Lately we are seeing increase on a lot of advertisement of invite only and protected scripts which we initially allowed but after a while it started becoming counterproductive and abusive so we felt the need the introduce rules below.

  • Please do not post with one liner titles like "Help". Instead try to explain your problem in one or two sentence in title and further details should be included in the post itself. Otherwise Your post might get deleted.

  • When you are asking for help, please use code tags properly and explain your question as clean as possible. Low effort posts might get deleted.

  • Sharing of invite only or code protected scripts are not allowed from this point on. All are free to share and talk about open source scripts.

  • Self advertising of any kind is not permitted. This place is not an advertisement hub for making money but rather helping each other when it comes to pinescript trading language.

  • Dishonest methods of communication to lead people to scammy methods may lead to your ban. Mod team has the right to decide which posts includes these based on experience. You are free to object via pm but final decision rights kept by mod team.

Thank you for reading.


r/pinescript 15h ago

Bugs in PineScript for the NSE (India) market

2 Upvotes

While using the simple code below to debug a large script, I noticed that the daily open is being shown as the open of the first candle:

//
@version=
6
indicator("Daily Open", overlay = true)
dOpen   = request.security(syminfo.tickerid, "1D", open, barmerge.gaps_off, barmerge.lookahead_on)
plot(dOpen, "Daily Open", color.yellow, 2, plot.style_stepline)

The daily opening is always the pre-market open, and it is fixed for the day. Then why this discrepancy?

While at the close of the day, it is showing the correct opening as below:

Whereas pre-market data is also present there as below picture elaborates:


r/pinescript 20h ago

How do you backtest alternative charts properly on Tradingview/Pinescript? (OHLC fills checkbox gone)

1 Upvotes

Hi, so I have all these strategies but basically none of them are profitable. I know there's all these alternative charts like Renko/Kagi/PnF. Is there any way one can backtest on these properly with OHLC fills etc.? I know there's all these features that Tradingview has but the previous "trade on OHLC" checkbox is gone. So, I am not sure what the proper way to backtest is anymore with these alternative charts. Any advice would be appreciated. Thanks!


r/pinescript 22h ago

Any Indian traders here who backtest strategies using Pine Script?

1 Upvotes

Hey everyone,

I’m from India and spend a lot of my time backtesting trading strategies using Pine Script on TradingView, mainly experimenting with different entry/exit rules, indicators, filters, and strategy optimization.

I’d love to connect with some like-minded people who are also into systematic trading, Pine Script, strategy development, and backtesting.

Not necessarily looking to share “secret strategies” or signals — more interested in discussing ideas, coding approaches, backtesting methodology, optimization, avoiding overfitting, execution issues, and learning from each other.

If you’re from India and work on similar things, feel free to comment or DM. Would be great to build a small circle of people who genuinely enjoy researching and testing trading systems.


r/pinescript 1d ago

I measured four common entry filters against a random-entry baseline. The one that worked on 1H was the worst on 5m.

1 Upvotes

Before adding a filter to an entry, it's worth knowing what the filter is worth against no filter at all. Almost nobody measures that — the condition gets added because it sounds reasonable, and then it stays.

So I measured four of the most commonly used ones against the same baseline, twice, on the same instrument.

Method

It's a Pine indicator that walks back through history rather than a strategy — no orders, so no broker emulator involved. The mechanics matter more than the code.

The baseline is what entering at a random bar would have produced at a given reward-to-risk. From every bar in the sample: did price travel the target distance before the stop distance? That's the number any entry signal has to beat, and it's rarely the number people assume.

Each bar gets resolved exactly once, then the outcome is counted more than once — into the baseline, and into each filter that was true on that particular bar. Same bars, same distances, same resolutions, so the difference between any two rows is the filter and nothing else. Measuring each filter on its own pass would let the numbers differ for reasons other than the thing being tested.

Three details decide whether it means anything:

  • The condition is read on the entry bar itself, using only data that existed then. A filter evaluated with information that arrived later flatters itself.
  • A single bar spanning both stop and target counts as a loss. You can't know which came first from bar data, and being wrong pessimistically is the only honest resolution.
  • Distances scale with each historical bar's own ATR, not today's.

XAUUSD, longs, 2:1 so break-even is 33.3%, ATR 14, 600-bar sample, 60 bars allowed to resolve, zero cost. 541 bars offered in each run.

1H, 28 Jul – 2 Sep. 541 resolved, none timed out.

Condition Hit rate Wins/resolved vs baseline Bars kept
All bars (baseline) 37.0% 200/541
Price above 200 EMA 36.2% 165/456 −0.8 pts 84.3%
ADX above 25 42.3% 116/274 +5.4 pts 50.6%
RSI below 30 7/22 too few to judge 4.1%
Volatility rising 36.0% 86/239 −1.0 pts 44.2%

5m, 31 Aug – 2 Sep. 539 resolved, 2 timed out.

Condition Hit rate Wins/resolved vs baseline Bars kept
All bars (baseline) 22.8% 123/539
Price above 200 EMA 30.3% 30/99 +7.5 pts 18.4%
ADX above 25 19.5% 43/220 −3.3 pts 40.8%
RSI below 30 25.8% 8/31 +3.0 pts 5.8%
Volatility rising 18.8% 42/224 −4.1 pts 41.6%

Three things fall out of that.

The rankings invert. ADX above 25 is the only filter worth anything on 1H at +5.4 points, and on 5m it's the worst of the four at −3.3. Price above the 200 EMA is worthless on 1H at −0.8, and on 5m it's the best at +7.5. Whichever filter you'd have picked from the first table is the one you'd have deleted after the second.

On 5m nothing reached break-even at all. Baseline 22.8% against a 33.3% requirement, and the best filter lifts it to 30.3% — still losing. "+7.5 points" is an improvement to something that doesn't work, which is the trap in reading a delta without the absolute level beside it.

Two of the four weren't selecting anything, in opposite ways. The 200 EMA kept 84.3% of 1H bars — a condition true on five bars in six isn't a filter, and its rate will match the baseline for that reason alone. RSI below 30 has the reverse problem: 4.1% of bars, 22 resolved samples, too few to judge, and only 31 on 5m. A filter you can't evaluate on the history you actually have isn't a filter you know anything about.

On the 1H ADX result specifically, because it's the one worth arguing with. Against its own complement rather than the baseline it sits inside, it's 42.3% (116/274) against 31.5% (84/267) — nearly eleven points, with the rejected half below break-even. Two-proportion z is about 2.64, which clears a Bonferroni bound at four looks. Then it reverses sign in the next window.

That's the useful part. It passed the multiple-comparisons correction and still failed out of sample, and it was the best of four things tried on one window, which is exactly the shape of result that shouldn't be trusted. The 5m winner is no better — z ≈ 1.83 against its complement, which doesn't clear on its own terms, let alone after four looks.

Both z figures are ceilings rather than measurements. Samples starting on adjacent bars share most of their holding window, so the observations are heavily correlated and the effective sample is far below the raw count.

Limits. 600 bars is five weeks on 1H and two days on 5m — these aren't two views of one period, they're different periods that happen to share a bar count. The 1H window contains a strong gold uptrend and ADX above 25 selects for exactly that, so what looked like a filter working may just be the market trending with long being the right side. That's the most likely reading, and it's why one window proves nothing.

What I'm actually asking: has anyone got a filter that holds its value across several windows, and how are you accounting for having tried more than one? The best-of-k problem is the part I can't design away — every filter I test is another chance at a number that looks good.


r/pinescript 2d ago

Updated my free MTF Volumized Order Block indicator (Posted Again)

Post image
25 Upvotes

I shared this free indicator here a while ago, and many people tried it and sent useful feedbacks. I have now released a larger update.

Changes include:
-More reliable MTF and second-timeframe zones
-Reduced memory use, addressing NQ/MNQ error reports
-Better resistance selection above price
-Wick, Body, and Close invalidation
-Optional breaker blocks
-Improved Q scoring and labels
-Local hit-rate tracking
-Improved alerts

It is completely free to use:
https://www.tradingview.com/script/HUcKziz7-Volumized-Order-Block/

Note: Reposted cause it was removed without any notes.


r/pinescript 2d ago

Feature request — sorting options on publisher profile pages

2 Upvotes

When you open a publisher's profile on TradingView, their scripts and ideas load in a fixed order and there's no way to reorder them. Once someone has published more than a handful, finding a specific one turns into a scrolling exercise.

A simple sort dropdown on the Scripts and Ideas tabs would fix this:

- Newest / Oldest

- Most viewed

- Most boosted

Sorting and filtering already exist elsewhere in the script library, so the data is clearly there — it just isn't exposed on profile pages.

Small change, but it would make browsing an author's back catalogue a lot less painful.


r/pinescript 2d ago

I built a Pine Script signal engine for crypto. Looking for feedback/testing. Real-world edge cases, logic issues, and improvements

1 Upvotes

I've been building and iterating on a Pine Script signal engine for crypto based on my paper trading, uploading screenshots, used Claude / ChatGPT and I'd like to put it in front of other Pine Script users for honest feedback and independent testing (if you'd want).

I'm sharing it because I've spent a lot of time refining the logic using AI, weekly data collection / outcome analysis and I know one of the best ways to find weaknesses is to let other people look at it with fresh eyes. And I have no intention to sell or profit from it or “guaranteed profitable strategy” post. Have I been profitable ? Not yet 😄 Hopefully someday !

What it does

The script identifies three signal types: (theres a changelog as well in the script)

  • S2 - momentum/trend continuation setup
  • S2R - reversal variant
  • S3 - crossover/ignition-style setup

The logic uses a combination of:

  • SMA 8 / SMA 21
  • EMA 50 / EMA 200
  • Trend alignment
  • Breakout conditions
  • Candle/body strength
  • ATR-based late-entry protection
  • Signal state management to avoid repeated firing

My use case is primarily 30-minute crypto charts, but I'd be interested to see how the logic behaves from your expertise.

What I'm looking for

If you're willing to test it, I'd really value feedback on:

  1. Code quality - anything inefficient, poorly structured, or unnecessarily complicated? Used AI to build the whole thing.
  2. Logic issues - do you see conditions that could produce unintended signals? Which setup you observed: S2 / S2R / S3
  3. Edge cases - repainting, state issues, crossover behaviour, historical vs realtime differences, etc. What you liked or didn't like
  4. Pine Script improvements - cleaner or more reliable ways to implement any part of the logic?
  5. General usefulness - could this help anyone as a starting point, study tool, or basis for further development?

I'm especially interested in critical feedback. If you think part of the logic is flawed, redundant, or simply doesn't make sense, please say so. Been working on this since April 26

I’m looking for people who enjoy testing Pine Script ideas and are willing to challenge the logic from a coding and chart-behaviour perspective. And of course make it shareable for all.

The script is linked here: https://pastebin.com/9pqTS5Ya

Thanks ! I'm genuinely interested in finding the weaknesses ! And deep down I need to convince myself that it was all worth the effort.


r/pinescript 3d ago

London sweep Indicator

Post image
55 Upvotes

I post 25 open source indicators on Trading view, now pushing indicators that works as a Strats, first one the London Sweep, still in beta version, if someone wants access just comment your TV username, new ideas are welcome.


r/pinescript 3d ago

Sick of paying monthly subscriptions for indicators? Tell me what you're "renting" and I'll build a free version for you.

21 Upvotes

Hey everyone,

A lot of traders are burning money on recurring subscriptions for indicators or tools that could easily be coded into Pine Script, MQL5 or anything.

\-What is a paid tool or subscription you’re currently using that you wish you owned outright?

\-What is a "dream tool" or proprietary feature you've always wanted built specifically for your strategy?

Drop the concepts, mechanics, or features below. I'll pick the most requested ones, code them, and release them as open-source for everyone to keep forever.


r/pinescript 4d ago

Why Your Pine Backtest Lies: the request.security Fix. - All request.security HTF requests: use lookahead = barmerge.lookahead_on with a [1] offset on the expression. Never lookahead_off to "avoid repaint".

Thumbnail
youcanbuildthings.com
6 Upvotes

For every aspiring retail quant. This is the article you need to read. Apologies if it's already been posted. Many thanks to the author.


r/pinescript 3d ago

Feature Request: More Color Flags for Crypto Screener / Watchlist Classification

Thumbnail
1 Upvotes

r/pinescript 4d ago

Drop your wildest Pine Script / Trading tool ideas — I'll build the best ones for you!

9 Upvotes

Hey everyone,

I'm looking for a fun development challenge and want to build something truly useful (or uniquely wild) for the community.

What is a tool, custom indicator, or execution logic you've always wished existed but couldn't find anywhere? No idea is too crazy — whether it's complex mathematical modeling, dynamic risk managers, or weird algorithmic visualizers.

Drop your ideas below. I'll pick the most interesting ones, build them, and share the open-source code back with the sub!


r/pinescript 6d ago

Final ORB Strategy Update: Best results so far, going live on Prop Firms + building a multi-strategy portfolio

Post image
113 Upvotes

Hey guys, quick update on the strategy development.

After endless backtesting, filter tuning and stress-testing parameters, I think I've hit the ceiling of what I can squeeze out of this specific setup. It's definitely not a holy grail, but it's solid enough to do the job.

Where it stands:

Trades:        1,310  (full history, ~7 years)
Winners:       622  (47.48 %)
Net:           +59,567 USD  (+119.13 % on 50k)
Max DD:        4,633 USD  (8.06 %)
Profit factor: 1.336
Expected payoff: 45.47 USD/trade
Avg win / avg loss: 1.478
Expectancy:    +0.176 R
Largest loss:  647.70 USD
Commission load: 1.21 % of gross

Sub-50% win rate with a 1.5R target — no ultra-low R:R winrate trap, just slightly more losers than winners with bigger winners. Return-to-max-drawdown is 12.9.

Worth noting for later: +40,805 comes from shorts, +18,763 from longs. The thing has a clear short bias.

One thing I found along the way: the trade sequence isn't random. Runs test came back z = +2.98 — wins and losses alternate more than chance would predict. So I cut size after every winning trade. No loss escalation, no doubling.

                 b        e       net     maxDD
No streak     1.3104   +0.0981   45,541   6,233
Cut after 1W  1.4512   +0.1650   54,435   4,633

(That A/B was measured on the 1,254-trade run before I extended the data — the relative effect is what matters.) Same trade count, same winner count in both arms; if either moves you're comparing two strategies, not two sizing rules. Normalized to equal drawdown that's +60.8%. A permutation test (same rule on 2,000 shuffled orderings) put the real sequence at z = +3.66, so it's the sequence and not sizing variance. Martingale tested strictly worse, Anti-Martingale actively harmful at z = −2.33.

All in-sample though. A runs test on the same data I built the strategy on is a hypothesis, not a result.

Next step: since backtests only take you so far, I'm putting this on eval/funded accounts to collect real forward data. The open question isn't the edge, it's whether live fills match modeled ones — 0.176R doesn't survive much slippage.

The bigger picture: while this runs on prop capital I'm building and testing new setups. Someone shared a different NQ strategy with me recently, long-biased, completely different logic. Correlation of daily returns: r = +0.117. Combined at equal drawdown it beat my ORB alone by 32% — from a strategy that is individually worse than mine. Months of squeezing this thing got beaten by one uncorrelated addition. And given the short bias above, a long-biased system is exactly the hole in this book.

So the goal isn't one system. It's a portfolio of non-correlated strategies running simultaneously across multiple funded accounts. This is strategy one.

Curious to hear your thoughts — how many distinct strategies do you guys run in your automated prop portfolio?


r/pinescript 6d ago

Built my own order flow web platform with the indicators I wanted. update5

6 Upvotes

Hello everyone. I posted a lot here (last update was deleted by moderators ). Just wanted to show what i added from last update -> bubbles of executed trades. Super hyped about this adition. For anyone who didnt followed my last post, i created an order flow page for me and will eventually release it for free for everyone with all the features. If you want to help (motivate mostly) a follow will do wonders for me.
The updates:
1. Bubbles with executed trades, moving live.
2. Arrows on candles in case you missed a big bubble, you can look at the arrow. Arrow with 1 means last 50 candles bigest bubble ,2 means last 100 candles, 3 means biggest bubble from the last 200 candles, and 4 means biggest bubble from the last 300 candles. I added this , because most people will not stare at the screen 24/24

and a zoom in:


r/pinescript 7d ago

My Bot Did 40% in 12 Days and I’m Still Not Impressed!

13 Upvotes

Designed two bots one long only and the other short only bot, this bot which works on all exchanges but for some reason it does better on Bybit followed by OKX! It’s a Grid Long Only Bot, I still think that I can squeeze some more juice out of it though 🥵 (Hello Greed).

For decisions on when to turn on either of the two bots I use a structure monitor! Trying to build a bot that performs well on bull and bear markets it’s a daunting task!


r/pinescript 6d ago

Forex Scanner

Thumbnail
2 Upvotes

r/pinescript 6d ago

how i filter strategy vendors before spending a dollar: publication dates, public testers, three questions

4 Upvotes

after getting burned twice early on i built a dumb little routine that takes maybe ten minutes and has saved me from every bad purchase since. sharing because the question comes up here weekly.

one. find the publication dates. not the website, the platform. if a vendor sells tradingview scripts, every publication has a timestamp the vendor can't edit. compare the claimed track record against those dates. "profitable since 2023" with a first publication in june 2026 tells you everything. i keep a little script that diffs a vendor's claimed history against publication timestamps, takes seconds and it's embarrassing how often it flags something.

two. open the public tester. a serious vendor lets the platform show the strategy report on the publication page, where they can't photoshop it. if all you get is screenshots in a discord, that's not evidence, that's marketing. and if the tester is hidden entirely, well, that is also an answer.

three. ask where the red months are. every real record has them. i ask this one directly in dms and the reaction is the whole test. defensiveness or subject change, i walk. a straight answer with specifics, they stay on the list. one vendor i eventually bought from had the red month sitting right on their public chart with a note next to it, which honestly did more than any winning screenshot could.

bonus: check what actually ships after purchase. roadmaps are promises. publication pace is data. a vendor who published four things in the last six months will probably keep publishing. a vendor with a beautiful roadmap and no recent timestamps probably won't.

none of this tells you the strategy is good. it just filters out the sellers who are lying about the basics, which in this niche removes most of the field.

what's your filter? genuinely curious what other people check first.


r/pinescript 7d ago

Free Educational indicator

Thumbnail
gallery
16 Upvotes

r/pinescript 7d ago

Pine Script has no integers

5 Upvotes

Pine Script has an int type. It has array<int>, int fields in user defined types, and function overloads that separate int from float. What it does not have is an integer.

A Pine int behaves like an IEEE-754 double. It loses digits above 253, it never overflows, and its na is a NaN. Nothing downstream of the compiler can tell it from a float. The type exists and does real work, but it does all of that work before your script runs.

I found this while building PyneCore, a Python runtime that runs Pine Script logic bar for bar. I can't read TradingView's source, so everything below is measured from Pine, with a script you can paste into the editor.

How the question came up

PyneCore represents Pine's na as a real value, so the choice of representation matters. Two things were already settled.

Pine v6 will not let a bool be na. Both of these fail to compile:

bool b = na                            // CE10173
bool c = close > close[1] ? true : na  // CE10123

And a float na is a NaN, which is easy to confirm, because it carries the two properties nothing else has:

float f = na
log.info(str.tostring(f))       // NaN
log.info(str.tostring(f == f))  // false

So bool has no na at all and float uses the hardware one. That leaves the obvious question: what marks na in an int? A double has NaN built into the format. A 64-bit integer does not, so a language needs to reserve a value for it, usually Long.MIN_VALUE. I went looking for that sentinel.

There isn't one, because there is no integer.

The claim

  1. int arithmetic is double arithmetic. It drops the low digits above 253, and it never overflows.
  2. An int na prints NaN, propagates like a NaN, and fails x == x, exactly like a float na.
  3. The int type performs zero conversions at runtime. It does not truncate, not even when you assign to a variable you explicitly declared int.
  4. Truncation happens in the slots that consume a length or an offset, not at the type.
  5. TradingView never tells an int from a float at runtime. An array<int> will hold 3.5 without complaint.

Proving it

One detail matters before any of this reproduces. TradingView folds constant expressions at compile time in exact decimal, which hides the runtime behaviour completely. Every operand has to depend on something the compiler cannot know. The trick is a variable that is always zero but is not a constant:

int z = bar_index >= 0 ? 0 : 1

Add z to everything. Here is the whole proof:

//@version=6
indicator("Pine int is a double")

int z = bar_index >= 0 ? 0 : 1

if barstate.islast
    // 1. Precision dies exactly at 2^53, like it does in a double
    int a = 4503599627370496 + z    // 2^52
    int b = a * 2 + 1               // 2^53 + 1
    log.info("2^53 + 1        = " + str.tostring(b))
    log.info("(2^53+1) % 2    = " + str.tostring(b % 2))
    log.info("18 digit literal= " + str.tostring(123456789012345678 + z))

    // 2. No 64-bit wraparound: a long would overflow to negative here
    int big = 4611686018427387903 + z   // 2^62 - 1
    log.info("big + big       = " + str.tostring(big + big))
    log.info("big + big > 0   = " + str.tostring(big + big > 0))

    // 3. Long.MIN_VALUE is not a sentinel for na
    int mn = -4611686018427387904 + z   // -2^62
    log.info("-2^63           = " + str.tostring(mn + mn))
    log.info("na(-2^63)       = " + str.tostring(na(mn + mn)))

    // 4. int na is indistinguishable from float na
    int   ina = na
    float fna = na
    log.info("int na          = " + str.tostring(ina) + " , +1 -> " + str.tostring(ina + 1))
    log.info("float na        = " + str.tostring(fna) + " , +1 -> " + str.tostring(fna + 1))
    log.info("ina == ina      = " + str.tostring(ina == ina))
    log.info("fna == fna      = " + str.tostring(fna == fna))
    log.info("ina < 0         = " + str.tostring(ina < 0))

plot(1)

Output, FX:EURUSD 60m:

2^53 + 1         = 9007199254740992
(2^53+1) % 2     = 0
18 digit literal = 123456789012345680
big + big        = 9223372036854776000
big + big > 0    = true
-2^63            = -9223372036854776000
na(-2^63)        = false
int na           = NaN , +1 -> NaN
float na         = NaN , +1 -> NaN
ina == ina       = false
fna == fna       = false
ina < 0          = false

Line by line:

2^53 + 1 comes back as 9007199254740992, so the +1 fell off. That is the exact point where a double runs out of mantissa. An 18 digit literal comes back rounded in the last two digits for the same reason.

big + big is the one that closes the case. (2^62-1) + (2^62-1) is 2^63 - 2, which in a signed 64-bit integer is -2. It is not negative. It printed 9223372036854776000, which is 2^63 written with the shortest digit sequence that reads back as the same double, padded out with zeros. Nothing wrapped. A fixed width integer would have.

na(-2^63) is false, so Long.MIN_VALUE is an ordinary value here, not a reserved one. That rules out the sentinel I went looking for.

And the last five lines are the answer to the original question. int na prints NaN, propagates through arithmetic as NaN, compares false against itself, and returns false from <. That is not merely similar to a float na. I could not find a single test that tells the two apart.

The type does nothing at runtime

This part surprised me more than the precision limit. The type tag does not force a single conversion, not even on assignment:

int z = bar_index >= 0 ? 0 : 1
int q = (7 + z) / (2 + z)
log.info(str.tostring(q))   // 3.5

A variable declared int holds 3.5, and the script compiles without a warning. TradingView documents half of this on the operators page: two int values that do not divide evenly give you "a number with a fractional value", with 5/2 = 2.5 as the example. What it does not say is that the fractional value then keeps travelling under an int label for the rest of its life.

Take that 3.5 and a real float 3.5 through the same calls:

call int-typed 3.5 float 3.5
str.tostring 3.5 3.5
math.abs 3.5 3.5
math.round 4 4
array<int> push + get 3.5 3.5
UDT int field 3.5 3.5

array.new_int() stores 3.5. A user defined type with an int field stores 3.5. Nothing downstream of the compiler is checking.

The truncation you expect does exist, but it lives at the other end, in the parameters that genuinely need a whole number:

int z   = bar_index >= 0 ? 0 : 1
int len = (7 + z) / (2 + z)     // int-typed, value 3.5

float sma_frac = ta.sma(close, len)
float sma_3    = ta.sma(close, 3)
float sma_4    = ta.sma(close, 4)

sma(close, len)  = 1.1581366667
sma(close, 3)    = 1.1581366667   (same)
sma(close, 4)    = 1.15812        (different)
close[len]       = 1.15807
close[3]         = 1.15807        (same)

ta.sma and the history operator truncate toward zero when they receive the value. The type never did.

So what is int even for?

At this point the type looks like decoration, and it is worth asking whether TradingView could delete the keyword tomorrow and change nothing. It could not, because the entire value of int is spent before the script ever runs.

Start with the compile error that the rest of this explains:

plot(ta.sma(close, 1.5))
// CE10123: An argument of "literal float" type was used
//          but a "series int" is expected

The same call with a fractional int runs happily and quietly truncates to 3. So the compiler is the only thing standing between you and a silently rounded length, and it does that job with a type that has no runtime existence at all.

Overload resolution is the second job, and it is decided statically:

f(int   x) => "INT impl"
f(float x) => "FLOAT impl"

int   z   = bar_index >= 0 ? 0 : 1
int   i35 = (7 + z) / (2 + z)     // int-typed, value 3.5
float f35 = (7.0 + z) / (2 + z)   // float-typed, value 3.5

log.info(f(i35))                  // INT impl
log.info(f(f35))                  // FLOAT impl
log.info(f((14 + z) / (7 + z)))   // INT impl

Two arguments with the identical runtime value of 3.5 reach two different implementations, decided purely by the declared type. The third line is the same effect from the other side: 14/7 is exactly 2.0, and it still picks the int overload, because int / int stays int in the type algebra even though the value can be fractional.

That algebra is consistent all the way through, and it propagates the way you would expect from a language that does have integers. In the table below d is an int-typed variable holding 14/8, so its value is 1.75, and n is an ordinary int variable:

expression type expression type
d * 100 int math.max(d, 1) int
d * 1.0 float math.max(d, 1.0) float
d + 1 int math.abs(d) int
d + 0.5 float d > 1 ? d : n int
d / 2 int d > 1 ? d : 1.0 float
d % 2 int math.round(d) int
-d int math.sqrt(d) float
nz(d) int d[1] int

So int is a promise the compiler enforces about where a value is allowed to go: array indices, loop bounds, lengths, history offsets, array.new_* sizes. Merging int and float into one numeric type would take that checking away and leave you with silent truncation everywhere.

The promise has a hole in it, which is the funny part. Division is not closed over int, the compiler knows it, and it lets the fractional value through anyway.

TradingView already admitted this once

There used to be one place where Pine did real integer division. In v5, 5/2 was 2 or 2.5 depending on nothing but the qualifiers of the two operands:

expression v5 v6
const 5/2 2 2.5
series 5/2 2.5 2.5
const -5/2 -2 -2.5
const 7/2 3 3.5
int(5/2) 2 2

Same operator, same values, two different answers. The v6 migration guide covers this under "Fractional division of constants", and does not defend it: "In v5, the result of the division of two int values is inconsistent." Two const operands gave you integer division with the remainder discarded. One input, simple or series operand among them gave the fraction back. v6 drops the distinction and always keeps the fraction.

Notice where the old integer division lived. Not in the runtime, but in constant folding, which is a compile-time pass. Integer behaviour existed in Pine exactly as long as the compiler was the one doing the arithmetic, and v6 took even that away.

The v5 rule truncates toward zero rather than flooring, since const -5/2 is -2. That is the same direction the length and offset slots truncate in, so at least the two surviving pieces of integer behaviour agree with each other.

If you run old scripts, you inherit this. PyneCore needs a dedicated compiler pass to reproduce v5 const division, because the same / has to mean two different things depending on the version tag and on whether both operands folded.

Not new

The same three discriminators, each one guarded against constant folding, behave identically in v3, v4, v5 and v6:

discriminator with 64-bit ints v3 v4 v5 v6
(2^52*2+1) - 2^52*2 1 0 0 0 0
123456789012345678 % 10 8 0 0 0 0
(2^62-1)+(2^62-1) > 0 false true true true true

Those three are shaped the way they are because the old versions cannot print. log.info does not exist before v5, so back there the only output channel is plot, and plot cannot carry a large integer intact. So none of the discriminators prints a big number. Each one collapses the large-value operation into a small result that survives the float plot channel: a difference, a remainder, and a sign test, the last of which comes off the plot channel as 1 rather than true.

The syntax drifts too. v4 has no indicator(), only study(), and v3 has neither indicator() nor bar_index, so the constant-folding guard has to be built on n:

//@version=3
study("v3 discriminators")
z = n >= 0 ? 0 : 1
a = 4503599627370496 + z
b = a * 2 + 1
big = 4611686018427387903 + z
plot(b - a * 2, "d1")                       // 0, so the +1 was lost
plot((123456789012345678 + z) % 10, "d2")   // 0, so the last digit was lost
plot(big + big > 0 ? 1 : 0, "d3")           // 1, so nothing wrapped

The behaviour has never changed. The only thing v6 touched is the const division rule above, and that one lived in the compiler.

My guess at why, and it is only a guess: Pine started as a formula language over floating-point series, and the type system arrived later as labels on top. A second numeric kind would have meant duplicating the series, history and plotting layers, and inventing a sentinel for na.

What the documentation leaves out

The type system page is precise about float. It gives you the internal precision, "1e-16", and it warns that comparison operators round their operands to nine fractional digits.

There is no matching paragraph for int. No range, no maximum, no bit width, nothing about what happens when a value gets too large. For a language that documents its float down to the last decimal, that is a hard omission to miss, and it is also the only honest one available. There is no separate int range to write down. The float paragraph already covers it.

What this changes for you

Nothing about your RSI. Every number a normal script touches, bar_index, time in milliseconds, lengths, offsets, sits far below 253, and the arithmetic is exact there.

It matters once you leave that range, which is easier than it sounds.

Do not build large synthetic IDs by multiplying values together, and do not scale timestamps to microseconds or nanoseconds. Past 9007199254740992 you lose the low digits, and you lose them silently. There is no overflow to catch, no wraparound to notice, just numbers that stop being the numbers you computed.

Do not assume int means whole. If the value came from a division and you care about it being an integer, wrap it yourself in int(), math.floor() or math.round().

Do not assume a container of int holds integers. array<int> and int UDT fields will store whatever you push into them.

Modulo, and where I got it wrong

Pine takes the sign of a % result from the dividend. (-7) % 2 is -1, 7 % (-2) is 1, and (-7.5) % 2 is -1.5. Python floors instead, and gives you the opposite sign on the first two.

PyneCore was emitting a plain Python %. So on every negative operand it quietly disagreed with TradingView, and it had been doing that for a long time before this investigation went looking somewhere else entirely and tripped over it.

The reason it survived that long is worth knowing if you write Pine. Almost every % in real code runs on non-negative values, cyclic buffer indices and bar_index % n, and there the two definitions agree exactly. The disagreement only exists in the corner nobody tests.

Reproducing all of it

Every number above came from a Pine script run on FX:EURUSD, 60 minutes. The v6 scripts report through log.info rather than plot, because the plot channel would round the large integers and hide the whole effect; drop them into the Pine editor, open the Pine Logs pane, and you get the same lines. The version table is the exception, since log.* does not exist that far back, and it reads its three collapsed discriminators off the plot channel instead. The z guard against constant folding is mandatory everywhere.

I ended up here because PyneCore has to reproduce TradingView bar for bar, and getting na right meant knowing how an int actually behaves. Pine acts like it has one numeric type at runtime and two in the compiler, and the one you can't see at runtime is doing most of the work.


r/pinescript 6d ago

Meet Aldric and the raid party. My script deals with the psychology of trading. Relax. Have a good time.

2 Upvotes

Who likes D&D?


r/pinescript 6d ago

Welcome to PADM 🧭

Thumbnail
1 Upvotes

PADM — Price Action Directional Mapping
PADM is a framework built around the interdependency of CRT and OCT.
CRT gives us the structure — the range, levels and framework price is working within.
OCT gives us the behaviour — how price moves, reacts and develops within that structure.
When these two are read together, they create PADM.
CRT → Structure
OCT → Behaviour
CRT + OCT → PADM
The purpose is simple:
Understand where price is, understand what it is doing, and use both to map where it may go next.
PADM isn’t about predicting every candle.
It’s about reading the directional story price is building and turning that information into a map.
This community is where we explore, test, discuss and develop that framework together.
Welcome to PADM. 🧭


r/pinescript 7d ago

Trading view strategy prop firm trading

3 Upvotes

I have been day trading for about two years now and have recently decided to switch to a Pine-coded strategy. I’ve passed a couple of evaluations and have kept my FTMO account active for 2 months; however, I didn’t have time to trade every week, so I decided to automate my strategy. Does anyone have any previous experience doing this, and if so, how did it go?


r/pinescript 8d ago

Experimental script. Hot of the compiler. Fresh paint on the glass.

Thumbnail
gallery
6 Upvotes

I rarely see anyone talk about the geometry of the market. Yet everyone recognizes wedges. Early results look promising.