I am working on converting a ThinkScript indicator into PineScript. I am currently having problems with converting ThinkScript's barNumber() function to PineScript. I think I know what to use as its equivalent but I am not sure I understand the barNumber() even after reading the documentation and examples.
This indicator is basically used as an entry/exit indicator. I think what the code is doing by utilizing the barNumber() is removing the signal if a new signal is plotted, but if that new signal is invalidated then it reverts to the previous signal.
Here is the part of code I am confused with the first few defs have more meat behind them just it is irrelevant to explain them they should all return as floats (def stateUp through def linDev):
def bar = barNumber();
def stateUp;
def stateDn;
def atrCCI;
def price;
def linDev;
def CCI = if linDev == 0
then 0
else (price - avg(price, length)) / linDev / 0.05;
def MT1 = if CCI > 0
then max(MT1[1], hl2 - ATRCCI)
else (min(MT1[1], hl2 + ATRCCI)
def state = if close > ST and close > MT1 then StateUp
else if close < ST and close < MT1 then StateDn
else State[1];
def newState = HighestAll(if state <> state[1] then bar else 0);
The code uses a lot of conditional statements, here are some of the other usages for this code:
CSA = if bar >= newState then MT1 else Double.NaN;
signal = if bar >= newState and state == stateUp and. . .
Is there an easy way to approach this in PineScript?
Thank you for the help!
The equivalent for thinkScript's BarNumber() is Pine-Script's bar_index.
thinkScript and Pine-Script both use a loop that represents the trading period range in effect. The BarNumber/bar_index value represents each measurement period that is being calculated through the loop.
To compare this to other types of coding, you might consider something like for bar_index in 0 to 10
for a trading period of 10 days, where bar_index
would count from 0 through 9 (ie, it acts like the stereotypical i
in a for
loop).
The period the index represents could be a day, minute, tick, etc - whatever you set for your chart or calculations. And, note: *a "day" represents a "trading day", not a "calendar day".
A confusing issue is: where do the bars start counting? The BarNumber() or bar_index starts at the earliest period of your time frame and counts up toward the most recent trading period of your time frame. Eg, the bar_index of 0 might represent 10 days ago, while the bar_index of 9 might represent today.
Here's some example code from the Kodify site (which provides Pine-Script tutorials):
//@version=4
study("Example of bar_index variable", overlay=true)
// Make a new label once
var label myLabel = label.new(x=bar_index, y=high + tr,
textcolor=color.white, color=color.blue)
// On the last bar, show the chart's bar count
if (barstate.islast)
// Set the label content
label.set_text(id=myLabel, text="Bars on\nthe chart:\n" +
tostring(bar_index + 1))
// Update the label's location
label.set_x(id=myLabel, x=bar_index)
label.set_y(id=myLabel, y=high + tr)
Note the tostring(bar_index + 1))
. They're adding one because, remember, the index is zero-based, so an index that counts 0 to 9 is actually counting 10 bars.
I think the reason the BarNumber()/bar_index concept is confusing is because we also consider values the other way. For example, if we're comparing close
to close[1]
, that is the current period's close
value compared to the previous period's close
value (close[1]
). That's opposite of the bar numbers! close[1]
would actually have a lower bar number/index because it's from the period before close
.
When we use something like close[1]
, the script is actually counting from the right to the left (most recent to earlier periods) - opposite of the BarNumber()/bar_index concept.