Average volume for First bar of the Day

apaul015

New member
I'm trying to create a code where you can input a "X" number of days, and I can get the average Volume of the First bar for those "X" days.
For example, I want to get the average Volume of the first Bar for the last 5 days, beginning with yesterday.

I feel like this should be pretty simple, but I can't seem to get the code right. Any help would be appreciated!
 
Solution
@apaul015
That took a minute.
Had to figure out how to define a moving range.
Averages first bar of day volume for past X number of prior days at the opening bar of every day.
The first X number of days on a chart will be blank as there isn't enough data until the day after X number of days.
ilKCM7K.png

Ruby:
#Averages first bar of day volume for past X number of prior days at the opening bar of every day.
#Svanoy

input Number_Of_Signals_To_Be_Averaged = 5;
input Value_To_Be_Averaged = volume;
input Time_Of_First_Bar_Of_Day = 0930;

def NotToday = GetDay() <> GetLastDay();
def BarToBeAveraged = (secondsFromTime(Time_Of_First_Bar_Of_Day)==0) and NotToday;
def SignalBar = (secondsFromTime(Time_Of_First_Bar_Of_Day)==0);
def...
Apologies for reviving a solved thread.
I would like to average the volume of the first 6 bars for an ORB strategy but am having trouble modifying Savnoy's code. Would anyone be willing to take a stab at it while I continue attempting?
 
@Jonessw1
I'm assuming you want to use the total volume for the first 6 bars of the day instead of just the first bars volume.
Ruby:
#Modification request
#Averages total volume for first 6 bars of day of past X number of prior days at the opening bar of every day.
#Svanoy

input Number_Of_Signals_To_Be_Averaged = 5;
input Number_Of_Bars_To_Total_Per_Day = 6;
input Value_To_Be_Averaged = volume;
input Time_Of_First_Bar_Of_Day = 0930;

def NotToday = GetDay() <> GetLastDay();
def BarCounter = if secondsFromTime(Time_Of_First_Bar_Of_Day)==0 then 1
                 else if BarCounter[1] == Number_Of_Bars_To_Total_Per_Day or BarCounter[1] == 0 then 0
                 else BarCounter[1] + 1;
def RangeTotalVolume= if BarCounter == 1 then Value_To_Be_Averaged
                      else if (BarCounter and Barcounter <= Number_Of_Bars_To_Total_Per_Day ) then RangeTotalVolume[1] + Value_To_Be_Averaged
                      else double.nan;
def SignalBar = BarCounter == Number_Of_Bars_To_Total_Per_Day;
def BarToBeAveraged = BarCounter == Number_Of_Bars_To_Total_Per_Day and NotToday;
def TotalSignalCount = if BarToBeAveraged then TotalSignalCount[1] + 1 else TotalSignalCount[1];

def bar = BarNumber();
def BarNum = if !IsNaN(close) and BarNumber()>0 then bar else BarNum[1];
def VBar = HighestAll(BarNum);

def SignalRangeTotal;
if BarNumber() == 0 {
    SignalRangeTotal = 0;
} else if BarToBeAveraged  {
    SignalRangeTotal = SignalRangeTotal[1] + RangeTotalVolume;
} else {
    SignalRangeTotal = SignalRangeTotal[1];
}

def TotalToBeRemoved = fold i = 0 to VBar while ((TotalSignalCount - GetValue(TotalSignalCount,i)) <= Number_Of_Signals_To_Be_Averaged) and TotalSignalCount > Number_Of_Signals_To_Be_Averaged do if BarToBeAveraged then TotalToBeRemoved[1] + GetValue(RangeTotalVolume,i) else TotalToBeRemoved[1];

def RangeAverage = if SignalBar then ((SignalRangeTotal[1]-TotalToBeRemoved[1]) / Number_Of_Signals_To_Be_Averaged) else Double.NaN;

AddChartBubble(SignalBar and TotalSignalCount >= Number_Of_Signals_To_Be_Averaged and NotToday,high,"Total Signals: "+TotalSignalCount,color.white);
AddChartBubble(SignalBar and TotalSignalCount >= Number_Of_Signals_To_Be_Averaged and NotToday,high,"Cumulative Avg: "+SignalRangeTotal,color.light_green);
AddChartBubble(SignalBar and TotalSignalCount >= Number_Of_Signals_To_Be_Averaged ,high,"Average of" + "\n" + "Total Volume for First 6 Bars" + "\n" + "of Last "+Number_Of_Signals_To_Be_Averaged+" Days. Starting Yesterday: "+rangeaverage,color.light_red);
 
Exactly! Thank you for this.

Code:
def BarCounter = if secondsFromTime(Time_Of_First_Bar_Of_Day)==0 then 1
                 else if BarCounter[1] == Number_Of_Bars_To_Total_Per_Day or BarCounter[1] == 0 then 0
                 else BarCounter[1] + 1;
def RangeTotalVolume= if BarCounter == 1 then Value_To_Be_Averaged
                      else if (BarCounter and Barcounter <= Number_Of_Bars_To_Total_Per_Day ) then RangeTotalVolume[1] + Value_To_Be_Averaged
                      else double.nan;

I will now try to make some useful plots.
 
@apaul015 - I am new to trading, can you explain what you are trying to capture using this code @Svanoy wrote ? trying to learn
@rcheltap

For this, I was mainly trying to explore different ways of calculating relative volume. The idea behind it is that stocks with high relative volume tend to give me the moves I'm looking for intraday, and the first 15 minutes of the day is when the most volume is typically done. If the volume during this period is significantly higher than what was normal, then there may be an opportunity for a trade depending on how the price action looks. Not using this as a signal to get long or short, but as a check in favor for my overall thesis on the stock.
 
@Jonessw1
I'm assuming you want to use the total volume for the first 6 bars of the day instead of just the first bars volume.
Ruby:
#Modification request
#Averages total volume for first 6 bars of day of past X number of prior days at the opening bar of every day.
#Svanoy

input Number_Of_Signals_To_Be_Averaged = 5;
input Number_Of_Bars_To_Total_Per_Day = 6;
input Value_To_Be_Averaged = volume;
input Time_Of_First_Bar_Of_Day = 0930;

def NotToday = GetDay() <> GetLastDay();
def BarCounter = if secondsFromTime(Time_Of_First_Bar_Of_Day)==0 then 1
                 else if BarCounter[1] == Number_Of_Bars_To_Total_Per_Day or BarCounter[1] == 0 then 0
                 else BarCounter[1] + 1;
def RangeTotalVolume= if BarCounter == 1 then Value_To_Be_Averaged
                      else if (BarCounter and Barcounter <= Number_Of_Bars_To_Total_Per_Day ) then RangeTotalVolume[1] + Value_To_Be_Averaged
                      else double.nan;
def SignalBar = BarCounter == Number_Of_Bars_To_Total_Per_Day;
def BarToBeAveraged = BarCounter == Number_Of_Bars_To_Total_Per_Day and NotToday;
def TotalSignalCount = if BarToBeAveraged then TotalSignalCount[1] + 1 else TotalSignalCount[1];

def bar = BarNumber();
def BarNum = if !IsNaN(close) and BarNumber()>0 then bar else BarNum[1];
def VBar = HighestAll(BarNum);

def SignalRangeTotal;
if BarNumber() == 0 {
    SignalRangeTotal = 0;
} else if BarToBeAveraged  {
    SignalRangeTotal = SignalRangeTotal[1] + RangeTotalVolume;
} else {
    SignalRangeTotal = SignalRangeTotal[1];
}

def TotalToBeRemoved = fold i = 0 to VBar while ((TotalSignalCount - GetValue(TotalSignalCount,i)) <= Number_Of_Signals_To_Be_Averaged) and TotalSignalCount > Number_Of_Signals_To_Be_Averaged do if BarToBeAveraged then TotalToBeRemoved[1] + GetValue(RangeTotalVolume,i) else TotalToBeRemoved[1];

def RangeAverage = if SignalBar then ((SignalRangeTotal[1]-TotalToBeRemoved[1]) / Number_Of_Signals_To_Be_Averaged) else Double.NaN;

AddChartBubble(SignalBar and TotalSignalCount >= Number_Of_Signals_To_Be_Averaged and NotToday,high,"Total Signals: "+TotalSignalCount,color.white);
AddChartBubble(SignalBar and TotalSignalCount >= Number_Of_Signals_To_Be_Averaged and NotToday,high,"Cumulative Avg: "+SignalRangeTotal,color.light_green);
AddChartBubble(SignalBar and TotalSignalCount >= Number_Of_Signals_To_Be_Averaged ,high,"Average of" + "\n" + "Total Volume for First 6 Bars" + "\n" + "of Last "+Number_Of_Signals_To_Be_Averaged+" Days. Starting Yesterday: "+rangeaverage,color.light_red);
Hi @Svanoy Great code! I'm wondering what syntax would need to be changed in order to convert this to an intraday study? So instead of calculating against the first 6 bars of x days prior, just focus on the first 6 bars (1m agg) of the day and then base the rvol calculation off that throughout the session. Subsequently, Rvol thresholds could be defined against the avg vol of those first 6 bars combined.

Thanks!

H
 
Hoping to revive this old thread. I am looking for something very similar to this however I am trying to have it compare the volume of the past x days at the current time. For example if its 30 min after open, compare the average volume of the last x days at 30 mins after open. Some thing if its 2 hours after open, it would automatically compare the las x day at 2 hours after open. I have been trying to modify Svanoy's code with get time() but have been unsuccessful.

If I could get it to work, ideally I would have it on a watchlist but I'm not sure if that is possible.
 
@pluder sorry for the delay, been on vacation and getting caught up afterwards and almost didn't see this. Here is what I've come up with. If not all days have volume at the current time, a label appear at the top stating this and the average will be calculated with number of days that have volume at current time.
IwsC0uT.jpeg

Ruby:
#Modification request
#Averages total volume at same time of last bar over X number of prior days.
#Svanoy

input Number_Of_Days_To_Be_Averaged = 5;
input Value_To_Be_Averaged = volume;

def SecondsInDay = 86400;
def SecondsInHour = 3600;
def epoch = (GetTime() / 1000);
def CalcHour = Floor((epoch % SecondsInDay) / SecondsInHour);
def CalcMin = Floor(((epoch % SecondsInDay) % SecondsInHour)) / 60;
def LastBarHour = If IsNaN(close[-1]) then CalcHour else Double.NaN;
def LastBarMin = If IsNaN(close[-1]) then CalcMin else Double.NaN;
def TotalDays = if GetDayofWeek(GetYYYYMMDD()) <> GetDayofWeek(GetYYYYMMDD()[1]) && GetDayofWeek(GetYYYYMMDD()[-1]) <> 7 then TotalDays[1]+1 else TotalDays[1];

def CurrentHour = fold h = 0 to HighestAll(Barnumber()) while !IsNaN(GetValue(close, -h)) do GetValue(LastBarHour,-h);
def CurrentMin = fold m = 0 to HighestAll(Barnumber()) while !IsNaN(GetValue(close, -m)) do GetValue(LastBarMin,-m);
def LastDay = fold d = 0 to HighestAll(Barnumber()) while !IsNaN(GetValue(close, -d)) do GetValue(TotalDays,-d);

def NotToday = GetDay() <> GetLastDay();
def DaysAgo = LastDay - TotalDays;
def SignalBar = CalcHour == CurrentHour && CalcMin == CurrentMin && DaysAgo <= Number_Of_Days_To_Be_Averaged;
def SignalCount = If BarNumber()==1 && !SignalBar then 0 else if SignalBar && NotToday then SignalCount[1]+1 else SignalCount[1];

plot arrow = If (SignalBar && NotToday) or IsNaN(close[-1]) then high else Double.NaN;
arrow.setpaintingStrategy(paintingStrategy.BOOLEAN_ARROW_DOWN);
arrow.assignValueColor(color.ORANGE);

