Trying to learn BarNumber() function in thinkscript? Take a look at some of the notes below—credit to the folks over at the ThinkScript Lounge.
BarNumber Usage
First you must remember that thinkscript runs your script once for each and every bar on your chart, regardless of the aggregation period. So for instance, for daily charts I usually run a 9m D (9 month daily) with 5 expansion bars. TOS counts around 195 bars for this chart, the number varies slightly based on the mix of months on the chart. Typically you'll want to suspend a study's calculation for data in the expansion bars.
So looking at the two subject lines the first is simple enough we create a variable, barNum, that contains the number assigned each individual bar on the chart, 1 thru N. This is done because we want to use barNum in several places in the script without incurring the processing expense of calling the barNumber() function each time.
Code:
******************************************************
def barNum = if(barNumber() * (close > 0)<=barnumber(),barnumber(),double.nan);
************************************************************
# define period to plot
declare lower;
input candlestart = 28;
input candlestop = 14;
# Test if the barnumber has a closing value, if there is, the barnumber is good
# If there is no close value, the candle has not formed yet,
def barNum = if(barNumber() * (close > 0)<=barnumber(),barnumber(),double.nan);
def numBars = HighestAll(barNum);
plot barsWanted = if( (numBars - barNum >= candlestop)
AND (numBars - barNum < candlestart),
high, double.NaN);
barsWanted.SetLineWeight(3);
barsWanted.SetPaintingStrategy(curve.POINTS);
*************** Plot barnumber **********************
def barNumber = barNumber();
#def barCount = HighestAll(if(IsNaN(price), 0, barNumber));
plot bn = barNumber;
bn.setPaintingStrategy(PaintingStrategy.VALUES_BELOW);
If the strategy is omitted a straight line is plotted. With the strategy included
the number of each bar is printed instead of the plot.
##################################
BarNumber() will never be 0
Simplify, simplify, simplify. Here's what is going is going wrong. Labels show the current value of a variable.
Code:
def FormingBar = !IsNaN(open) and IsNaN(open [-1] ) ; # This is 1 if true and 0 is false.
def FormingBarNumber = if barnumber() == [1 or 0] then barNumber() else double.nan ; # BarNumber() will never be 0 and in order for it to be 1 you would need a chart with only 1 bar on the screen.
But more importantly those aren't doing anything at all in the script, why have them? What are you trying to do?
Barnumber() and bn - a function and a variable are different things
Also remember when using both Barnumber() and bn that a function and a variable are different things. Here is something that should show that difference
Code:
declare lower;
def random = Random();
plot
"Function/Function" = Random() / Random();
plot
"Variable/Variable" = random / random;
"Variable/Variable".SetStyle(Curve.Points);
9-21-19 17:22 JohnnyQs_IRA: If anyone is interested.. I put together a little Education Script to assist myself in understanding the Script Function and some general line drawing logic. It is included below..
Code:
## Education: The Script Function Exercise #1 JQ
## OneNote Name:Edu_Script_Ex1_JQ
#Mobius: Scripts must end in a plot as their output. That plot can then be referenced as a global variable.
The objective of ALL ThinkScript is to plot something on a chart. ThinkScript is a chart painting program.
# Drawing a line from Point_A with and without a Script{} sub-routine
# Mobius
# Data Needed: Bar at Condition (bC), Value at Condition (vC), Length of Line (LL)
# User Inputs
input n = 20; #hint n: Length for calculations.
input SdMulti = 2.0; #hint SdMulti: Multiplier for St Dev.
input AtrMulti = 1.5; #hint AtrMulti: Multiplier for ATR.
# Chart Data
def o = open;
def h = high;
def l = low;
def c = close;
def bar = BarNumber();
# Internal Script Reference
script LinePlot
{
input LL = 0; #Line Length
input vC = close; #Value at Condition
input bC = 0; #Bar at Condition
plot line = if HighestAll(bC) - LL <= bC
and bC == highestAll(bC)
then vC
else Double.NaN;
}
# if the highest bar meeting the condition - LineLength is less than Bar at Condition
# and bC == highest bar meeting the condition
# then value at condition
# else double.nan
#> End Script (JQ)
#> BarNumber Plot
plot barNumBelow = bar;
barNumBelow.setpaintingStrategy(paintingStrategy.VALUES_BELOW);
# Variables for example
# Example: First bar of mean value in a squeeze
def Avg = Average(c, n); # c = close n = length
def SD = StDev(c, n); # c = close n = length
def ATR = Average(TrueRange(h, c, l), n); # h = high c = close l = low n = length
plot upperSD = Avg + (SdMulti * SD);
upperSD.setdefaultcolor(color.BLUE);
upperSD.setlineweight(2);
addlabel(1,"upperSD", uppersd.takeValueColor());
# addchartbubble(1, lowestall(low), "SD\n" + upperSD, color.white, no);
plot upperATR = Avg + (AtrMulti * ATR);
upperATR.setdefaultcolor(color.plum);
# addchartbubble(1, lowestall(low), "ATR\n" + upperATR, color.white, no);
upperATR.setlineweight(2);
addlabel(1," upperATR", upperATR.takeValueColor());
addlabel(1," Condition: upperSD crosses below upperATR ", Color.violet);
# Variables for plotting line segment
# bC is the Bar at Condition input to the Script
def bC = if upperSD crosses below upperATR
then bar
else bC[1]; # barnumber where the condition is met
#! assigns bC an initial value of n/a
#! bC retains its bC[1] value until the condition is met
#! if upperSD crosses below upperATR bC takes the current barnumber as its value
#! bC retains that barnumber until the condition is met again if ever
#> addchartbubble(1, lowestall(low), "bC\n" + bC, color.white, no);
# vC is the Value at Condition input to the Script
def vC = if upperSD crosses below upperATR
then Round(Avg / TickSize(), 0) * TickSize()
else vC[1]; # value (y-axis) where the condition is met
#! assigns vC an initial value of n/a
#! vC retains its vC[1] value until the condition is met
#! if upperSD crosses below upperATR vC takes the current Avg rounded to the nearest tick as its value
#! vC retains that value until the condition is met again if ever
#> addchartbubble(1, lowestall(low), "vC\n" + vC, color.white, no);
# LL is then LineLength input to the sctipt
def LL = if bar != bC
then bar - bC
else if bar == bC
then Double.NaN
else LL[1]; # Line Length
input Display_LL_Debug = {default "Hide", "Display"};
addchartbubble(Display_LL_Debug, lowestall(low), "bar\n" + bar, color.white, no);
addchartbubble(Display_LL_Debug, lowestall(low), "bC\n" + bC, color.white, no);
addchartbubble(Display_LL_Debug, lowestall(low), "bar\n!=bC\n" + (bar != bC), color.white, no);
addchartbubble(Display_LL_Debug, lowestall(low), "bar\n-bC\n" + (bar - bC), color.white, no);
addchartbubble(Display_LL_Debug, lowestall(low), "bar\n==bC\n" + (bar == bC), color.white, no);
addchartbubble(Display_LL_Debug, lowestall(low), "LL\n" + LL, color.white, no);
addchartbubble(Display_LL_Debug, lowestall(low), "LL[1]\n" + LL[1], color.white, no);
# Plots
# Method without Script{} for plotting just one line
plot Squeeze_Pivot_1 = if HighestAll(bC) - LL <= bC
and bC == highestAll(bC)
then vC
else Double.NaN;
Squeeze_Pivot_1.SetStyle(Curve.Points);
Squeeze_Pivot_1.setDefaultColor(color.orange);
Squeeze_Pivot_1.setLineWeight(5);
AddLabel(1,"Squeeze_Pivot_1", Squeeze_Pivot_1.takeValueColor());
input Display_SP1_Debug = { default "Hide", "Display"};
addchartbubble(Display_SP1_Debug, lowestall(low), "HAbC\n" + highestall(bC), color.white, no);
addchartbubble(Display_SP1_Debug, lowestall(low), "LL\n" + LL, color.white, no);
addchartbubble(Display_SP1_Debug, lowestall(low), "HAbC\n-LL\n" + (highestall(bC) - ll), color.white, no);
addchartbubble(Display_SP1_Debug, lowestall(low), "bC\n" + bC, color.white, no);
addchartbubble(Display_SP1_Debug, lowestall(low), "bC==\nHAbC\n" + (bC == highestall(bC)), color.white, no);
# Method with Script{} for plotting multiple lines with different conditions
#Note: Since there's only one plot statement in the Script() a plot extension name is not needed.
plot Squeeze_Pivot_2 = LinePlot(vC = vC, LL = LL, bC = bC);
Squeeze_Pivot_2.setDefaultColor(color.cyan);
Squeeze_Pivot_2.SetLineWeight(3);
AddLabel(1,"Squeeze_Pivot_2: script", Squeeze_Pivot_2.takeValueColor());
# End of Code
Last edited by a moderator: