pine-scriptthinkscript

ThinkScript to PineScript Conversion Question


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!


Solution

  • 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.