def RangeTotalVolume = if DaysAgo == 1 + Number_Of_Days_To_Be_Averaged then 0 else if SignalBar && NotToday then RangeTotalVolume[1] + Value_To_Be_Averaged else RangeTotalVolume[1];

def RangeAverage = RangeTotalVolume / SignalCount;
def RVOL = Round(volume/RangeAverage,2);

addlabel(yes,"Current Bar Volume: " +volume+" / RVOL: "+RVOL,color.white,yes);
addlabel(yes,"Average Volume From the Same Time Over the Past " +Number_Of_Days_To_Be_Averaged+ " Days: "+RangeAverage,color.WHITE,yes);
addlabel(If SignalCount < Number_Of_Days_To_Be_Averaged then yes else no,"Not Enough Days with Volume at Time of Current Bar",color.LIGHT_RED,yes);

Here is the scan: Results returned in red indicate the specified number of days to average did not all have volume at the time of the current bar and the average will be calculated with number of days that have volume at current time.

Ruby:
def Number_Of_Days_To_Be_Averaged = 5;
def Value_To_Be_Averaged = volume;

def SecondsInDay = 86400;
def SecondsInHour = 3600;
def epoch = (GetTime() / 1000);
def CalcHour = Floor((epoch % SecondsInDay) / SecondsInHour);
def CalcMin = Floor(((epoch % SecondsInDay) % SecondsInHour)) / 60;
def LastBarHour = If IsNaN(close[-1]) then CalcHour else Double.NaN;
def LastBarMin = If IsNaN(close[-1]) then CalcMin else Double.NaN;
def TotalDays = if GetDayofWeek(GetYYYYMMDD()) <> GetDayofWeek(GetYYYYMMDD()[1]) && GetDayofWeek(GetYYYYMMDD()[-1]) <> 7 then TotalDays[1]+1 else TotalDays[1];

def CurrentHour = fold h = 0 to HighestAll(Barnumber()) while !IsNaN(GetValue(close, -h)) do GetValue(LastBarHour,-h);
def CurrentMin = fold m = 0 to HighestAll(Barnumber()) while !IsNaN(GetValue(close, -m)) do GetValue(LastBarMin,-m);
def LastDay = fold d = 0 to HighestAll(Barnumber()) while !IsNaN(GetValue(close, -d)) do GetValue(TotalDays,-d);

def NotToday = GetDay() <> GetLastDay();
def DaysAgo = LastDay - TotalDays;
def SignalBar = CalcHour == CurrentHour && CalcMin == CurrentMin && DaysAgo <= Number_Of_Days_To_Be_Averaged;
def SignalCount = If BarNumber()==1 && !SignalBar then 0 else if SignalBar && NotToday then SignalCount[1]+1 else SignalCount[1];

def RangeTotalVolume = if DaysAgo == 1 + Number_Of_Days_To_Be_Averaged then 0 else if SignalBar && NotToday then RangeTotalVolume[1] + Value_To_Be_Averaged else RangeTotalVolume[1];

def RangeAverage = RangeTotalVolume / SignalCount;

plot RVOL = Round(volume/RangeAverage,2);
RVOL.AssignValueColor(If SignalCount < Number_Of_Days_To_Be_Averaged then color.RED else color.WHITE);
 
Last edited:
@hboogie Labels will show after close of last bar in average range.
Ruby:
#Modification request
#Averages total volume of first X bars of then day.
#Svanoy

input Number_Of_Bars_To_Be_Averaged = 5;
input Time_of_First_bar = 0930;

def Value_To_Be_Averaged = volume;
def RangeBar = If SecondsTillTime(Time_of_First_bar) == 0 then 1 else
If RangeBar[1] < Number_Of_Bars_To_Be_Averaged && Rangebar[1] then RangeBar[1]+1 else 0;

plot arrow = if RangeBar then high else double.nan;
arrow.setpaintingStrategy(paintingStrategy.BOOLEAN_ARROW_DOWN);
arrow.assignValueColor(color.ORANGE);
 
def RangeTotal = If !RangeBar[1] && RangeBar then Value_To_Be_Averaged else if RangeBar then RangeTotal[1]+Value_To_Be_Averaged else RangeTotal[1];

def RangeAverage = If !RangeBar then RangeTotal/Number_Of_Bars_To_Be_Averaged else 0;
def RVOL = Round(RangeAverage / Value_To_Be_Averaged,2);

AddLabel(RangeAverage,"RVOL of Current Bar Based on First "+Number_Of_Bars_To_Be_Averaged+" Bars Average Volume: "+RVOL,color.WHITE,yes);
AddLabel(RangeAverage,"Average Volume of the First: "+Number_Of_Bars_To_Be_Averaged+" Bars: "+RangeAverage,color.WHITE,yes);
 
@hboogie Labels will show after close of last bar in average range.
Ruby:
#Modification request
#Averages total volume of first X bars of then day.
#Svanoy

input Number_Of_Bars_To_Be_Averaged = 5;
input Time_of_First_bar = 0930;

def Value_To_Be_Averaged = volume;
def RangeBar = If SecondsTillTime(Time_of_First_bar) == 0 then 1 else
If RangeBar[1] < Number_Of_Bars_To_Be_Averaged && Rangebar[1] then RangeBar[1]+1 else 0;

plot arrow = if RangeBar then high else double.nan;
arrow.setpaintingStrategy(paintingStrategy.BOOLEAN_ARROW_DOWN);
arrow.assignValueColor(color.ORANGE);
 
def RangeTotal = If !RangeBar[1] && RangeBar then Value_To_Be_Averaged else if RangeBar then RangeTotal[1]+Value_To_Be_Averaged else RangeTotal[1];

def RangeAverage = If !RangeBar then RangeTotal/Number_Of_Bars_To_Be_Averaged else 0;
def RVOL = Round(RangeAverage / Value_To_Be_Averaged,2);

AddLabel(RangeAverage,"RVOL of Current Bar Based on First "+Number_Of_Bars_To_Be_Averaged+" Bars Average Volume: "+RVOL,color.WHITE,yes);
AddLabel(RangeAverage,"Average Volume of the First: "+Number_Of_Bars_To_Be_Averaged+" Bars: "+RangeAverage,color.WHITE,yes);
This is wonderful. Thank you. I wanted to include logic from @halcyonguy from this thread https://usethinkscript.com/threads/fast-climbing-volume-watchlist-for-scalping.21160/post-154907

and came up with this
Code:
# Combo RVOL session and Volume Increasing from the following uts threads
# https://usethinkscript.com/threads/fast-climbing-volume-watchlist-for-scalping.21160/#post-154907
# https://usethinkscript.com/threads/average-volume-for-first-bar-of-the-day.10449/post-155111
# Credit to those threads for the idea.

# declare lower;

# === INPUTS ===
input Number_Of_Bars_To_Be_Averaged = 5;
input Time_of_First_Bar = 0930;
input qty_of_bars = 4;
input percent_gain = 15.0;
input min_rvol_required = 1.0;

# === BASE DEFINITIONS ===
def v = volume;
def isFirstBar = SecondsTillTime(Time_Of_First_Bar) == 0;

# === INITIAL RANGE VOLUME CALC (for RVOL) ===
def RangeBar = if isFirstBar then 1
               else if RangeBar[1] < Number_Of_Bars_To_Be_Averaged and RangeBar[1] then RangeBar[1] + 1
               else 0;

def RangeTotal = if !RangeBar[1] and RangeBar then v
                 else if RangeBar then RangeTotal[1] + v
                 else RangeTotal[1];

def RangeAverage = if !RangeBar then RangeTotal / Number_Of_Bars_To_Be_Averaged else Double.NaN;
def RVOL = if RangeAverage > 0 then Round(v / RangeAverage, 2) else Double.NaN;

# === VOLUME SPIKE DETECTION ===
def cnt = fold i = 0 to qty_of_bars
          with x
          while GetValue(v, i) > ((1 + percent_gain / 100) * GetValue(v, i + 1))
          do x + 1;

def vper = Round(100 * ((v - v[1]) / v[1]), 0);

# === TIER CONDITIONS (ALL TIED TO SINGLE RVOL FILTER) ===
def show1 = cnt == 1 and RVOL >= min_rvol_required;
def show2 = cnt == 2 and RVOL >= min_rvol_required;
def show3 = cnt == 3 and RVOL >= min_rvol_required;
def show4 = cnt >= 4 and RVOL >= min_rvol_required;

# === HISTOGRAM ===
plot volPlot = v;
volPlot.setPaintingStrategy(PaintingStrategy.HISTOGRAM);
volPlot.setDefaultColor(Color.DARK_GRAY);
volPlot.setLineWeight(2);

# === CHART BUBBLES ===
AddChartBubble(show1, v, "1\n" + vper + "%", Color.LIGHT_GREEN, no);
AddChartBubble(show2, v, "2\n" + vper + "%", Color.GREEN, no);
AddChartBubble(show3, v, "3\n" + vper + "%", Color.YELLOW, no);
AddChartBubble(show4, v, "4+\n" + vper + "%", Color.ORANGE, no);

# === LABEL ===
AddLabel(!IsNaN(RangeAverage), "RVOL: " + RVOL + " | Avg Vol (first " + Number_Of_Bars_To_Be_Averaged + " bars): " + RangeAverage, Color.WHITE);

However i can't quite get it to work to my liking. Specifically, i want to only show bubbles based off the min_rvol input. so if there are rvol prints of 2, only show bubbles greater than 2.

Also, make sure that the volume spike logic is correlated to your rvol start session logic so each bar is basing their calculation off that value.

Ideally , would like to introduce logic to separate and pickup on 100%+ bars with a label or possible alert and histo bar painted.

Hoping you guys can help out.

Thanks,
 
Last edited:
@hboogie I'm not quite sure what you mean here.
Specifically, i want to only show bubbles based off the min_rvol input. so if there are rvol prints of 2, only show bubbles greater than 2.
and here
Also, make sure that the volume spike logic is correlated to your rvol start session logic so each bar is basing their calculation off that value.
Can you elaborate on what you expect the code to do?
 
@hboogie I'm not quite sure what you mean here.

and here

Can you elaborate on what you expect the code to do?

Yes. Thank you for the reply. The first part was tied to the 4 bubbles being printed in @halcyonguy’s post. I understand now that the rvol calc is an absolute number and can’t be tied to just 4 bubble types.

So ideally what I’d like to see is the ability to filter for rising volume conditions that are all based off the start of day volume. For instance if the rvol for the first 5 bars equals x , any subsequent increases in rvol (with x bars back as an input) will print a bubble showing its increase. The increases can be contained as inputs perhaps to only filter volume increases above x% along with rvol greater than a % of the session start rvol.

The goal is to capture the volume increases and flag the bigger increases right before a breakdown or breakout happens. Hope this makes sense.

Thank you.

H
 
@hboogie Okay, so the problem is RVOL is not a single value calculated for the first 5 bars. RVOL is calculated for each subsequent bar based on the average volume of the first 5 bars.

I can check for a minimum increase in RVOL, only question is do you want a minimum increase between each bar of the look back bars or combined minimum increase across the look back bars?

I will have to add an RVOL calculation for each of the first 5 bars to calculate after the 5th bar closes to prevent false positives on bars 6 through 10 either way.
 
@hboogie Okay, so the problem is RVOL is not a single value calculated for the first 5 bars. RVOL is calculated for each subsequent bar based on the average volume of the first 5 bars.

I can check for a minimum increase in RVOL, only question is do you want a minimum increase between each bar of the look back bars or combined minimum increase across the look back bars?

I will have to add an RVOL calculation for each of the first 5 bars to calculate after the 5th bar closes to prevent false positives on bars 6 through 10 either way.

My first thought is a combined min increase. Conceptually it’s new so I’d be grateful and curious on how you would express it.

I believe by both flagging an increase in volume combined with an rvol filter could reduce the noise associated with just flagging volume % increases.

HTH
 
@hboogie I included both, minimum increase between bars in range and minimum increase across range.

Ruby:
# declare lower;

# === INPUTS ===
input Number_Of_Bars_To_Be_Averaged = 5;
input Time_of_First_Bar = 0930;
input qty_of_bars = 4;
input percent_gain = 15.0;
input min_rvol_required = 1.0;
input Use_Range_Total = no;
input Min_Range_Total_Gain = 90;

# === BASE DEFINITIONS ===
def v = volume;
def isFirstBar = SecondsTillTime(Time_Of_First_Bar) == 0;

# === INITIAL RANGE VOLUME CALC (for RVOL) ===
def RangeBar = if isFirstBar then 1
               else if RangeBar[1] < Number_Of_Bars_To_Be_Averaged and RangeBar[1] then RangeBar[1] + 1
               else 0;

def RangeTotal = if !RangeBar[1] and RangeBar then v
                 else if RangeBar then RangeTotal[1] + v
                 else RangeTotal[1];

def RangeAverage = if !RangeBar then RangeTotal / Number_Of_Bars_To_Be_Averaged else Double.NaN;
def RVOL = if !IsNaN(RangeAverage) then Round(v / RangeAverage, 2) else double.nan;

# === VOLUME SPIKE DETECTION ===

def gain = Round((fold l = 0 to qty_of_bars
                  with y 
                  do y + (GetValue(v,l) - GetValue(v,l+1)) / GetValue(v,l+1))*100,0);

def cnt = if Use_Range_Total then
              fold z = 0 to qty_of_bars
              with u = 0
              do if GetValue(v,z)>=GetValue(v,z+1) then u+1 else u
         else 
              fold i = 0 to qty_of_bars
              with x = 0
              while GetValue(v, i) > ((1 + percent_gain / 100) * GetValue(v, i + 1))
              do x + 1;

def vper = Round(100 * ((v - v[1]) / v[1]), 0);

# === TIER CONDITIONS (ALL TIED TO SINGLE RVOL FILTER) ===
def show1 = !Use_Range_Total && cnt == 1 && RVOL >= min_rvol_required && RangeAverage;
def show2 = !Use_Range_Total && cnt == 2 && RVOL >= min_rvol_required && RangeAverage;
def show3 = !Use_Range_Total && cnt == 3 && RVOL >= min_rvol_required && RangeAverage;
def show4 = !Use_Range_Total && cnt >= 4 && RVOL >= min_rvol_required && RangeAverage;

def show5 = Use_Range_Total && cnt > 1 && gain >= Min_Range_Total_Gain && RVOL >= min_rvol_required && RangeAverage;


# === HISTOGRAM ===
plot volPlot = v;
volPlot.setPaintingStrategy(PaintingStrategy.HISTOGRAM);
volPlot.assignValueColor(if RangeBar then Color.YELLOW else if RVOL >1 && !RangeBar then Color.Dark_Green else Color.DARK_GRAY);
volPlot.setLineWeight(2);

# === CHART BUBBLES ===
AddChartBubble((show1 && !show2[-1]), v, "1\n" +vper+ "%", Color.LIGHT_GREEN, yes);
AddChartBubble((show2 && !show3[-1]), v, "1\n" +vper+ "%", Color.GREEN, yes);
AddChartBubble((show3 && !show4[-1]), v, "1\n" +vper+ "%", Color.YELLOW, yes);
AddChartBubble((show4 && !show4[-1]), v, "1\n" +vper+ "%", Color.ORANGE, yes);
AddChartBubble((show5 && !show5[-1]), v, "At least "+Min_Range_Total_Gain+ "% over last "+qty_of_bars+" bars\n"+"RVOL Greater than "+min_rvol_required, Color.ORANGE, yes);

# === LABEL ===
AddLabel(!IsNaN(RangeAverage), "RVOL: " + AsText(RVOL,NumberFormat.TWO_DECIMAL_PLACES) + " | Avg Vol (first " + Number_Of_Bars_To_Be_Averaged + " bars): " + RangeAverage, Color.WHITE);
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
286 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top