View Of Volume --Archived

Status
Not open for further replies.

MatthewA

Active member
Code:
#____   ____.__                        _____  ____   ____    .__                       
#\   \ /   /|__| ______  _  __   _____/ ____\ \   \ /   /___ |  |  __ __  _____   ____ 
# \   V   / |  |/ __ \ \/ \/ /  /  _ \   __\   \   V   /  _ \|  | |  |  \/     \_/ __ \
#  \     /  |  \  ___/\     /  (  <_> )  |      \     (  <_> )  |_|  |  /  | |  \  ___/
#   \___/   |__|\___/  \/\_/    \____/|__|       \___/ \____/|____/____/|__|_|  /\___/
                                                                    
                                                                                      
#   _                   _                _     _   _                    _               
# _| |_ _ ___ ___ _____|_|___    ___ ___| |___| |_|_|_ _ ___    _ _ ___| |_ _ _____ ___
#| . | | |   | .'|     | |  _|  |  _| -_| | .'|  _| | | | -_|  | | | . | | | |     | -_|
#|___|_  |_|_|__,|_|_|_|_|___|  |_| |___|_|__,|_| |_|\_/|___|   \_/|___|_|___|_|_|_|___|
#    |___|                                                                             

# Special thanks to Welkin from UseThinkScript.com

# For any asset, knowing the volume of trades is useless without context.
# We must be include patterns which are out of view of most charts.
# Large spikes and drops of Volume must considered relattive to the delta of price and the time of occurance. 

#EOM colors: The Ease Of Movement ( EoM ) is the the amount of volume required to move prices. EoM was developed by Richard W. Arms, Jr., the creator of Equivolume.
#We will set the brightness of the price according to the Relative Dynamic EOM. Viewing bright EOM prices in a trending distribution indicates that it would be EASY for the trend to continue into that direction after the occasional retracements. Viewing bright EOM Volumes when the market is range-bound indicates which it will be EASY for price to drift in that range.

#DPL Lines:  We take a cautionary View of Difficult Price Lines ( DPLs ) to avoid Volumes where price will chop erratically, as these areas will be DIFFICULT to enter good trends and it is more comfortable to wait so that we may avoid uneccessary stress. The DPL lines are based on the works of Melvin E. Dickover, who developed FreedomOfMovement which takes into account price-volume behavior in order to detect points where movement of price is suddenly restricted. You may consider taking profits a bit before the next DPL line or wating to open your next position until the Difficult Volumes have weakened. You will notice that the DPL caclulations are much more accurate than simply drawing Support & Resistance Lines at recent Highs and Lows, however I would discourage the user from attempting to scalp off of bounces at the DPLs. We must take a long term View Of Volume to understand the price action as a whole.

# It is well known that Volume Accumulates while the market consolidates for the majority of time and Volume Distributes into strong trends. Only with a View of Volume can one understand when it would be more comfortable to wait or

declare upper;
declare hide_on_daily;
def h=high; def l=low; def hlc=hlc3; def c=close; def NAN=double.NAN;
input WinsorizingPercentage =5; #hint WinsorizingPercentage: % percentage to shift Normalized Values to prevent extreme arbitrary skewing.
# Traditionally Winsorizing works by replacing extreme High and Extreme Low values with and upper or lower common percentile median. However in our applicatoin we wish to simplfy the load on our computers and prevent wild shifts.

input DPLthreshold=95; #hint DPLthreshold: The required strength of a DPL where a Volume is expected to bring DIFFICULT erratic chop. 

DefineGlobalColor("1stStrongest", CreateColor(0,230,255));
DefineGlobalColor("2ndStrongest", CreateColor(0,190,255));
DefineGlobalColor("3rdStrongest", CreateColor(0,150,255));
DefineGlobalColor("4thStrongest", CreateColor(0,110,255));
DefineGlobalColor("5thStrongest", CreateColor(0,70,255));
DefineGlobalColor("6thStrongest", CreateColor(0,0,200));
DefineGlobalColor("7thStrongest", CreateColor(0,0,150));
DefineGlobalColor("8thStrongest", CreateColor(0,0,100));

DefineGlobalColor("DifficultPriceLine", createcolor(75,180,255));
# VOLUME SELECTION
# Unfortunately, tick data is only available for the past 5 days in ThinkScript Servers.
def shares = If(!IsNaN(volume), volume, 1);
def oi = If(!IsNaN(open_interest), open_interest, 1);
def iv = If(!IsNaN(imp_volatility), imp_volatility, .00001);
def v;
#hint volumeSource: Choose to use either Share Volume (normal volume), Shares Per Range which is Share Volume / Range chosen below, or Trades Per Range which is Trade Volume / Range chosen below. ToS servers only store tick data for 5 days...
input volumeSource = {
    default "Share Volume",   
    "OpenInterest", 
    "Shares/OI",   
    "ImpliedVolatility",   
    "Shares/IV",
    "Shares*IV",
    "Trades/IV"
  
};
switch (volumeSource) {
case "Share Volume":
    v = shares;
case "OpenInterest":
    v = oi;
case "Shares/OI":
    v = shares / oi;
case "ImpliedVolatility":
    v = iv;
case "Shares/IV":
    v = shares / iv;
case "Shares*IV":
    v = shares * iv;
case "Trades/IV":
    v = shares / iv;
}

script prior {
    input of = close;
    def priorOf = if of != of[1] then of[1] else priorOf[1];
    plot
    prior = priorOf;
}

def x = BarNumber();
def x0 = if isNaN(close[-1]) and !isNaN(close) then x else x0[1]; # X0 periodization is required for the Winsorizing operation required later. Please read a bit about "Winsorization"
def rteBar = if GetTime() crosses above RegularTradingStart(GetYYYYMMDD()) then
               x else rteBar[1];
def priorRTEbar1  = prior(rteBar);
def priorRTEbar2  = prior(priorRTEbar1);
def priorRTEbar3  = prior(priorRTEbar2);
def priorRTEbar4  = prior(priorRTEbar3);
def priorRTEbar5  = prior(priorRTEbar4);
def priorRTEbar6  = prior(priorRTEbar5);
def priorRTEbar7  = prior(priorRTEbar6);

#Relative VOLUME portion
def pV1  = GetValue(v, rteBar - priorRTEbar1);
def pV2  = GetValue(v, rteBar - priorRTEbar2);
def pV3  = GetValue(v, rteBar - priorRTEbar3);
def pV4  = GetValue(v, rteBar - priorRTEbar4);
def pV5  = GetValue(v, rteBar - priorRTEbar5);
def pV6  = GetValue(v, rteBar - priorRTEbar6);
def pV7  = GetValue(v, rteBar - priorRTEbar7);

def avgPriorVol = (pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7) / 7;
def StdDevPriorVol = StDev(pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7);

def relVol = ( v - avgPriorVol ) / StdDevPriorVol;
def minVol = LowestAll(relVol);
def maxVol = HighestAll(relVol);
def normalizedRelativeVolume = 1 + (((relVol - minVol) / (maxVol - minVol)) * (100));

def relVolWinsorizeBaseline =  simpleMovingAvg(normalizedRelativeVolume, 1440);
def WinsorizingMin =  relVolWinsorizeBaseline + WinsorizingPercentage;
def WinzoringForcedMax=100 - WinsorizingMin;
def WinsorizedRelVol = if normalizedRelativeVolume> WinzoringForcedMax then WinzoringForcedMax else if normalizedRelativeVolume < WinsorizingMin then WinsorizingMin else normalizedRelativeVolume;
def minNormalizedRelVol=min(Lowestall(WinsorizedRelVol),WinsorizingPercentage);
def maxNormalizedRelVol=Highestall(WinsorizedRelVol);
def ViewOfVolumeRelativeRelVol = 1 + (((WinsorizedRelVol - minNormalizedRelVol) / (maxNormalizedRelVol - minNormalizedRelVol)) * 100); # Plot as Histogram


#Relative PRICE MOVE
input PastPriceMovePercent=50; #hint PastPriceMovePercent: The 0-100% normalized% of the price move which is compared relative to priceActionIndicator moves of previous days. Preferably greater than 50%.
def PriorDayPriceMOVE = AbsValue((hlc - hlc[1]) / (hlc[1]));
def pM1  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar1);
def pM2  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar2);
def pM3  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar3);
def pM4  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar4);
def pM5  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar5);
def pM6  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar6);
def pM7  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar7);

def avgPriorMOVE = (pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7 ) / 7;
def StdDevPriorMOVE = StDev(pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7);
def relMOVE = ((( PriorDayPriceMOVE - avgPriorMOVE) / StdDevPriorMOVE) * (PastPriceMovePercent)) + ((PriorDayPriceMOVE) * (100 - PastPriceMovePercent));
def minMOVE = LowestAll(relMOVE);
def maxMOVE = HighestAll(relMOVE);
def normalizedMOVE = 1 + (((relMOVE - minMOVE) / (maxMOVE - minMOVE)) * (100));

# Final EASEOfMovement solution to highlight price moves which may occur in smooth trends from low orderflow....
# Strong EOMs from trends are likely to continue in the direction of that trend after the occasional pause.
# Strong EOMs that do not outside of strong trends are likely to revisit the same prices.
def EaseOfMovement = normalizedMOVE / ViewOfVolumeRelativeRelVol;
def minEoM = LowestAll(EaseOfMovement);
def maxEoM = HighestAll(EaseOfMovement);
def normalizedEase = 1 + (((EaseOfMovement - minEoM) / (maxEoM - minEoM)) * 100);
 # Nice to plot as Histogram
def WinsorizingMinEOM =  simpleMovingAvg(normalizedEase, 144);;
def WinzoringForcedMaxEOM=100 - WinsorizingMinEOM;
def WinsorizedEOM = if normalizedEase> WinzoringForcedMaxEOM then WinzoringForcedMaxEOM else if normalizedEase < WinsorizingPercentage then WinsorizingPercentage else normalizedEase;
def minNormalizedEoM=Lowestall(WinsorizedEOM);
def maxNormalizedEoM=Highestall(WinsorizedEOM);
plot ViewOfVolumeRelativeEoM =1 + (((WinsorizedEOM - minNormalizedEoM) / (maxNormalizedEoM - minNormalizedEoM)) * 100);
# Nice to plot as Histogram

input   FirstEasiestOrderFlow1st= 60; #hint FirstEasiestOrderFlow1st:
input  SecondEasiestOrderFlow2nd= 50; #hint SecondEasiestOrderFlow2nd:
input   ThirdEasiestOrderFlow3rd= 40; #hint ThirdEasiestOrderFlow3rd:
input   FouthEasiestOrderFlow4th= 30; #hint FouthEasiestOrderFlow4th:
input   FifthEasiestOrderFlow5th= 20; #hint FifthEasiestOrderFlow5th:
input   SixthEasiestOrderFlow6th= 15; #hint SixthEasiestOrderFlow6th:
input SeventhEasiestOrderFlow7th= 10; #hint SeventhEasiestOrderFlow7th:
input  EighthEasiestOrderFlow8th= 5; #hint EighthEasiestOrderFlow8th:

AssignPriceColor(
 if ViewOfVolumeRelativeEoM > FirstEasiestOrderFlow1st then GlobalColor("1stStrongest")
 else if ViewOfVolumeRelativeEoM > SecondEasiestOrderFlow2nd then GlobalColor("2ndStrongest")
 else if ViewOfVolumeRelativeEoM > ThirdEasiestOrderFlow3rd then GlobalColor("3rdStrongest")
 else if ViewOfVolumeRelativeEoM > FouthEasiestOrderFlow4th then GlobalColor("4thStrongest")
 else if ViewOfVolumeRelativeEoM > FifthEasiestOrderFlow5th then GlobalColor("5thStrongest")
 else if ViewOfVolumeRelativeEoM > SixthEasiestOrderFlow6th then GlobalColor("6thStrongest")
 else if ViewOfVolumeRelativeEoM > SeventhEasiestOrderFlow7th then GlobalColor("7thStrongest")
 else if ViewOfVolumeRelativeEoM > EighthEasiestOrderFlow8th then GlobalColor("8thStrongest")
 else Color.Black);

# Final FOM solution to draw the 'Defended Price Line' (DPL) where trading is overencumbered with Volumes...
#We expect choppiness and erratic stop outs to randomly provide and restrict liquidity near DPLs and we prefer not to trade in these DIFFICULT DPLs.
def FreedomMOVEMENT = ViewOfVolumeRelativeRelVol / normalizedMOVE;
def relFOM = 1/ViewOfVolumeRelativeEoM;
def minFOM = LowestAll(relFOM);
def maxFOM = HighestAll(relFOM);
def normalizedFOM = 1 + (((relFOM - minFOM) / (maxFOM - minFOM)) * 100); # Plot as volume


def DPLlimitLength = 60;
def DPLcheck =  (MovingAverage(AverageType.WEIGHTED, normalizedFOM, DPLlimitLength));
plot DefendedPriceLineDPL = if normalizedFOM > ((DPLcheck/2)+DPLthreshold) then close else Double.NaN;
def DPLcount= if !isNAN(DefendedPriceLineDPL) then DPLcount[1]+1 else DPLcount[1];
DefendedPriceLineDPL.setPaintingStrategy(PaintingStrategy.Squares);
DefendedPriceLineDPL.SetDefaultColor(GlobalColor("DifficultPriceLine")); DefendedPriceLineDPL.hideBubble(); DefendedPriceLineDPL.hideTitle();
DefendedPriceLineDPL.SetLineWeight(5);
addLabel(1,"| " + DPLcount  + " DPLs (Difficult Price Lines) ◽--- " + DPLthreshold +"% level |",GlobalColor("DifficultPriceLine"));

#Assign DPL lines at specific points
#######################################

rec DPLcounter;
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] < 20) {
DPLcounter =DPLcounter[1] + 1;
} else {
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] == 20) {
DPLcounter = 1;
} else {
DPLcounter =DPLcounter[1];
}
};
rec DifficultPrice1;
if DPLcounter==1 && DPLcounter[1]!=1 {
DifficultPrice1= close; } else {DifficultPrice1=CompoundValue(1, DifficultPrice1[1], NAN);};
plot DPL1=DifficultPrice1;
DPL1.SetPaintingStrategy(PaintingStrategy.DASHES); DPL1.hideBubble(); DPL1.hideTitle();
DPL1.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL1.SetLineWeight(1);

rec DifficultPrice2;
if DPLcounter==2 && DPLcounter[1]!=2 {
DifficultPrice2= close; } else {DifficultPrice2=CompoundValue(1, DifficultPrice2[1], NAN);};
plot DPL2=DifficultPrice2;
DPL2.SetPaintingStrategy(PaintingStrategy.DASHES); DPL2.hideBubble(); DPL2.hideTitle();
DPL2.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL2.SetLineWeight(1);

rec DifficultPrice3;
if DPLcounter==3 && DPLcounter[1]!=3 {
DifficultPrice3= close; } else {DifficultPrice3=CompoundValue(1, DifficultPrice3[1], NAN);};
plot DPL3=DifficultPrice3;
DPL3.SetPaintingStrategy(PaintingStrategy.DASHES); DPL3.hideBubble(); DPL3.hideTitle();
DPL3.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL3.SetLineWeight(1);

rec DifficultPrice4;
if DPLcounter==4 && DPLcounter[1]!=4 {
DifficultPrice4= close; } else {DifficultPrice4=CompoundValue(1, DifficultPrice4[1], NAN);};
plot DPL4=DifficultPrice4;
DPL4.SetPaintingStrategy(PaintingStrategy.DASHES); DPL4.hideBubble(); DPL4.hideTitle();
DPL4.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL4.SetLineWeight(1);

rec DifficultPrice5;
if DPLcounter==5 && DPLcounter[1]!=5 {
DifficultPrice5= close; } else {DifficultPrice5=CompoundValue(1, DifficultPrice5[1], NAN);};
plot DPL5=DifficultPrice5;
DPL5.SetPaintingStrategy(PaintingStrategy.DASHES); DPL5.hideBubble(); DPL5.hideTitle();
DPL5.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL5.SetLineWeight(1);

rec DifficultPrice6;
if DPLcounter==6 && DPLcounter[1]!=6 {
DifficultPrice6= close; } else {DifficultPrice6=CompoundValue(1, DifficultPrice6[1], NAN);};
plot DPL6=DifficultPrice6;
DPL6.SetPaintingStrategy(PaintingStrategy.DASHES); DPL6.hideBubble(); DPL6.hideTitle();
DPL6.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL6.SetLineWeight(1);

rec DifficultPrice7;
if DPLcounter==7 && DPLcounter[1]!=7 {
DifficultPrice7= close; } else {DifficultPrice7=CompoundValue(1, DifficultPrice7[1], NAN);};
plot DPL7=DifficultPrice7;
DPL7.SetPaintingStrategy(PaintingStrategy.DASHES); DPL7.hideBubble(); DPL7.hideTitle();
DPL7.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL7.SetLineWeight(1);

rec DifficultPrice8;
if DPLcounter==8 && DPLcounter[1]!=8 {
DifficultPrice8= close; } else {DifficultPrice8=CompoundValue(1, DifficultPrice8[1], NAN);};
plot DPL8=DifficultPrice8;
DPL8.SetPaintingStrategy(PaintingStrategy.DASHES); DPL8.hideBubble(); DPL8.hideTitle();
DPL8.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL8.SetLineWeight(1);

rec DifficultPrice9;
if DPLcounter==9 && DPLcounter[1]!=9 {
DifficultPrice9= close; } else {DifficultPrice9=CompoundValue(1, DifficultPrice9[1], NAN);};
plot DPL9=DifficultPrice9;
DPL9.SetPaintingStrategy(PaintingStrategy.DASHES); DPL9.hideBubble(); DPL9.hideTitle();
DPL9.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL9.SetLineWeight(1);

rec DifficultPrice10;
if DPLcounter==10 && DPLcounter[1]!=10 {
DifficultPrice10= close; } else {DifficultPrice10=CompoundValue(1, DifficultPrice10[1], NAN);};
plot DPL10=DifficultPrice10;
DPL10.SetPaintingStrategy(PaintingStrategy.DASHES); DPL10.hideBubble(); DPL10.hideTitle();
DPL10.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL10.SetLineWeight(1);

rec DifficultPrice11;
if DPLcounter==11 && DPLcounter[1]!=11 {
DifficultPrice11= close; } else {DifficultPrice11=CompoundValue(1, DifficultPrice11[1], NAN);};
plot DPL11=DifficultPrice11;
DPL11.SetPaintingStrategy(PaintingStrategy.DASHES); DPL11.hideBubble(); DPL11.hideTitle();
DPL11.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL11.SetLineWeight(1);

rec DifficultPrice12;
if DPLcounter==12 && DPLcounter[1]!=12 {
DifficultPrice12= close; } else {DifficultPrice12=CompoundValue(1, DifficultPrice12[1], NAN);};
plot DPL12=DifficultPrice12;
DPL12.SetPaintingStrategy(PaintingStrategy.DASHES); DPL12.hideBubble(); DPL12.hideTitle();
DPL12.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL12.SetLineWeight(1);

rec DifficultPrice13;
if DPLcounter==13 && DPLcounter[1]!=13 {
DifficultPrice13= close; } else {DifficultPrice13=CompoundValue(1, DifficultPrice13[1], NAN);};
plot DPL13=DifficultPrice13;
DPL13.SetPaintingStrategy(PaintingStrategy.DASHES); DPL13.hideBubble(); DPL13.hideTitle();
DPL13.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL13.SetLineWeight(1);

rec DifficultPrice14;
if DPLcounter==14 && DPLcounter[1]!=14 {
DifficultPrice14= close; } else {DifficultPrice14=CompoundValue(1, DifficultPrice14[1], NAN);};
plot DPL14=DifficultPrice14;
DPL14.SetPaintingStrategy(PaintingStrategy.DASHES); DPL14.hideBubble(); DPL14.hideTitle();
DPL14.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL14.SetLineWeight(1);

rec DifficultPrice15;
if DPLcounter==15 && DPLcounter[1]!=15 {
DifficultPrice15= close; } else {DifficultPrice15=CompoundValue(1, DifficultPrice15[1], NAN);};
plot DPL15=DifficultPrice15;
DPL15.SetPaintingStrategy(PaintingStrategy.DASHES); DPL15.hideBubble(); DPL15.hideTitle();
DPL15.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL15.SetLineWeight(1);

rec DifficultPrice16;
if DPLcounter==16 && DPLcounter[1]!=16 {
DifficultPrice16= close; } else {DifficultPrice16=CompoundValue(1, DifficultPrice16[1], NAN);};
plot DPL16=DifficultPrice16;
DPL16.SetPaintingStrategy(PaintingStrategy.DASHES); DPL16.hideBubble(); DPL16.hideTitle();
DPL16.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL16.SetLineWeight(1);


rec DifficultPrice17;
if DPLcounter==17 && DPLcounter[1]!=17 {
DifficultPrice17= close; } else {DifficultPrice17=CompoundValue(1, DifficultPrice17[1], NAN);};
plot DPL17=DifficultPrice17;
DPL17.SetPaintingStrategy(PaintingStrategy.DASHES); DPL17.hideBubble(); DPL17.hideTitle();
DPL17.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL17.SetLineWeight(1);

rec DifficultPrice18;
if DPLcounter==18 && DPLcounter[1]!=18 {
DifficultPrice18= close; } else {DifficultPrice18=CompoundValue(1, DifficultPrice18[1], NAN);};
plot DPL18=DifficultPrice18;
DPL18.SetPaintingStrategy(PaintingStrategy.DASHES); DPL18.hideBubble(); DPL18.hideTitle();
DPL18.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL18.SetLineWeight(1);

rec DifficultPrice19;
if DPLcounter==19 && DPLcounter[1]!=19 {
DifficultPrice19= close; } else {DifficultPrice19=CompoundValue(1, DifficultPrice19[1], NAN);};
plot DPL19=DifficultPrice19;
DPL19.SetPaintingStrategy(PaintingStrategy.DASHES); DPL19.hideBubble(); DPL19.hideTitle();
DPL19.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL19.SetLineWeight(1);


rec DifficultPrice20;
if DPLcounter==20 && DPLcounter[1]!=20 {
DifficultPrice20= close; } else {DifficultPrice20=CompoundValue(1, DifficultPrice20[1], NAN);};
plot DPL20=DifficultPrice20;
DPL20.SetPaintingStrategy(PaintingStrategy.DASHES); DPL20.hideBubble(); DPL20.hideTitle();
DPL20.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL20.SetLineWeight(1);

### Caution Relative Volume compares the current OrderFlow to the Volume of the EXACT same time of day for several times. For instance the Volume usually increases in the first minute after 9:30 AM EST as the NewYork WallStreet Opens... It would be completely meaningless to compare the open Volume to any other time of day except the market open of the previous days.
#Testing enough Data is loaded to calculate Relative Volumes
def CalendarDays = GetYYYYMMDD();
def NumberOfCalendarDaysOnChart = DaysFromDate(First(CalendarDays)) + GetDayOfWeek(First(CalendarDays));
AddLabel(NumberOfCalendarDaysOnChart <10, "RelativeVolume Error: Only " + NumberOfCalendarDaysOnChart + " days loaded on chart...Please add more days", Color.RED);


AddLabel(PastPriceMovePercent <40, " Caution: RelativePriceMove is only " + PastPriceMovePercent + " %. Please consider a larger relative price comparison to the past days.", Color.YELLOW);
 
Last edited by a moderator:

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

Code:
#____   ____.__                        _____  ____   ____    .__                       
#\   \ /   /|__| ______  _  __   _____/ ____\ \   \ /   /___ |  |  __ __  _____   ____ 
# \   V   / |  |/ __ \ \/ \/ /  /  _ \   __\   \   V   /  _ \|  | |  |  \/     \_/ __ \
#  \     /  |  \  ___/\     /  (  <_> )  |      \     (  <_> )  |_|  |  /  | |  \  ___/
#   \___/   |__|\___/  \/\_/    \____/|__|       \___/ \____/|____/____/|__|_|  /\___/
                                                                    
                                                                                      
#   _                   _                _     _   _                    _               
# _| |_ _ ___ ___ _____|_|___    ___ ___| |___| |_|_|_ _ ___    _ _ ___| |_ _ _____ ___
#| . | | |   | .'|     | |  _|  |  _| -_| | .'|  _| | | | -_|  | | | . | | | |     | -_|
#|___|_  |_|_|__,|_|_|_|_|___|  |_| |___|_|__,|_| |_|\_/|___|   \_/|___|_|___|_|_|_|___|
#    |___|                                                                             

# Special thanks to Welkin from UseThinkScript.com

# For any asset, knowing the volume of trades is useless without context.
# We must be include patterns which are out of view of most charts.
# Large spikes and drops of Volume must considered relattive to the delta of price and the time of occurance. 

#EOM colors: The Ease Of Movement ( EoM ) is the the amount of volume required to move prices. EoM was developed by Richard W. Arms, Jr., the creator of Equivolume.
#We will set the brightness of the price according to the Relative Dynamic EOM. Viewing bright EOM prices in a trending distribution indicates that it would be EASY for the trend to continue into that direction after the occasional retracements. Viewing bright EOM Volumes when the market is range-bound indicates which it will be EASY for price to drift in that range.

#DPL Lines:  We take a cautionary View of Difficult Price Lines ( DPLs ) to avoid Volumes where price will chop erratically, as these areas will be DIFFICULT to enter good trends and it is more comfortable to wait so that we may avoid uneccessary stress. The DPL lines are based on the works of Melvin E. Dickover, who developed FreedomOfMovement which takes into account price-volume behavior in order to detect points where movement of price is suddenly restricted. You may consider taking profits a bit before the next DPL line or wating to open your next position until the Difficult Volumes have weakened. You will notice that the DPL caclulations are much more accurate than simply drawing Support & Resistance Lines at recent Highs and Lows, however I would discourage the user from attempting to scalp off of bounces at the DPLs. We must take a long term View Of Volume to understand the price action as a whole.

# It is well known that Volume Accumulates while the market consolidates for the majority of time and Volume Distributes into strong trends. Only with a View of Volume can one understand when it would be more comfortable to wait or

declare upper;
declare hide_on_daily;
def h=high; def l=low; def hlc=hlc3; def c=close; def NAN=double.NAN;
input WinsorizingPercentage =5; #hint WinsorizingPercentage: % percentage to shift Normalized Values to prevent extreme arbitrary skewing.
# Traditionally Winsorizing works by replacing extreme High and Extreme Low values with and upper or lower common percentile median. However in our applicatoin we wish to simplfy the load on our computers and prevent wild shifts.

input DPLthreshold=95; #hint DPLthreshold: The required strength of a DPL where a Volume is expected to bring DIFFICULT erratic chop. 

DefineGlobalColor("1stStrongest", CreateColor(0,230,255));
DefineGlobalColor("2ndStrongest", CreateColor(0,190,255));
DefineGlobalColor("3rdStrongest", CreateColor(0,150,255));
DefineGlobalColor("4thStrongest", CreateColor(0,110,255));
DefineGlobalColor("5thStrongest", CreateColor(0,70,255));
DefineGlobalColor("6thStrongest", CreateColor(0,0,200));
DefineGlobalColor("7thStrongest", CreateColor(0,0,150));
DefineGlobalColor("8thStrongest", CreateColor(0,0,100));

DefineGlobalColor("DifficultPriceLine", createcolor(75,180,255));
# VOLUME SELECTION
# Unfortunately, tick data is only available for the past 5 days in ThinkScript Servers.
def shares = If(!IsNaN(volume), volume, 1);
def oi = If(!IsNaN(open_interest), open_interest, 1);
def iv = If(!IsNaN(imp_volatility), imp_volatility, .00001);
def v;
#hint volumeSource: Choose to use either Share Volume (normal volume), Shares Per Range which is Share Volume / Range chosen below, or Trades Per Range which is Trade Volume / Range chosen below. ToS servers only store tick data for 5 days...
input volumeSource = {
    default "Share Volume",   
    "OpenInterest", 
    "Shares/OI",   
    "ImpliedVolatility",   
    "Shares/IV",
    "Shares*IV",
    "Trades/IV"
  
};
switch (volumeSource) {
case "Share Volume":
    v = shares;
case "OpenInterest":
    v = oi;
case "Shares/OI":
    v = shares / oi;
case "ImpliedVolatility":
    v = iv;
case "Shares/IV":
    v = shares / iv;
case "Shares*IV":
    v = shares * iv;
case "Trades/IV":
    v = shares / iv;
}

script prior {
    input of = close;
    def priorOf = if of != of[1] then of[1] else priorOf[1];
    plot
    prior = priorOf;
}

def x = BarNumber();
def x0 = if isNaN(close[-1]) and !isNaN(close) then x else x0[1]; # X0 periodization is required for the Winsorizing operation required later. Please read a bit about "Winsorization"
def rteBar = if GetTime() crosses above RegularTradingStart(GetYYYYMMDD()) then
               x else rteBar[1];
def priorRTEbar1  = prior(rteBar);
def priorRTEbar2  = prior(priorRTEbar1);
def priorRTEbar3  = prior(priorRTEbar2);
def priorRTEbar4  = prior(priorRTEbar3);
def priorRTEbar5  = prior(priorRTEbar4);
def priorRTEbar6  = prior(priorRTEbar5);
def priorRTEbar7  = prior(priorRTEbar6);

#Relative VOLUME portion
def pV1  = GetValue(v, rteBar - priorRTEbar1);
def pV2  = GetValue(v, rteBar - priorRTEbar2);
def pV3  = GetValue(v, rteBar - priorRTEbar3);
def pV4  = GetValue(v, rteBar - priorRTEbar4);
def pV5  = GetValue(v, rteBar - priorRTEbar5);
def pV6  = GetValue(v, rteBar - priorRTEbar6);
def pV7  = GetValue(v, rteBar - priorRTEbar7);

def avgPriorVol = (pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7) / 7;
def StdDevPriorVol = StDev(pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7);

def relVol = ( v - avgPriorVol ) / StdDevPriorVol;
def minVol = LowestAll(relVol);
def maxVol = HighestAll(relVol);
def normalizedRelativeVolume = 1 + (((relVol - minVol) / (maxVol - minVol)) * (100));

def relVolWinsorizeBaseline =  simpleMovingAvg(normalizedRelativeVolume, 1440);
def WinsorizingMin =  relVolWinsorizeBaseline + WinsorizingPercentage;
def WinzoringForcedMax=100 - WinsorizingMin;
def WinsorizedRelVol = if normalizedRelativeVolume> WinzoringForcedMax then WinzoringForcedMax else if normalizedRelativeVolume < WinsorizingMin then WinsorizingMin else normalizedRelativeVolume;
def minNormalizedRelVol=min(Lowestall(WinsorizedRelVol),WinsorizingPercentage);
def maxNormalizedRelVol=Highestall(WinsorizedRelVol);
def ViewOfVolumeRelativeRelVol = 1 + (((WinsorizedRelVol - minNormalizedRelVol) / (maxNormalizedRelVol - minNormalizedRelVol)) * 100); # Plot as Histogram


#Relative PRICE MOVE
input PastPriceMovePercent=50; #hint PastPriceMovePercent: The 0-100% normalized% of the price move which is compared relative to priceActionIndicator moves of previous days. Preferably greater than 50%.
def PriorDayPriceMOVE = AbsValue((hlc - hlc[1]) / (hlc[1]));
def pM1  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar1);
def pM2  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar2);
def pM3  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar3);
def pM4  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar4);
def pM5  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar5);
def pM6  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar6);
def pM7  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar7);

def avgPriorMOVE = (pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7 ) / 7;
def StdDevPriorMOVE = StDev(pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7);
def relMOVE = ((( PriorDayPriceMOVE - avgPriorMOVE) / StdDevPriorMOVE) * (PastPriceMovePercent)) + ((PriorDayPriceMOVE) * (100 - PastPriceMovePercent));
def minMOVE = LowestAll(relMOVE);
def maxMOVE = HighestAll(relMOVE);
def normalizedMOVE = 1 + (((relMOVE - minMOVE) / (maxMOVE - minMOVE)) * (100));

# Final EASEOfMovement solution to highlight price moves which may occur in smooth trends from low orderflow....
# Strong EOMs from trends are likely to continue in the direction of that trend after the occasional pause.
# Strong EOMs that do not outside of strong trends are likely to revisit the same prices.
def EaseOfMovement = normalizedMOVE / ViewOfVolumeRelativeRelVol;
def minEoM = LowestAll(EaseOfMovement);
def maxEoM = HighestAll(EaseOfMovement);
def normalizedEase = 1 + (((EaseOfMovement - minEoM) / (maxEoM - minEoM)) * 100);
 # Nice to plot as Histogram
def WinsorizingMinEOM =  simpleMovingAvg(normalizedEase, 144);;
def WinzoringForcedMaxEOM=100 - WinsorizingMinEOM;
def WinsorizedEOM = if normalizedEase> WinzoringForcedMaxEOM then WinzoringForcedMaxEOM else if normalizedEase < WinsorizingPercentage then WinsorizingPercentage else normalizedEase;
def minNormalizedEoM=Lowestall(WinsorizedEOM);
def maxNormalizedEoM=Highestall(WinsorizedEOM);
plot ViewOfVolumeRelativeEoM =1 + (((WinsorizedEOM - minNormalizedEoM) / (maxNormalizedEoM - minNormalizedEoM)) * 100);
# Nice to plot as Histogram

input   FirstEasiestOrderFlow1st= 60; #hint FirstEasiestOrderFlow1st:
input  SecondEasiestOrderFlow2nd= 50; #hint SecondEasiestOrderFlow2nd:
input   ThirdEasiestOrderFlow3rd= 40; #hint ThirdEasiestOrderFlow3rd:
input   FouthEasiestOrderFlow4th= 30; #hint FouthEasiestOrderFlow4th:
input   FifthEasiestOrderFlow5th= 20; #hint FifthEasiestOrderFlow5th:
input   SixthEasiestOrderFlow6th= 15; #hint SixthEasiestOrderFlow6th:
input SeventhEasiestOrderFlow7th= 10; #hint SeventhEasiestOrderFlow7th:
input  EighthEasiestOrderFlow8th= 5; #hint EighthEasiestOrderFlow8th:

AssignPriceColor(
 if ViewOfVolumeRelativeEoM > FirstEasiestOrderFlow1st then GlobalColor("1stStrongest")
 else if ViewOfVolumeRelativeEoM > SecondEasiestOrderFlow2nd then GlobalColor("2ndStrongest")
 else if ViewOfVolumeRelativeEoM > ThirdEasiestOrderFlow3rd then GlobalColor("3rdStrongest")
 else if ViewOfVolumeRelativeEoM > FouthEasiestOrderFlow4th then GlobalColor("4thStrongest")
 else if ViewOfVolumeRelativeEoM > FifthEasiestOrderFlow5th then GlobalColor("5thStrongest")
 else if ViewOfVolumeRelativeEoM > SixthEasiestOrderFlow6th then GlobalColor("6thStrongest")
 else if ViewOfVolumeRelativeEoM > SeventhEasiestOrderFlow7th then GlobalColor("7thStrongest")
 else if ViewOfVolumeRelativeEoM > EighthEasiestOrderFlow8th then GlobalColor("8thStrongest")
 else Color.Black);

# Final FOM solution to draw the 'Defended Price Line' (DPL) where trading is overencumbered with Volumes...
#We expect choppiness and erratic stop outs to randomly provide and restrict liquidity near DPLs and we prefer not to trade in these DIFFICULT DPLs.
def FreedomMOVEMENT = ViewOfVolumeRelativeRelVol / normalizedMOVE;
def relFOM = 1/ViewOfVolumeRelativeEoM;
def minFOM = LowestAll(relFOM);
def maxFOM = HighestAll(relFOM);
def normalizedFOM = 1 + (((relFOM - minFOM) / (maxFOM - minFOM)) * 100); # Plot as volume


def DPLlimitLength = 60;
def DPLcheck =  (MovingAverage(AverageType.WEIGHTED, normalizedFOM, DPLlimitLength));
plot DefendedPriceLineDPL = if normalizedFOM > ((DPLcheck/2)+DPLthreshold) then close else Double.NaN;
def DPLcount= if !isNAN(DefendedPriceLineDPL) then DPLcount[1]+1 else DPLcount[1];
DefendedPriceLineDPL.setPaintingStrategy(PaintingStrategy.Squares);
DefendedPriceLineDPL.SetDefaultColor(GlobalColor("DifficultPriceLine")); DefendedPriceLineDPL.hideBubble(); DefendedPriceLineDPL.hideTitle();
DefendedPriceLineDPL.SetLineWeight(5);
addLabel(1,"| " + DPLcount  + " DPLs (Difficult Price Lines) ◽--- " + DPLthreshold +"% level |",GlobalColor("DifficultPriceLine"));

#Assign DPL lines at specific points
#######################################

rec DPLcounter;
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] < 20) {
DPLcounter =DPLcounter[1] + 1;
} else {
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] == 20) {
DPLcounter = 1;
} else {
DPLcounter =DPLcounter[1];
}
};
rec DifficultPrice1;
if DPLcounter==1 && DPLcounter[1]!=1 {
DifficultPrice1= close; } else {DifficultPrice1=CompoundValue(1, DifficultPrice1[1], NAN);};
plot DPL1=DifficultPrice1;
DPL1.SetPaintingStrategy(PaintingStrategy.DASHES); DPL1.hideBubble(); DPL1.hideTitle();
DPL1.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL1.SetLineWeight(1);

rec DifficultPrice2;
if DPLcounter==2 && DPLcounter[1]!=2 {
DifficultPrice2= close; } else {DifficultPrice2=CompoundValue(1, DifficultPrice2[1], NAN);};
plot DPL2=DifficultPrice2;
DPL2.SetPaintingStrategy(PaintingStrategy.DASHES); DPL2.hideBubble(); DPL2.hideTitle();
DPL2.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL2.SetLineWeight(1);

rec DifficultPrice3;
if DPLcounter==3 && DPLcounter[1]!=3 {
DifficultPrice3= close; } else {DifficultPrice3=CompoundValue(1, DifficultPrice3[1], NAN);};
plot DPL3=DifficultPrice3;
DPL3.SetPaintingStrategy(PaintingStrategy.DASHES); DPL3.hideBubble(); DPL3.hideTitle();
DPL3.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL3.SetLineWeight(1);

rec DifficultPrice4;
if DPLcounter==4 && DPLcounter[1]!=4 {
DifficultPrice4= close; } else {DifficultPrice4=CompoundValue(1, DifficultPrice4[1], NAN);};
plot DPL4=DifficultPrice4;
DPL4.SetPaintingStrategy(PaintingStrategy.DASHES); DPL4.hideBubble(); DPL4.hideTitle();
DPL4.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL4.SetLineWeight(1);

rec DifficultPrice5;
if DPLcounter==5 && DPLcounter[1]!=5 {
DifficultPrice5= close; } else {DifficultPrice5=CompoundValue(1, DifficultPrice5[1], NAN);};
plot DPL5=DifficultPrice5;
DPL5.SetPaintingStrategy(PaintingStrategy.DASHES); DPL5.hideBubble(); DPL5.hideTitle();
DPL5.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL5.SetLineWeight(1);

rec DifficultPrice6;
if DPLcounter==6 && DPLcounter[1]!=6 {
DifficultPrice6= close; } else {DifficultPrice6=CompoundValue(1, DifficultPrice6[1], NAN);};
plot DPL6=DifficultPrice6;
DPL6.SetPaintingStrategy(PaintingStrategy.DASHES); DPL6.hideBubble(); DPL6.hideTitle();
DPL6.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL6.SetLineWeight(1);

rec DifficultPrice7;
if DPLcounter==7 && DPLcounter[1]!=7 {
DifficultPrice7= close; } else {DifficultPrice7=CompoundValue(1, DifficultPrice7[1], NAN);};
plot DPL7=DifficultPrice7;
DPL7.SetPaintingStrategy(PaintingStrategy.DASHES); DPL7.hideBubble(); DPL7.hideTitle();
DPL7.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL7.SetLineWeight(1);

rec DifficultPrice8;
if DPLcounter==8 && DPLcounter[1]!=8 {
DifficultPrice8= close; } else {DifficultPrice8=CompoundValue(1, DifficultPrice8[1], NAN);};
plot DPL8=DifficultPrice8;
DPL8.SetPaintingStrategy(PaintingStrategy.DASHES); DPL8.hideBubble(); DPL8.hideTitle();
DPL8.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL8.SetLineWeight(1);

rec DifficultPrice9;
if DPLcounter==9 && DPLcounter[1]!=9 {
DifficultPrice9= close; } else {DifficultPrice9=CompoundValue(1, DifficultPrice9[1], NAN);};
plot DPL9=DifficultPrice9;
DPL9.SetPaintingStrategy(PaintingStrategy.DASHES); DPL9.hideBubble(); DPL9.hideTitle();
DPL9.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL9.SetLineWeight(1);

rec DifficultPrice10;
if DPLcounter==10 && DPLcounter[1]!=10 {
DifficultPrice10= close; } else {DifficultPrice10=CompoundValue(1, DifficultPrice10[1], NAN);};
plot DPL10=DifficultPrice10;
DPL10.SetPaintingStrategy(PaintingStrategy.DASHES); DPL10.hideBubble(); DPL10.hideTitle();
DPL10.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL10.SetLineWeight(1);

rec DifficultPrice11;
if DPLcounter==11 && DPLcounter[1]!=11 {
DifficultPrice11= close; } else {DifficultPrice11=CompoundValue(1, DifficultPrice11[1], NAN);};
plot DPL11=DifficultPrice11;
DPL11.SetPaintingStrategy(PaintingStrategy.DASHES); DPL11.hideBubble(); DPL11.hideTitle();
DPL11.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL11.SetLineWeight(1);

rec DifficultPrice12;
if DPLcounter==12 && DPLcounter[1]!=12 {
DifficultPrice12= close; } else {DifficultPrice12=CompoundValue(1, DifficultPrice12[1], NAN);};
plot DPL12=DifficultPrice12;
DPL12.SetPaintingStrategy(PaintingStrategy.DASHES); DPL12.hideBubble(); DPL12.hideTitle();
DPL12.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL12.SetLineWeight(1);

rec DifficultPrice13;
if DPLcounter==13 && DPLcounter[1]!=13 {
DifficultPrice13= close; } else {DifficultPrice13=CompoundValue(1, DifficultPrice13[1], NAN);};
plot DPL13=DifficultPrice13;
DPL13.SetPaintingStrategy(PaintingStrategy.DASHES); DPL13.hideBubble(); DPL13.hideTitle();
DPL13.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL13.SetLineWeight(1);

rec DifficultPrice14;
if DPLcounter==14 && DPLcounter[1]!=14 {
DifficultPrice14= close; } else {DifficultPrice14=CompoundValue(1, DifficultPrice14[1], NAN);};
plot DPL14=DifficultPrice14;
DPL14.SetPaintingStrategy(PaintingStrategy.DASHES); DPL14.hideBubble(); DPL14.hideTitle();
DPL14.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL14.SetLineWeight(1);

rec DifficultPrice15;
if DPLcounter==15 && DPLcounter[1]!=15 {
DifficultPrice15= close; } else {DifficultPrice15=CompoundValue(1, DifficultPrice15[1], NAN);};
plot DPL15=DifficultPrice15;
DPL15.SetPaintingStrategy(PaintingStrategy.DASHES); DPL15.hideBubble(); DPL15.hideTitle();
DPL15.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL15.SetLineWeight(1);

rec DifficultPrice16;
if DPLcounter==16 && DPLcounter[1]!=16 {
DifficultPrice16= close; } else {DifficultPrice16=CompoundValue(1, DifficultPrice16[1], NAN);};
plot DPL16=DifficultPrice16;
DPL16.SetPaintingStrategy(PaintingStrategy.DASHES); DPL16.hideBubble(); DPL16.hideTitle();
DPL16.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL16.SetLineWeight(1);


rec DifficultPrice17;
if DPLcounter==17 && DPLcounter[1]!=17 {
DifficultPrice17= close; } else {DifficultPrice17=CompoundValue(1, DifficultPrice17[1], NAN);};
plot DPL17=DifficultPrice17;
DPL17.SetPaintingStrategy(PaintingStrategy.DASHES); DPL17.hideBubble(); DPL17.hideTitle();
DPL17.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL17.SetLineWeight(1);

rec DifficultPrice18;
if DPLcounter==18 && DPLcounter[1]!=18 {
DifficultPrice18= close; } else {DifficultPrice18=CompoundValue(1, DifficultPrice18[1], NAN);};
plot DPL18=DifficultPrice18;
DPL18.SetPaintingStrategy(PaintingStrategy.DASHES); DPL18.hideBubble(); DPL18.hideTitle();
DPL18.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL18.SetLineWeight(1);

rec DifficultPrice19;
if DPLcounter==19 && DPLcounter[1]!=19 {
DifficultPrice19= close; } else {DifficultPrice19=CompoundValue(1, DifficultPrice19[1], NAN);};
plot DPL19=DifficultPrice19;
DPL19.SetPaintingStrategy(PaintingStrategy.DASHES); DPL19.hideBubble(); DPL19.hideTitle();
DPL19.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL19.SetLineWeight(1);


rec DifficultPrice20;
if DPLcounter==20 && DPLcounter[1]!=20 {
DifficultPrice20= close; } else {DifficultPrice20=CompoundValue(1, DifficultPrice20[1], NAN);};
plot DPL20=DifficultPrice20;
DPL20.SetPaintingStrategy(PaintingStrategy.DASHES); DPL20.hideBubble(); DPL20.hideTitle();
DPL20.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL20.SetLineWeight(1);

### Caution Relative Volume compares the current OrderFlow to the Volume of the EXACT same time of day for several times. For instance the Volume usually increases in the first minute after 9:30 AM EST as the NewYork WallStreet Opens... It would be completely meaningless to compare the open Volume to any other time of day except the market open of the previous days.
#Testing enough Data is loaded to calculate Relative Volumes
def CalendarDays = GetYYYYMMDD();
def NumberOfCalendarDaysOnChart = DaysFromDate(First(CalendarDays)) + GetDayOfWeek(First(CalendarDays));
AddLabel(NumberOfCalendarDaysOnChart <10, "RelativeVolume Error: Only " + NumberOfCalendarDaysOnChart + " days loaded on chart...Please add more days", Color.RED);


AddLabel(PastPriceMovePercent <40, " Caution: RelativePriceMove is only " + PastPriceMovePercent + " %. Please consider a larger relative price comparison to the past days.", Color.YELLOW);
 
Code:
#____   ____.__                        _____  ____   ____    .__                       
#\   \ /   /|__| ______  _  __   _____/ ____\ \   \ /   /___ |  |  __ __  _____   ____ 
# \   V   / |  |/ __ \ \/ \/ /  /  _ \   __\   \   V   /  _ \|  | |  |  \/     \_/ __ \
#  \     /  |  \  ___/\     /  (  <_> )  |      \     (  <_> )  |_|  |  /  | |  \  ___/
#   \___/   |__|\___/  \/\_/    \____/|__|       \___/ \____/|____/____/|__|_|  /\___/
                                                                                                                                                  

#         _                              ___ _ _     
# _ _ ___| |_ _ _____ ___    ___ ___ ___|  _|_| |___
#| | | . | | | |     | -_|  | . |  _| . |  _| | | -_|
# \_/|___|_|___|_|_|_|___|  |  _|_| |___|_| |_|_|___|
#                           |_|                     


# Special thanks to Welkin from UseThinkScript.com

# For any asset, knowing the volume of trades is useless without context.
# We must be include patterns which are out of view of most charts.
# Large spikes and drops of Volume must considered relattive to the delta of price and the time of occurance. 

# There is a strong statistical link between the afternoon and overnight volumes and the ease of which the market will trend into the following day.


def h=high; def l=low; def hlc=hlc3; def NAN=double.NAN;
input SpacesLabels = 10; #hint SpacesLabels: The number of spaces you wish to extend the Labels to make viewing easier.
def b  = SpacesLabels;
def b1 = b + 1;
input MarketOpenTime= 0930;#hint MarketOpenTime: Time to begin the morning session, regular trading hours RTH.
input AfternoonSessionTime = 1515; #hint AfternoonSessionTime: Time to begin the afternoon session that you wish to compare to the next day.
 
def BeginAfternoonSession= if SecondsTillTime(AfternoonSessionTime) crosses below 1 then yes else no;
def BeginEveningSession= if GetTime() crosses above RegularTradingEnd(GetYYYYMMDD()) then yes else no;
def EndEveningSession = if GetTime() crosses above RegularTradingStart(GetYYYYMMDD())then yes else no;

def FindAfternoonHigh = if BeginAfternoonSession then h else if !BeginAfternoonSession && h > FindAfternoonHigh[1] then h else if !BeginAfternoonSession  && h <= FindAfternoonHigh[1] then FindAfternoonHigh[1] else h;
def SelectAfternoonHigh = if BeginEveningSession then FindAfternoonHigh[1] else SelectAfternoonHigh[1];
Plot AfternoonSessionHigh = SelectAfternoonHigh;
def FindAfternoonLow = if BeginAfternoonSession then l else if !BeginAfternoonSession && l < FindAfternoonLow[1] then l else if !BeginAfternoonSession  && l >= FindAfternoonLow[1] then FindAfternoonLow[1] else l;
def SelectAfternoonLow = if BeginEveningSession then FindAfternoonLow[1] else SelectAfternoonLow[1];
Plot AfternoonSessionLow = SelectAfternoonLow;

def FindOvernightHigh = if BeginEveningSession then h else if !BeginEveningSession && h > FindAfternoonHigh[1] then h else if !BeginEveningSession  && h <= FindOvernightHigh[1] then FindOvernightHigh[1] else h;
def SelectOvernightHigh = if EndEveningSession then FindOvernightHigh[1] else SelectOvernightHigh[1];
Plot OvernightHigh = SelectOvernightHigh;
def FindOvernightLow = if BeginEveningSession then l else if !BeginEveningSession && l < FindOvernightLow[1] then l else if !BeginEveningSession  && l >= FindOvernightLow[1] then FindOvernightLow[1] else l;
def SelectOvernightLow = if EndEveningSession then FindOvernightLow[1] else SelectOvernightLow[1];
Plot OvernightLow = SelectOvernightLow;


def SimpleTrendsFromPastVolumes = if h > min(OvernightHigh,AfternoonSessionHigh) then +1 else if l<max(OvernightLow,AfternoonSessionLow) then -1 else 0;
AfternoonSessionHigh.setdefaultColor(color.gray);
AfternoonSessionHigh.assignValueColor(if h>=AfternoonSessionHigh && SimpleTrendsFromPastVolumes==1 then color.green else if l<= AfternoonSessionHigh && SimpleTrendsFromPastVolumes==-1 then color.red else color.blue); AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), AfternoonSessionHigh[b1], "Yesterday Afternoon High", color.blue, yes);
AfternoonSessionLow.setdefaultColor(color.gray);
AfternoonSessionLow.assignValueColor(if h>=AfternoonSessionLow && SimpleTrendsFromPastVolumes==1 then color.green else if l<= AfternoonSessionLow && SimpleTrendsFromPastVolumes==-1 then color.red else color.blue);; AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), AfternoonSessionLow[b1], "Yesterday Afternoon Low", color.blue, no);
OvernightHigh.setdefaultColor(color.gray);
OvernightHigh.assignValueColor(if h>=OvernightHigh && SimpleTrendsFromPastVolumes==1 then color.green else if l<= OvernightHigh && SimpleTrendsFromPastVolumes==-1 then color.red else color.blue); AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), OvernightHigh[b1], "Overnight High", color.blue, yes);
OvernightLow.setdefaultColor(color.gray);
OvernightLow.assignValueColor(if h>=OvernightLow && SimpleTrendsFromPastVolumes==1 then color.green else if l<= OvernightLow && SimpleTrendsFromPastVolumes==-1 then color.red else color.blue); AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]),OvernightLow[b1], "Overnight Low", color.blue, no);



def isETH = CompoundValue(1, if BeginAfternoonSession then 1 else if EndEveningSession then 0 else isETH[1], 0);
def isAfterHoursSessions  = if isETH
                    then 1
                    else 0;

input pricePerRowHeightMode = { AUTOMATIC, default TICKSIZE}; #hint pricePerRowHeightMode: There are often advantages to using Tick data when possible.
input multiplier = 1;
def onExpansion = no;
input profiles = 10;
input valueAreaPercent =65;

def cond          = isAfterHoursSessions[1] != isAfterHoursSessions;
def profilecount  = if cond then profilecount[1] + 1 else profilecount[1];
def profiletoday  = HighestAll(profilecount) - profilecount ;

def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
}

profile OvernightVolume = VolumeProfile("startNewProfile" = cond, "onExpansion" = no, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def OvernightCON = CompoundValue(1, onExpansion, no);

def OvernightPointOfControl = if IsNaN(close) then OvernightPointOfControl[1] else if IsNaN(OvernightVolume.GetPointOfControl()) and OvernightCON then OvernightPointOfControl[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetPointOfControl() else OvernightPointOfControl[1];
def OvernightHVA = if IsNaN(close) then OvernightHVA[1] else if IsNaN(OvernightVolume.GetHighestValueArea()) and OvernightCON then OvernightHVA[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetHighestValueArea() else OvernightHVA[1];
def OvernightLVA = if IsNaN(close) then OvernightLVA[1] else if IsNaN(OvernightVolume.GetLowestValueArea()) and OvernightCON then OvernightLVA[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetLowestValueArea() else OvernightLVA[1];

plot OvernightPOC    = OvernightPointOfControl;
plot OvernightVAHigh = OvernightHVA;
plot OvernightVALow  = OvernightLVA;
DefineGlobalColor("Overnight POC Lines", color.Dark_gray);
OvernightPOC.SetDefaultColor(GlobalColor("Point Of Control"));OvernightPOC.SetPaintingStrategy(PaintingStrategy.Line); OvernightPOC.setLineWeight(4);
OvernightVAHigh.SetPaintingStrategy(PaintingStrategy.Line);OvernightVAHigh.SetDefaultColor(GlobalColor("Value Area")); OvernightVAHigh.setLineWeight(2);
OvernightVALow.SetPaintingStrategy(PaintingStrategy.Line);OvernightVALow.SetDefaultColor(GlobalColor("Value Area")); OvernightVALow.setLineWeight(2);

AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]), OvernightPOC[b1], "Overnight POC Lines", OvernightPOC.TakeValueColor(),yes);
AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]), OvernightVAHigh[b1], "Overnight POC Lines", OvernightVAHigh.TakeValueColor(),yes);
AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]),OvernightVALow[b1], "Overnight POC Lines",OvernightVALow.TakeValueColor(), no);

plot PointOfControlClouds = NAN;
PointOfControlClouds.HideBubble();
PointOfControlClouds.HideTitle();
PointOfControlClouds.DefineColor("OvernightPointOfControlArea", color.Dark_gray);
AddCloud(OvernightVAHigh, OvernightVALow, PointOfControlClouds.Color("OvernightPointOfControlArea"));


input RandomWalkDriftingLength =33;#hint RandomWalkDriftingLength: This is the length the indicator will use to segment volume profiles with Non-repainting pivots.
def bnOK = BarNumber() > RandomWalkDriftingLength;
def isHigher = fold f = 1 to RandomWalkDriftingLength + 1 with p = 1
               while p do h > GetValue(h, -f);
def HH = if bnOK and isHigher
         and h == Highest(h, RandomWalkDriftingLength)
         then h else NAN;
def isLower = fold j = 1 to RandomWalkDriftingLength + 1 with q = 1
              while q do l < GetValue(l, -j);
def LL = if bnOK and isLower
         and l == Lowest(l, RandomWalkDriftingLength)
         then l else NAN;

def PivH = if HH > 0 then 1 else 0;
def PivL = if LL > 0 then 1 else 0;

rec dir = CompoundValue(1, if !IsNaN(PivL) then 1 else if !IsNaN(PivH) then -1 else dir[1], 0);

def Dn = dir crosses above 0;
def Up = dir crosses below 0;

def UpTime = if Up then 1 else UpTime[1] + 1;
def NewUp = if Up then h else NewUp[1]; # Recent High

def DownTime = if Dn then 1 else DownTime[1] + 1;
def NewDown = if Dn then l else NewDown[1]; # Recent Low

##############
### CLOCK ####
##############
def yyyymmdd = GetYYYYMMDD();
def seconds = SecondsFromTime(0);
def month = GetYear() * 12 + GetMonth();
def year = GetYear();
def day_number = DaysFromDate(First(yyyymmdd)) + GetDayOfWeek(First(yyyymmdd));
def dom = GetDayOfMonth(yyyymmdd);
def dow = GetDayOfWeek(yyyymmdd - dom + 1);
def expthismonth = (if dow > 5 then 27 else 20) - dow;
def exp_opt = month + (dom > expthismonth);
def timeOfPhaseProfile=BarNumber()-1;
####################################
# TICKS: Show true Volume at Price #
####################################
def ExpandTheLinesToNextSegment=no;
input NumberOfVolumeProfiles =50; #hint NumberOfVolumeProfiles: The number of Volume Profiles you wish to view.
input ProfilevalueAreaPercent =65;# ProfilevalueAreaPercent: The % of all Volume traded in the profile that you wish to focus on your profiles.
def NewVolumeProfile = if DownTime ==1 or UpTime ==1 then 1 else NAN;
input ShowPOCclouds=no;# hint ShowPOCclouds: Use to highlight the higher Volume areas of the Volume Profile.

profile vol = volumeProfile("startNewProfile" = (NewVolumeProfile), "onExpansion" = ExpandTheLinesToNextSegment, "numberOfProfiles" = NumberOfVolumeProfiles, "pricePerRow" = PricePerRow.TICKSIZE, "value area percent" = ProfilevalueAreaPercent);
input ProfileTransparency =75;#hint ProfileTransparency: The Transparency of the Volume Profiles
vol.Show(createcolor(0,0,150), if ShowPOCclouds then createcolor(0,0,150) else Color.Current, if ShowPOCclouds then createcolor(0,0,150) else Color.Current, ProfileTransparency);



def con = compoundValue(1, ExpandTheLinesToNextSegment, no);
def pc = if IsNaN(vol.getPointOfControl()) and con then pc[1] else vol.getPointOfControl();
def hVA = if IsNaN(vol.getHighestValueArea()) and con then hVA[1] else vol.getHighestValueArea();
def lVA = if IsNaN(vol.getLowestValueArea()) and con then lVA[1] else vol.getLowestValueArea();

def hProfile = if IsNaN(vol.getHighest()) and con then hProfile[1] else vol.getHighest();
def lProfile = if IsNaN(vol.getLowest()) and con then lProfile[1] else vol.getLowest();
def plotsDomain = IsNaN(close) == ExpandTheLinesToNextSegment;

DefineGlobalColor("Point Of Control", color.Blue);
DefineGlobalColor("Value Area", createcolor(0,0,150));
plot POC = if plotsDomain then pc else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;

POC.SetDefaultColor(globalColor("Point Of Control")); POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); POC.HideBubble(); POC.HideTitle(); POC.setLineWeight(3);
VAHigh.SetPaintingStrategy(PaintingStrategy.Line); VAHigh.SetDefaultColor(Color.Blue); VAHigh.hideBubble(); VAHigh.HideTitle(); VAHigh.setLineWeight(1);
VALow.SetPaintingStrategy(PaintingStrategy.Line); VALow.SetDefaultColor(Color.Blue); VALow.HideBubble(); VALow.HideTitle(); VALow.setLineWeight(1);

#plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
#plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
#ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); ProfileHigh.SetDefaultColor(Color.Dark_Green); #ProfileHigh.hideBubble(); ProfileHigh.HideTitle(); ProfileHigh.setLineWeight(1);
#ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); ProfileLow.SetDefaultColor(Color.Dark_Red); #ProfileLow.hideBubble();  ProfileLow.HideTitle(); ProfileLow.setLineWeight(1);
 
ViewOfVolume2.0.png

I need to explain in greater detail why Viewing Volume this way relaxes me.
Tonight I have to start on a literature review about preventing patients from bleeding out in the ER, and so I may be absent for a little while longer.

In the meantime would you wonderful people please verify that you are not being let down with poor performance and ' repainting ' ... 🙏
 
n the meantime would you wonderful people please verify that you are not being let down with poor performance and ' repainting ' ...

@MatthewA I hope this reply finds you've successfully concluded your literature review...I have quite a bit of work in front of me at the moment, but as soon as I can clear my desk, I will be focusing on your latest Volume Profile/Dynamic Relative Volume system...

Thank you for your time and attention to this endeavor...Much appreciated! 😎
 
@MatthewA I hope this reply finds you've successfully concluded your literature review...I have quite a bit of work in front of me at the moment, but as soon as I can clear my desk, I will be focusing on your latest Volume Profile/Dynamic Relative Volume system...

Thank you for your time and attention to this endeavor...Much appreciated! 😎
I aced some online assignments today but it's taking me a bit longer than I hoped to start writing. I'm also trying to work on my pronunciation of the medical words. I regret not speaking aloud when watching dramas like Grey's anatomy LOL 😅 that's how some people learned perfect pronunciation.

I appreciate all the feedback on coding. I'm also curious how we will add more Volatility indicators @chewie76 @Ramisegal @mashume without overcrowding the charts.
Whenever @Welkin would screen share with me he would explain that he used a LOT of charts on big TV screens and he had some very tough disciplined eyes as well... 👁

Anyway before I get ambitious I want to confirm that ViewOfVolume2.0 can run well on the 1 minute 15 day chart without lagging (repainting) for anyone. Then we can worry about adding the next parts that you will want.
 
I'm also curious how we will add more Volatility indicators @chewie76 @Ramisegal @mashume without overcrowding the charts.
From where I'm sitting, it seems that there is enough room for three lower indicators on a chart without crushing the upper chart...How many Volatility indicators are you thinking of adding?

Anyway before I get ambitious I want to confirm that ViewOfVolume2.0 can run well on the 1 minute 15 day chart without lagging (repainting) for anyone. Then we can worry about adding the next parts that you will want.
No worries...I'll set it up tonight and let you know how it goes...

One question, if I may...Is there no lower Relative Volume indicator in v2.0?
 
From where I'm sitting, it seems that there is enough room for three lower indicators on a chart without crushing the upper chart...How many Volatility indicators are you thinking of adding?


No worries...I'll set it up tonight and let you know how it goes...

One question, if I may...Is there no lower Relative Volume indicator in v2.0?
No sir there are no lower indicators to show relative Volume this time.
The winsorizing technique should hopefully use relative Volume to consistsntly derive an EASY Eease Of Movement EoM and warn us of DIFFICULT Difficult Price Lines DPL...

It may require gentle adjustments to the filtering % values but I certainly do not expect any more awful lagging 🙂
 
chart...How many Volatility indicators are you thinking of adding?
It certainly never hurts to try things.
I intend to try any and all suggestions.
Hopefully we may reach the point where able to claim that we have priced in Volume & Volatility together ❤️ 🙏 😀

@Welkin always saw Volatility related terms as a measure of a natural delay to a silly "over reaction" in the markets.
Relative to what he considered to be minor corrections over the long course. Some of his instincts still elude me even after taking notes and watching him 😅
 
The winsorizing technique should hopefully use relative Volume to consistsntly derive an EASY Eease Of Movement EoM and warn us of DIFFICULT Difficult Price Lines DPL...
@MatthewA I'm looking forward to seeing the Winsorizing in action... 😎

Would it be possible to add candle-coloring (AssignPriceColor()) to the Dynamic Relative Volume to help delineate visually between EOM (Green) and DPL (Red)...Not to jump ahead, but I've already taken the liberty of setting up the DefineGlobals for the colors in the hopes that I may be able to help...

Code:
RED (Difficult Price Lines ( DPLs ))

DefineGlobalColor("1stStrongest", CreateColor(247,131,131));
DefineGlobalColor("2ndStrongest", CreateColor(219,129,129));
DefineGlobalColor("3rdStrongest", CreateColor(196,117,117));
DefineGlobalColor("4thStrongest", CreateColor(168,112,117));
DefineGlobalColor("5thStrongest", CreateColor(149,104,106));
DefineGlobalColor("6thStrongest", CreateColor(135,100,101));
DefineGlobalColor("7thStrongest", CreateColor(122,92,93));
DefineGlobalColor("8thStrongest", CreateColor(105,78,78));


GREEN (Ease Of Movement ( EoM ))

DefineGlobalColor("1stStrongest", CreateColor(107,177,92));
DefineGlobalColor("2ndStrongest", CreateColor(102,157,90));
DefineGlobalColor("3rdStrongest", CreateColor(93,140,82));
DefineGlobalColor("4thStrongest", CreateColor(90,120,79));
DefineGlobalColor("5thStrongest", CreateColor(81,107,73));
DefineGlobalColor("6thStrongest", CreateColor(76,98,70));
DefineGlobalColor("7thStrongest", CreateColor(71,88,65));
DefineGlobalColor("8thStrongest", CreateColor(60,76,55));

I'm working on setting up the Dynamic Relative Volume and Volume Profile as I write this reply, so I should be able to give you some feedback on the performance shortly...I optimized my system for VoV 1.0, allocating/dedicating 8GB RAM to TOS and had it running pretty smoothly, so VoV 2.0 should run even smoother...hopefully... 😃
 
Last edited:
@MatthewA OK...I've spent some time acquainting myself with the VoV 2.0 scripts and realized I spoke to soon before regarding a candle-coloring scheme involving red and green...I've gathered that EOM is defining what to color the candles and DPL's are dashed lines colored together with one DefineGlobalColor(), but, of course, you already knew that 😉

With that said, I've taken the liberty again to go ahead and modify the scripts somewhat...Essentially I've made some granular UI adjustments...Line Thickness...Line Display (show/hide)...Color Tweaks...I am attaching the modified code for your review...I hope it meets with your approval...

Dynamic Relative Volume

Code:
#____   ____.__                        _____  ____   ____    .__                       
#\   \ /   /|__| ______  _  __   _____/ ____\ \   \ /   /___ |  |  __ __  _____   ____
# \   V   / |  |/ __ \ \/ \/ /  /  _ \   __\   \   V   /  _ \|  | |  |  \/     \_/ __ \
#  \     /  |  \  ___/\     /  (  <_> )  |      \     (  <_> )  |_|  |  /  | |  \  ___/
#   \___/   |__|\___/  \/\_/    \____/|__|       \___/ \____/|____/____/|__|_|  /\___/
                                                                    
                                                                                      
#   _                   _                _     _   _                    _               
# _| |_ _ ___ ___ _____|_|___    ___ ___| |___| |_|_|_ _ ___    _ _ ___| |_ _ _____ ___
#| . | | |   | .'|     | |  _|  |  _| -_| | .'|  _| | | | -_|  | | | . | | | |     | -_|
#|___|_  |_|_|__,|_|_|_|_|___|  |_| |___|_|__,|_| |_|\_/|___|   \_/|___|_|___|_|_|_|___|
#    |___|                                                                             

# Special thanks to Welkin from UseThinkScript.com

# For any asset, knowing the volume of trades is useless without context.
# We must include patterns which are out of view of most charts.
# Large spikes and drops of Volume must considered relative to the delta of price and the time of occurence.

#EOM colors: The Ease Of Movement ( EoM ) is the the amount of volume required to move prices. EoM was developed by Richard W. Arms, Jr., the creator of Equivolume.
#We will set the brightness of the price according to the Relative Dynamic EOM. Viewing bright EOM prices in a trending distribution indicates that it would be EASY for the trend to continue into that direction after the occasional retracements. Viewing bright EOM Volumes when the market is range-bound indicates which it will be EASY for price to drift in that range.

#DPL Lines:  We take a cautionary View of Difficult Price Lines ( DPLs ) to avoid Volumes where price will chop erratically, as these areas will be DIFFICULT to enter good trends and it is more comfortable to wait so that we may avoid uneccessary stress. The DPL lines are based on the works of Melvin E. Dickover, who developed FreedomOfMovement which takes into account price-volume behavior in order to detect points where movement of price is suddenly restricted. You may consider taking profits a bit before the next DPL line or wating to open your next position until the Difficult Volumes have weakened. You will notice that the DPL caclulations are much more accurate than simply drawing Support & Resistance Lines at recent Highs and Lows, however I would discourage the user from attempting to scalp off of bounces at the DPLs. We must take a long term View Of Volume to understand the price action as a whole.

# It is well known that Volume Accumulates while the market consolidates for the majority of time and Volume Distributes into strong trends. Only with a View of Volume can one understand when it would be more comfortable to wait or

declare upper;
declare hide_on_daily;
def h=high; def l=low; def hlc=hlc3; def c=close; def NAN=double.NAN;
input WinsorizingPercentage =5; #hint WinsorizingPercentage: % percentage to shift Normalized Values to prevent extreme arbitrary skewing.
# Traditionally Winsorizing works by replacing extreme High and Extreme Low values with and upper or lower common percentile median. However in our applicatoin we wish to simplfy the load on our computers and prevent wild shifts.

input DPLthreshold=95; #hint DPLthreshold: The required strength of a DPL where a Volume is expected to bring DIFFICULT erratic chop.

#DefineGlobalColor("1stStrongest", CreateColor(0,230,255));
#DefineGlobalColor("2ndStrongest", CreateColor(0,190,255));
#DefineGlobalColor("3rdStrongest", CreateColor(0,150,255));
#DefineGlobalColor("4thStrongest", CreateColor(0,110,255));
#DefineGlobalColor("5thStrongest", CreateColor(0,70,255));
#DefineGlobalColor("6thStrongest", CreateColor(0,0,200));
#DefineGlobalColor("7thStrongest", CreateColor(0,0,150));
#DefineGlobalColor("8thStrongest", CreateColor(0,0,100));

DefineGlobalColor("1stStrongest", CreateColor(107,177,92));
DefineGlobalColor("2ndStrongest", CreateColor(102,157,90));
DefineGlobalColor("3rdStrongest", CreateColor(93,140,82));
DefineGlobalColor("4thStrongest", CreateColor(90,120,79));
DefineGlobalColor("5thStrongest", CreateColor(81,107,73));
DefineGlobalColor("6thStrongest", CreateColor(76,98,70));
DefineGlobalColor("7thStrongest", CreateColor(71,88,65));
DefineGlobalColor("8thStrongest", CreateColor(60,76,55));

DefineGlobalColor("DifficultPriceLine", Color.RED); #createcolor(75,180,255));
# VOLUME SELECTION
# Unfortunately, tick data is only available for the past 5 days in ThinkScript Servers.
def shares = If(!IsNaN(volume), volume, 1);
def oi = If(!IsNaN(open_interest), open_interest, 1);
def iv = If(!IsNaN(imp_volatility), imp_volatility, .00001);
def v;
#hint volumeSource: Choose to use either Share Volume (normal volume), Shares Per Range which is Share Volume / Range chosen below, or Trades Per Range which is Trade Volume / Range chosen below. ToS servers only store tick data for 5 days...
input volumeSource = {
    default "Share Volume",   
    "OpenInterest",
    "Shares/OI",   
    "ImpliedVolatility",   
    "Shares/IV",
    "Shares*IV",
    "Trades/IV"
 
};
switch (volumeSource) {
case "Share Volume":
    v = shares;
case "OpenInterest":
    v = oi;
case "Shares/OI":
    v = shares / oi;
case "ImpliedVolatility":
    v = iv;
case "Shares/IV":
    v = shares / iv;
case "Shares*IV":
    v = shares * iv;
case "Trades/IV":
    v = shares / iv;
}

script prior {
    input of = close;
    def priorOf = if of != of[1] then of[1] else priorOf[1];
    plot
    prior = priorOf;
}

def x = BarNumber();
def x0 = if isNaN(close[-1]) and !isNaN(close) then x else x0[1]; # X0 periodization is required for the Winsorizing operation required later. Please read a bit about "Winsorization"
def rteBar = if GetTime() crosses above RegularTradingStart(GetYYYYMMDD()) then
               x else rteBar[1];
def priorRTEbar1  = prior(rteBar);
def priorRTEbar2  = prior(priorRTEbar1);
def priorRTEbar3  = prior(priorRTEbar2);
def priorRTEbar4  = prior(priorRTEbar3);
def priorRTEbar5  = prior(priorRTEbar4);
def priorRTEbar6  = prior(priorRTEbar5);
def priorRTEbar7  = prior(priorRTEbar6);

#Relative VOLUME portion
def pV1  = GetValue(v, rteBar - priorRTEbar1);
def pV2  = GetValue(v, rteBar - priorRTEbar2);
def pV3  = GetValue(v, rteBar - priorRTEbar3);
def pV4  = GetValue(v, rteBar - priorRTEbar4);
def pV5  = GetValue(v, rteBar - priorRTEbar5);
def pV6  = GetValue(v, rteBar - priorRTEbar6);
def pV7  = GetValue(v, rteBar - priorRTEbar7);

def avgPriorVol = (pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7) / 7;
def StdDevPriorVol = StDev(pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7);

def relVol = ( v - avgPriorVol ) / StdDevPriorVol;
def minVol = LowestAll(relVol);
def maxVol = HighestAll(relVol);
def normalizedRelativeVolume = 1 + (((relVol - minVol) / (maxVol - minVol)) * (100));

def relVolWinsorizeBaseline =  simpleMovingAvg(normalizedRelativeVolume, 1440);
def WinsorizingMin =  relVolWinsorizeBaseline + WinsorizingPercentage;
def WinzoringForcedMax=100 - WinsorizingMin;
def WinsorizedRelVol = if normalizedRelativeVolume> WinzoringForcedMax then WinzoringForcedMax else if normalizedRelativeVolume < WinsorizingMin then WinsorizingMin else normalizedRelativeVolume;
def minNormalizedRelVol=min(Lowestall(WinsorizedRelVol),WinsorizingPercentage);
def maxNormalizedRelVol=Highestall(WinsorizedRelVol);
def ViewOfVolumeRelativeRelVol = 1 + (((WinsorizedRelVol - minNormalizedRelVol) / (maxNormalizedRelVol - minNormalizedRelVol)) * 100); # Plot as Histogram


#Relative PRICE MOVE
input PastPriceMovePercent=50; #hint PastPriceMovePercent: The 0-100% normalized% of the price move which is compared relative to priceActionIndicator moves of previous days. Preferably greater than 50%.
def PriorDayPriceMOVE = AbsValue((hlc - hlc[1]) / (hlc[1]));
def pM1  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar1);
def pM2  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar2);
def pM3  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar3);
def pM4  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar4);
def pM5  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar5);
def pM6  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar6);
def pM7  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar7);

def avgPriorMOVE = (pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7 ) / 7;
def StdDevPriorMOVE = StDev(pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7);
def relMOVE = ((( PriorDayPriceMOVE - avgPriorMOVE) / StdDevPriorMOVE) * (PastPriceMovePercent)) + ((PriorDayPriceMOVE) * (100 - PastPriceMovePercent));
def minMOVE = LowestAll(relMOVE);
def maxMOVE = HighestAll(relMOVE);
def normalizedMOVE = 1 + (((relMOVE - minMOVE) / (maxMOVE - minMOVE)) * (100));

# Final EASEOfMovement solution to highlight price moves which may occur in smooth trends from low orderflow....
# Strong EOMs from trends are likely to continue in the direction of that trend after the occasional pause.
# Strong EOMs that do not outside of strong trends are likely to revisit the same prices.
def EaseOfMovement = normalizedMOVE / ViewOfVolumeRelativeRelVol;
def minEoM = LowestAll(EaseOfMovement);
def maxEoM = HighestAll(EaseOfMovement);
def normalizedEase = 1 + (((EaseOfMovement - minEoM) / (maxEoM - minEoM)) * 100);
 # Nice to plot as Histogram
def WinsorizingMinEOM =  simpleMovingAvg(normalizedEase, 144);;
def WinzoringForcedMaxEOM=100 - WinsorizingMinEOM;
def WinsorizedEOM = if normalizedEase> WinzoringForcedMaxEOM then WinzoringForcedMaxEOM else if normalizedEase < WinsorizingPercentage then WinsorizingPercentage else normalizedEase;
def minNormalizedEoM=Lowestall(WinsorizedEOM);
def maxNormalizedEoM=Highestall(WinsorizedEOM);
plot ViewOfVolumeRelativeEoM =1 + (((WinsorizedEOM - minNormalizedEoM) / (maxNormalizedEoM - minNormalizedEoM)) * 100);
# Nice to plot as Histogram

input   FirstEasiestOrderFlow1st= 60; #hint FirstEasiestOrderFlow1st:
input  SecondEasiestOrderFlow2nd= 50; #hint SecondEasiestOrderFlow2nd:
input   ThirdEasiestOrderFlow3rd= 40; #hint ThirdEasiestOrderFlow3rd:
input   FouthEasiestOrderFlow4th= 30; #hint FourthEasiestOrderFlow4th:
input   FifthEasiestOrderFlow5th= 20; #hint FifthEasiestOrderFlow5th:
input   SixthEasiestOrderFlow6th= 15; #hint SixthEasiestOrderFlow6th:
input SeventhEasiestOrderFlow7th= 10; #hint SeventhEasiestOrderFlow7th:
input  EighthEasiestOrderFlow8th= 5; #hint EighthEasiestOrderFlow8th:

AssignPriceColor(
 if ViewOfVolumeRelativeEoM > FirstEasiestOrderFlow1st then GlobalColor("1stStrongest")
 else if ViewOfVolumeRelativeEoM > SecondEasiestOrderFlow2nd then GlobalColor("2ndStrongest")
 else if ViewOfVolumeRelativeEoM > ThirdEasiestOrderFlow3rd then GlobalColor("3rdStrongest")
 else if ViewOfVolumeRelativeEoM > FouthEasiestOrderFlow4th then GlobalColor("4thStrongest")
 else if ViewOfVolumeRelativeEoM > FifthEasiestOrderFlow5th then GlobalColor("5thStrongest")
 else if ViewOfVolumeRelativeEoM > SixthEasiestOrderFlow6th then GlobalColor("6thStrongest")
 else if ViewOfVolumeRelativeEoM > SeventhEasiestOrderFlow7th then GlobalColor("7thStrongest")
 else if ViewOfVolumeRelativeEoM > EighthEasiestOrderFlow8th then GlobalColor("8thStrongest")
 else Color.Black);

# Final FOM solution to draw the 'Defended Price Line' (DPL) where trading is overencumbered with Volumes...
#We expect choppiness and erratic stop outs to randomly provide and restrict liquidity near DPLs and we prefer not to trade in these DIFFICULT DPLs.
def FreedomMOVEMENT = ViewOfVolumeRelativeRelVol / normalizedMOVE;
def relFOM = 1/ViewOfVolumeRelativeEoM;
def minFOM = LowestAll(relFOM);
def maxFOM = HighestAll(relFOM);
def normalizedFOM = 1 + (((relFOM - minFOM) / (maxFOM - minFOM)) * 100); # Plot as volume


def DPLlimitLength = 60;
def DPLcheck =  (MovingAverage(AverageType.WEIGHTED, normalizedFOM, DPLlimitLength));
plot DefendedPriceLineDPL = if normalizedFOM > ((DPLcheck/2)+DPLthreshold) then close else Double.NaN;
def DPLcount= if !isNAN(DefendedPriceLineDPL) then DPLcount[1]+1 else DPLcount[1];
DefendedPriceLineDPL.setPaintingStrategy(PaintingStrategy.Squares);
DefendedPriceLineDPL.SetDefaultColor(GlobalColor("DifficultPriceLine")); DefendedPriceLineDPL.hideBubble(); DefendedPriceLineDPL.hideTitle();
DefendedPriceLineDPL.SetLineWeight(5);
addLabel(1,"| " + DPLcount  + " DPLs (Difficult Price Lines) ◽--- " + DPLthreshold +"% level |",GlobalColor("DifficultPriceLine"));

#Assign DPL lines at specific points
#######################################

rec DPLcounter;
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] < 20) {
DPLcounter =DPLcounter[1] + 1;
} else {
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] == 20) {
DPLcounter = 1;
} else {
DPLcounter =DPLcounter[1];
}
};
rec DifficultPrice1;
if DPLcounter==1 && DPLcounter[1]!=1 {
DifficultPrice1= close; } else {DifficultPrice1=CompoundValue(1, DifficultPrice1[1], NAN);};
plot DPL1=DifficultPrice1;
DPL1.SetPaintingStrategy(PaintingStrategy.DASHES); DPL1.hideBubble(); DPL1.hideTitle();
DPL1.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL1.SetLineWeight(1);

rec DifficultPrice2;
if DPLcounter==2 && DPLcounter[1]!=2 {
DifficultPrice2= close; } else {DifficultPrice2=CompoundValue(1, DifficultPrice2[1], NAN);};
plot DPL2=DifficultPrice2;
DPL2.SetPaintingStrategy(PaintingStrategy.DASHES); DPL2.hideBubble(); DPL2.hideTitle();
DPL2.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL2.SetLineWeight(1);

rec DifficultPrice3;
if DPLcounter==3 && DPLcounter[1]!=3 {
DifficultPrice3= close; } else {DifficultPrice3=CompoundValue(1, DifficultPrice3[1], NAN);};
plot DPL3=DifficultPrice3;
DPL3.SetPaintingStrategy(PaintingStrategy.DASHES); DPL3.hideBubble(); DPL3.hideTitle();
DPL3.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL3.SetLineWeight(1);

rec DifficultPrice4;
if DPLcounter==4 && DPLcounter[1]!=4 {
DifficultPrice4= close; } else {DifficultPrice4=CompoundValue(1, DifficultPrice4[1], NAN);};
plot DPL4=DifficultPrice4;
DPL4.SetPaintingStrategy(PaintingStrategy.DASHES); DPL4.hideBubble(); DPL4.hideTitle();
DPL4.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL4.SetLineWeight(1);

rec DifficultPrice5;
if DPLcounter==5 && DPLcounter[1]!=5 {
DifficultPrice5= close; } else {DifficultPrice5=CompoundValue(1, DifficultPrice5[1], NAN);};
plot DPL5=DifficultPrice5;
DPL5.SetPaintingStrategy(PaintingStrategy.DASHES); DPL5.hideBubble(); DPL5.hideTitle();
DPL5.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL5.SetLineWeight(1);

rec DifficultPrice6;
if DPLcounter==6 && DPLcounter[1]!=6 {
DifficultPrice6= close; } else {DifficultPrice6=CompoundValue(1, DifficultPrice6[1], NAN);};
plot DPL6=DifficultPrice6;
DPL6.SetPaintingStrategy(PaintingStrategy.DASHES); DPL6.hideBubble(); DPL6.hideTitle();
DPL6.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL6.SetLineWeight(1);

rec DifficultPrice7;
if DPLcounter==7 && DPLcounter[1]!=7 {
DifficultPrice7= close; } else {DifficultPrice7=CompoundValue(1, DifficultPrice7[1], NAN);};
plot DPL7=DifficultPrice7;
DPL7.SetPaintingStrategy(PaintingStrategy.DASHES); DPL7.hideBubble(); DPL7.hideTitle();
DPL7.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL7.SetLineWeight(1);

rec DifficultPrice8;
if DPLcounter==8 && DPLcounter[1]!=8 {
DifficultPrice8= close; } else {DifficultPrice8=CompoundValue(1, DifficultPrice8[1], NAN);};
plot DPL8=DifficultPrice8;
DPL8.SetPaintingStrategy(PaintingStrategy.DASHES); DPL8.hideBubble(); DPL8.hideTitle();
DPL8.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL8.SetLineWeight(1);

rec DifficultPrice9;
if DPLcounter==9 && DPLcounter[1]!=9 {
DifficultPrice9= close; } else {DifficultPrice9=CompoundValue(1, DifficultPrice9[1], NAN);};
plot DPL9=DifficultPrice9;
DPL9.SetPaintingStrategy(PaintingStrategy.DASHES); DPL9.hideBubble(); DPL9.hideTitle();
DPL9.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL9.SetLineWeight(1);

rec DifficultPrice10;
if DPLcounter==10 && DPLcounter[1]!=10 {
DifficultPrice10= close; } else {DifficultPrice10=CompoundValue(1, DifficultPrice10[1], NAN);};
plot DPL10=DifficultPrice10;
DPL10.SetPaintingStrategy(PaintingStrategy.DASHES); DPL10.hideBubble(); DPL10.hideTitle();
DPL10.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL10.SetLineWeight(1);

rec DifficultPrice11;
if DPLcounter==11 && DPLcounter[1]!=11 {
DifficultPrice11= close; } else {DifficultPrice11=CompoundValue(1, DifficultPrice11[1], NAN);};
plot DPL11=DifficultPrice11;
DPL11.SetPaintingStrategy(PaintingStrategy.DASHES); DPL11.hideBubble(); DPL11.hideTitle();
DPL11.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL11.SetLineWeight(1);

rec DifficultPrice12;
if DPLcounter==12 && DPLcounter[1]!=12 {
DifficultPrice12= close; } else {DifficultPrice12=CompoundValue(1, DifficultPrice12[1], NAN);};
plot DPL12=DifficultPrice12;
DPL12.SetPaintingStrategy(PaintingStrategy.DASHES); DPL12.hideBubble(); DPL12.hideTitle();
DPL12.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL12.SetLineWeight(1);

rec DifficultPrice13;
if DPLcounter==13 && DPLcounter[1]!=13 {
DifficultPrice13= close; } else {DifficultPrice13=CompoundValue(1, DifficultPrice13[1], NAN);};
plot DPL13=DifficultPrice13;
DPL13.SetPaintingStrategy(PaintingStrategy.DASHES); DPL13.hideBubble(); DPL13.hideTitle();
DPL13.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL13.SetLineWeight(1);

rec DifficultPrice14;
if DPLcounter==14 && DPLcounter[1]!=14 {
DifficultPrice14= close; } else {DifficultPrice14=CompoundValue(1, DifficultPrice14[1], NAN);};
plot DPL14=DifficultPrice14;
DPL14.SetPaintingStrategy(PaintingStrategy.DASHES); DPL14.hideBubble(); DPL14.hideTitle();
DPL14.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL14.SetLineWeight(1);

rec DifficultPrice15;
if DPLcounter==15 && DPLcounter[1]!=15 {
DifficultPrice15= close; } else {DifficultPrice15=CompoundValue(1, DifficultPrice15[1], NAN);};
plot DPL15=DifficultPrice15;
DPL15.SetPaintingStrategy(PaintingStrategy.DASHES); DPL15.hideBubble(); DPL15.hideTitle();
DPL15.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL15.SetLineWeight(1);

rec DifficultPrice16;
if DPLcounter==16 && DPLcounter[1]!=16 {
DifficultPrice16= close; } else {DifficultPrice16=CompoundValue(1, DifficultPrice16[1], NAN);};
plot DPL16=DifficultPrice16;
DPL16.SetPaintingStrategy(PaintingStrategy.DASHES); DPL16.hideBubble(); DPL16.hideTitle();
DPL16.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL16.SetLineWeight(1);


rec DifficultPrice17;
if DPLcounter==17 && DPLcounter[1]!=17 {
DifficultPrice17= close; } else {DifficultPrice17=CompoundValue(1, DifficultPrice17[1], NAN);};
plot DPL17=DifficultPrice17;
DPL17.SetPaintingStrategy(PaintingStrategy.DASHES); DPL17.hideBubble(); DPL17.hideTitle();
DPL17.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL17.SetLineWeight(1);

rec DifficultPrice18;
if DPLcounter==18 && DPLcounter[1]!=18 {
DifficultPrice18= close; } else {DifficultPrice18=CompoundValue(1, DifficultPrice18[1], NAN);};
plot DPL18=DifficultPrice18;
DPL18.SetPaintingStrategy(PaintingStrategy.DASHES); DPL18.hideBubble(); DPL18.hideTitle();
DPL18.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL18.SetLineWeight(1);

rec DifficultPrice19;
if DPLcounter==19 && DPLcounter[1]!=19 {
DifficultPrice19= close; } else {DifficultPrice19=CompoundValue(1, DifficultPrice19[1], NAN);};
plot DPL19=DifficultPrice19;
DPL19.SetPaintingStrategy(PaintingStrategy.DASHES); DPL19.hideBubble(); DPL19.hideTitle();
DPL19.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL19.SetLineWeight(1);

rec DifficultPrice20;
if DPLcounter==20 && DPLcounter[1]!=20 {
DifficultPrice20= close; } else {DifficultPrice20=CompoundValue(1, DifficultPrice20[1], NAN);};
plot DPL20=DifficultPrice20;
DPL20.SetPaintingStrategy(PaintingStrategy.DASHES); DPL20.hideBubble(); DPL20.hideTitle();
DPL20.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL20.SetLineWeight(1);

### Caution Relative Volume compares the current OrderFlow to the Volume of the EXACT same time of day for several times. For instance the Volume usually increases in the first minute after 9:30 AM EST as the NewYork WallStreet Opens... It would be completely meaningless to compare the open Volume to any other time of day except the market open of the previous days.
#Testing enough Data is loaded to calculate Relative Volumes
def CalendarDays = GetYYYYMMDD();
def NumberOfCalendarDaysOnChart = DaysFromDate(First(CalendarDays)) + GetDayOfWeek(First(CalendarDays));
AddLabel(NumberOfCalendarDaysOnChart <10, "RelativeVolume Error: Only " + NumberOfCalendarDaysOnChart + " days loaded on chart...Please add more days", Color.RED);


AddLabel(PastPriceMovePercent <40, " Caution: RelativePriceMove is only " + PastPriceMovePercent + " %. Please consider a larger relative price comparison to the past days.", Color.YELLOW);


Dynamic Volume Profile

Code:
#____   ____.__                        _____  ____   ____    .__                       
#\   \ /   /|__| ______  _  __   _____/ ____\ \   \ /   /___ |  |  __ __  _____   ____
# \   V   / |  |/ __ \ \/ \/ /  /  _ \   __\   \   V   /  _ \|  | |  |  \/     \_/ __ \
#  \     /  |  \  ___/\     /  (  <_> )  |      \     (  <_> )  |_|  |  /  | |  \  ___/
#   \___/   |__|\___/  \/\_/    \____/|__|       \___/ \____/|____/____/|__|_|  /\___/
                                                                                                                                                  

#         _                              ___ _ _     
# _ _ ___| |_ _ _____ ___    ___ ___ ___|  _|_| |___
#| | | . | | | |     | -_|  | . |  _| . |  _| | | -_|
# \_/|___|_|___|_|_|_|___|  |  _|_| |___|_| |_|_|___|
#                           |_|                     


# Special thanks to Welkin from UseThinkScript.com

# For any asset, knowing the volume of trades is useless without context.
# We must be include patterns which are out of view of most charts.
# Large spikes and drops of Volume must considered relattive to the delta of price and the time of occurance.

# There is a strong statistical link between the afternoon and overnight volumes and the ease of which the market will trend into the following day.


def h = high;
def l = low;
def hlc = hlc3;
def NAN = Double.NaN;

input SpacesLabels = 10; #hint SpacesLabels: The number of spaces you wish to extend the Labels to make viewing easier.
def b  = SpacesLabels;
def b1 = b + 1;
input MarketOpenTime = 0930;#hint MarketOpenTime: Time to begin the morning session, regular trading hours RTH.
input AfternoonSessionTime = 1515; #hint AfternoonSessionTime: Time to begin the afternoon session that you wish to compare to the next day.

def BeginAfternoonSession = if SecondsTillTime(AfternoonSessionTime) crosses below 1 then yes else no;
def BeginEveningSession = if GetTime() crosses above RegularTradingEnd(GetYYYYMMDD()) then yes else no;
def EndEveningSession = if GetTime() crosses above RegularTradingStart(GetYYYYMMDD()) then yes else no;

def FindAfternoonHigh = if BeginAfternoonSession then h else if !BeginAfternoonSession && h > FindAfternoonHigh[1] then h else if !BeginAfternoonSession  && h <= FindAfternoonHigh[1] then FindAfternoonHigh[1] else h;
def SelectAfternoonHigh = if BeginEveningSession then FindAfternoonHigh[1] else SelectAfternoonHigh[1];
plot AfternoonSessionHigh = SelectAfternoonHigh;
def FindAfternoonLow = if BeginAfternoonSession then l else if !BeginAfternoonSession && l < FindAfternoonLow[1] then l else if !BeginAfternoonSession  && l >= FindAfternoonLow[1] then FindAfternoonLow[1] else l;
def SelectAfternoonLow = if BeginEveningSession then FindAfternoonLow[1] else SelectAfternoonLow[1];
plot AfternoonSessionLow = SelectAfternoonLow;

def FindOvernightHigh = if BeginEveningSession then h else if !BeginEveningSession && h > FindAfternoonHigh[1] then h else if !BeginEveningSession  && h <= FindOvernightHigh[1] then FindOvernightHigh[1] else h;
def SelectOvernightHigh = if EndEveningSession then FindOvernightHigh[1] else SelectOvernightHigh[1];
plot OvernightHigh = SelectOvernightHigh;
def FindOvernightLow = if BeginEveningSession then l else if !BeginEveningSession && l < FindOvernightLow[1] then l else if !BeginEveningSession  && l >= FindOvernightLow[1] then FindOvernightLow[1] else l;
def SelectOvernightLow = if EndEveningSession then FindOvernightLow[1] else SelectOvernightLow[1];
plot OvernightLow = SelectOvernightLow;

input LineWeight = 1;
input ShowSimpleAfternoonTrendlines = yes;
input ShowSimpleOvernightTrendlines = yes;
def SimpleTrendsFromPastVolumes = if h > Min(OvernightHigh, AfternoonSessionHigh) then +1 else if l < Max(OvernightLow, AfternoonSessionLow) then -1 else 0;
AfternoonSessionHigh.SetDefaultColor(Color.LIGHT_GRAY);
#AfternoonSessionHigh.AssignValueColor(if h >= AfternoonSessionHigh && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= AfternoonSessionHigh && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW); #AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), AfternoonSessionHigh[b1], "Yesterday Afternoon High", color.blue, yes);
AfternoonSessionHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
AfternoonSessionHigh.SetLineWeight(LineWeight);
AfternoonSessionHigh.SetHiding(!ShowSimpleAfternoonTrendlines);
AfternoonSessionLow.SetDefaultColor(Color.LIGHT_GRAY);
#AfternoonSessionLow.AssignValueColor(if h >= AfternoonSessionLow && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= AfternoonSessionLow && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW);
#AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), AfternoonSessionLow[b1], "Yesterday Afternoon Low", color.blue, no);
AfternoonSessionLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
AfternoonSessionLow.SetHiding(!ShowSimpleAfternoonTrendlines);
AfternoonSessionHigh.SetLineWeight(LineWeight);
OvernightHigh.SetDefaultColor(Color.LIGHT_GRAY);
#OvernightHigh.AssignValueColor(if h >= OvernightHigh && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= OvernightHigh && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW); #AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), OvernightHigh[b1], "Overnight High", color.blue, yes);
OvernightHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
OvernightHigh.SetLineWeight(LineWeight);
OvernightHigh.SetHiding(!ShowSimpleOvernightTrendlines);
OvernightLow.SetDefaultColor(Color.LIGHT_GRAY);
#OvernightLow.AssignValueColor(if h >= OvernightLow && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= OvernightLow && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW); #AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]),OvernightLow[b1], "Overnight Low", color.blue, no);
OvernightLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
OvernightLow.SetLineWeight(LineWeight);
OvernightLow.SetHiding(!ShowSimpleOvernightTrendlines);


def isETH = CompoundValue(1, if BeginAfternoonSession then 1 else if EndEveningSession then 0 else isETH[1], 0);
def isAfterHoursSessions  = if isETH then 1 else 0;

input pricePerRowHeightMode = { AUTOMATIC, default TICKSIZE}; #hint pricePerRowHeightMode: There are often advantages to using Tick data when possible.
input multiplier = 1;
def onExpansion = no;
input profiles = 10;
input valueAreaPercent = 65;

def cond          = isAfterHoursSessions[1] != isAfterHoursSessions;
def profilecount  = if cond then profilecount[1] + 1 else profilecount[1];
def profiletoday  = HighestAll(profilecount) - profilecount ;

def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
}

profile OvernightVolume = VolumeProfile("startNewProfile" = cond, "onExpansion" = no, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def OvernightCON = CompoundValue(1, onExpansion, no);

def OvernightPointOfControl = if IsNaN(close) then OvernightPointOfControl[1] else if IsNaN(OvernightVolume.GetPointOfControl()) and OvernightCON then OvernightPointOfControl[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetPointOfControl() else OvernightPointOfControl[1];
def OvernightHVA = if IsNaN(close) then OvernightHVA[1] else if IsNaN(OvernightVolume.GetHighestValueArea()) and OvernightCON then OvernightHVA[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetHighestValueArea() else OvernightHVA[1];
def OvernightLVA = if IsNaN(close) then OvernightLVA[1] else if IsNaN(OvernightVolume.GetLowestValueArea()) and OvernightCON then OvernightLVA[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetLowestValueArea() else OvernightLVA[1];

DefineGlobalColor("Overnight POC Lines", Color.GRAY);
DefineGlobalColor("Overnight VAHigh Lines", Color.GRAY);
DefineGlobalColor("Overnight VALow Lines", Color.GRAY);

input OvernightLineWeight = 1;
input ShowOvernightPOC = yes;
input ShowOvernightHVA = yes;
input ShowOvernightLVA = yes;
plot OvernightPOC    = OvernightPointOfControl;
plot OvernightVAHigh = OvernightHVA;
plot OvernightVALow  = OvernightLVA;
#OvernightPOC.SetDefaultColor(GlobalColor("Point Of Control"));
OvernightPOC.SetDefaultColor(GlobalColor("Overnight POC Lines"));
OvernightPOC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
OvernightPOC.SetLineWeight(OvernightLineWeight);
OvernightPOC.SetHiding(!ShowOvernightPOC);
OvernightVAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
#OvernightVAHigh.SetDefaultColor(GlobalColor("Value Area"));
OvernightVAHigh.SetDefaultColor(GlobalColor("Overnight VAHigh Lines"));
OvernightVAHigh.SetLineWeight(OvernightLineWeight);
OvernightVAHigh.SetHiding(!ShowOvernightHVA);
OvernightVALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
#OvernightVALow.SetDefaultColor(GlobalColor("Value Area"));
OvernightVALow.SetDefaultColor(GlobalColor("Overnight VALow Lines"));
OvernightVALow.SetLineWeight(OvernightLineWeight);
OvernightVALow.SetHiding(!ShowOvernightLVA);

#AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]), OvernightPOC[b1], "Overnight POC Lines", OvernightPOC.TakeValueColor(),yes);
#AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]), OvernightVAHigh[b1], "Overnight POC Lines", OvernightVAHigh.TakeValueColor(),yes);
#AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]),OvernightVALow[b1], "Overnight POC Lines",OvernightVALow.TakeValueColor(), no);

plot PointOfControlClouds = NAN;
PointOfControlClouds.HideBubble();
PointOfControlClouds.HideTitle();
PointOfControlClouds.DefineColor("OvernightPointOfControlArea", Color.DARK_GRAY);
#AddCloud(OvernightVAHigh, OvernightVALow, PointOfControlClouds.Color("OvernightPointOfControlArea"));


input RandomWalkDriftingLength = 33;#hint RandomWalkDriftingLength: This is the length the indicator will use to segment volume profiles with Non-repainting pivots.
def bnOK = BarNumber() > RandomWalkDriftingLength;
def isHigher = fold f = 1 to RandomWalkDriftingLength + 1 with p = 1
               while p do h > GetValue(h, -f);
def HH = if bnOK and isHigher
         and h == Highest(h, RandomWalkDriftingLength)
         then h else NAN;
def isLower = fold j = 1 to RandomWalkDriftingLength + 1 with q = 1
              while q do l < GetValue(l, -j);
def LL = if bnOK and isLower
         and l == Lowest(l, RandomWalkDriftingLength)
         then l else NAN;

def PivH = if HH > 0 then 1 else 0;
def PivL = if LL > 0 then 1 else 0;

rec dir = CompoundValue(1, if !IsNaN(PivL) then 1 else if !IsNaN(PivH) then -1 else dir[1], 0);

def Dn = dir crosses above 0;
def Up = dir crosses below 0;

def UpTime = if Up then 1 else UpTime[1] + 1;
def NewUp = if Up then h else NewUp[1]; # Recent High

def DownTime = if Dn then 1 else DownTime[1] + 1;
def NewDown = if Dn then l else NewDown[1]; # Recent Low

##############
### CLOCK ####
##############
def yyyymmdd = GetYYYYMMDD();
def seconds = SecondsFromTime(0);
def month = GetYear() * 12 + GetMonth();
def year = GetYear();
def day_number = DaysFromDate(First(yyyymmdd)) + GetDayOfWeek(First(yyyymmdd));
def dom = GetDayOfMonth(yyyymmdd);
def dow = GetDayOfWeek(yyyymmdd - dom + 1);
def expthismonth = (if dow > 5 then 27 else 20) - dow;
def exp_opt = month + (dom > expthismonth);
def timeOfPhaseProfile = BarNumber() - 1;
####################################
# TICKS: Show true Volume at Price #
####################################
def ExpandTheLinesToNextSegment = no;
input NumberOfVolumeProfiles = 50; #hint NumberOfVolumeProfiles: The number of Volume Profiles you wish to view.
input ProfilevalueAreaPercent = 65;# ProfilevalueAreaPercent: The % of all Volume traded in the profile that you wish to focus on your profiles.
def NewVolumeProfile = if DownTime == 1 or UpTime == 1 then 1 else NAN;
input ShowPOCclouds = no;# hint ShowPOCclouds: Use to highlight the higher Volume areas of the Volume Profile.

profile vol = VolumeProfile("startNewProfile" = (NewVolumeProfile), "onExpansion" = ExpandTheLinesToNextSegment, "numberOfProfiles" = NumberOfVolumeProfiles, "pricePerRow" = PricePerRow.TICKSIZE, "value area percent" = ProfilevalueAreaPercent);
input ProfileTransparency = 50; #75;#hint ProfileTransparency: The Transparency of the Volume Profiles
vol.Show(CreateColor(0, 102, 204), if ShowPOCclouds then CreateColor(0, 102, 204) else Color.CURRENT, if ShowPOCclouds then CreateColor(0, 102, 204) else Color.CURRENT, ProfileTransparency);



def con = CompoundValue(1, ExpandTheLinesToNextSegment, no);
def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
def hVA = if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else vol.GetHighestValueArea();
def lVA = if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else vol.GetLowestValueArea();

def hProfile = if IsNaN(vol.GetHighest()) and con then hProfile[1] else vol.GetHighest();
def lProfile = if IsNaN(vol.GetLowest()) and con then lProfile[1] else vol.GetLowest();
def plotsDomain = IsNaN(close) == ExpandTheLinesToNextSegment;

DefineGlobalColor("Point Of Control", Color.ORANGE);
DefineGlobalColor("Value Area", Color.CYAN);

input MainLineWeight = 1;
input ShowMainPOC = yes;
input ShowMainHVA = yes;
input ShowMainLVA = yes;

plot POC = if plotsDomain then pc else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;

POC.SetDefaultColor(GlobalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC.HideBubble();
POC.HideTitle();
POC.SetLineWeight(MainLineWeight);
POC.SetHiding(!ShowMainPOC);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
VAHigh.SetDefaultColor(GlobalColor("Value Area"));
VAHigh.HideBubble();
VAHigh.HideTitle();
VAHigh.SetLineWeight(MainLineWeight);
VAHigh.SetHiding(!ShowMainHVA);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
VALow.SetDefaultColor(GlobalColor("Value Area"));
VALow.HideBubble();
VALow.HideTitle();
VALow.SetLineWeight(MainLineWeight);
VALow.SetHiding(!ShowMainLVA);

#plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
#plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
#ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); ProfileHigh.SetDefaultColor(Color.Dark_Green); #ProfileHigh.hideBubble(); ProfileHigh.HideTitle(); ProfileHigh.setLineWeight(1);
#ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); ProfileLow.SetDefaultColor(Color.Dark_Red); #ProfileLow.hideBubble();  ProfileLow.HideTitle(); ProfileLow.setLineWeight(1);

As for the overall performance, I think the winsorizing has definitely helped...The initial load of the scripts and dataset took 10-15 seconds and subsequent loads took 3-5 seconds...YMMV, but I think the performance is much better, that is depending on what resources you are able to allocate to TOS and what kind of hardware you have...My system is 8 years old now and I'm well aware that I'm overdue for a new box, but it makes for a good benchmark when testing performance...

As for the dreaded Repainting, I didn't see any instances...With that said, the 1-minute chart does do some funky screen painting upon initial loading, but I think that is TOS trying to draw a significant data stream with only one core to work with...FWIW, I think Schwab should seriously consider investing in a multi-core rewrite of TOS instead of creating a doppelganger, but what do I know... 🤣

Bottom Line: I think VoV 2.0 is a big step forward! We'll see what happens at the Open tomorrow... 😎
 
Bottom Line: I think VoV 2.0 is a big step forward! We'll see what happens at the Open tomorrow... 😎
I am so glad 😊
As for the dreaded Repainting, I didn't see any instances...With that said, the 1-minute chart does do some funky screen painting upon initial loading,
Yes I am hoping that is the only problem, it is terrifying that several of us experienced repainting.

As for the overall performance, I think the winsorizing has definitely helped...The initial load of the scripts and dataset took 10-15 seconds and subsequent loads took 3-5 seconds...
I use a very affordable i5 laptop, I did *** RAM awhile back but there are limits to how much resources ToS will use on a laptop.
However when you look at Robin Hood and MetaTrader and many many other platforms with designs thst borderline outright theft I am grateful to the thinkorswim community 🙏.

looking forward to seeing the Winsorizing in action... 😎
Using mathematics to overcome limitations is a part of our history 🫡
I am happy and proud to be able to do so.
 
Bottom Line: I think VoV 2.0 is a big step forward! We'll see what happens at the Open tomorrow... 😎
I know you are aware of this but not everyday will highlight a fortune in trades as we have been getting recently.
There will also be flat days where we should rest 😌.

On the last flat day:
There were long bright easy EoM bars drifting in the premarket and dense Difficult DPLs above and below those bright easy bars. Price zigzaged in those areas All Day Long 😂, the price made fake breakouts into the DPLs and then turned abruptly back to the price range of the bright easy EOM bars from the premarket. I imagine the market considered the large number of people entering long just below the top DPLs and the surge of people entering short just above the bottom DPL as trapped liquidity 😅 oh my that could have been me if I were only looking at the amount of raw volumes and drawing support and resistance line.

Oh well so it is very nice to View the Volume "relative" to everything else.

In the coming days when we all have time to get together there is a great deal of space available for Volatility indicators.
I don't know everyone on the forum who enjoys working with Volatility, I did meet @Ramisegal
Post in thread 'Projected Move Expected Bounce For ThinkOrSwim' https://usethinkscript.com/threads/projected-move-expected-bounce-for-thinkorswim.17545/post-137467
 
Hello I hope everyone is doing well.
I have gotten good grades and am making friends at my clinicals.

Regarding the last ViewOfVolume I was very worried that people were experiencing design issues such as jerking around and repainting. It was particularly concerning when users experienced repainting as this is not a repainting indicator.

It was wonderful of those people to document and share those flaws which I did not notice. In response I am trying a modified " Winsorizing " function to allow this script to be used with fewer days loaded on the charts, and therefore fewer resources. ThinkScript must run every single bar on each chart every single time that the chart updates a new bar, and so to prevent misloading let us try 20 days and 15 days on the charts instead of 30 day charts.
https://en.wikipedia.org/wiki/Winsorizing#Distinction_from_trimming

I am also running fewer operations in this code and so I am hopeful usability issues will be resolved easily.

I owe the community a better explanation and a video of how I trade with this, but in the meantime could everyone please look at this and see if it loads correctly on their charts? @MerryDay @Ramisegal

Please don't spend more than a few minutes of your time verifying that there is no repainting lines in the code. The main thing to look for is that if you set a certain number of days on the chart that entire time period should load to the chart in a reasonable amount of time. If the chart fails to load the entire time span and adds days on later this will appear to repaint.

http://tos.mx/cXOcTMY

First off, thank you for your work and hope you are crushing your exams. Im very intrigued by this study so I tried loading up both iterations from this thread. Load time was perfectly fine, maybe little slower than most, but I had maybe 8-10 seconds, and I have about 12 other charts open, if they were all closed, probably could have loaded even faster. I haven't noticed any form of repainting, other then the initial load process that @netarchitech mentioned.

With the 90% threshold for DPL, it doesn't find any DPL's on SPY, WHEN its on 1M 20D, but when I switch it to 15 days (for some reason mine defaulted to 20) it finds 1 DPL when set to 90%. So I guess just make sure the shared link is using 15.

One thing I did notice is the # of DPL's in the label takes at least 1 full minute to determine how many there are, when first loaded it'll say 50 DPL's, 10 seconds later --- 46 DPLS--10 seconds later---39 DPLS---- etc, etc. Which all seems perfectly normal for such an intense script. And again, i didn't cut any resources that other users wouldn't be facing. AKA not a true test, since I didn't rid my monitors of extra charts.

Thanks again for this awesome framework, was hoping any notes or trials from other users you would find helpful as much as I do on my posts.


2024-01-31_12h02_10.png


@MatthewA OK...I've spent some time acquainting myself with the VoV 2.0 scripts and realized I spoke to soon before regarding a candle-coloring scheme involving red and green...I've gathered that EOM is defining what to color the candles and DPL's are dashed lines colored together with one DefineGlobalColor(), but, of course, you already knew that 😉

With that said, I've taken the liberty again to go ahead and modify the scripts somewhat...Essentially I've made some granular UI adjustments...Line Thickness...Line Display (show/hide)...Color Tweaks...I am attaching the modified code for your review...I hope it meets with your approval...

Dynamic Relative Volume

Code:
#____   ____.__                        _____  ____   ____    .__                      
#\   \ /   /|__| ______  _  __   _____/ ____\ \   \ /   /___ |  |  __ __  _____   ____
# \   V   / |  |/ __ \ \/ \/ /  /  _ \   __\   \   V   /  _ \|  | |  |  \/     \_/ __ \
#  \     /  |  \  ___/\     /  (  <_> )  |      \     (  <_> )  |_|  |  /  | |  \  ___/
#   \___/   |__|\___/  \/\_/    \____/|__|       \___/ \____/|____/____/|__|_|  /\___/
                                                                   
                                                                                     
#   _                   _                _     _   _                    _              
# _| |_ _ ___ ___ _____|_|___    ___ ___| |___| |_|_|_ _ ___    _ _ ___| |_ _ _____ ___
#| . | | |   | .'|     | |  _|  |  _| -_| | .'|  _| | | | -_|  | | | . | | | |     | -_|
#|___|_  |_|_|__,|_|_|_|_|___|  |_| |___|_|__,|_| |_|\_/|___|   \_/|___|_|___|_|_|_|___|
#    |___|                                                                            

# Special thanks to Welkin from UseThinkScript.com

# For any asset, knowing the volume of trades is useless without context.
# We must include patterns which are out of view of most charts.
# Large spikes and drops of Volume must considered relative to the delta of price and the time of occurence.

#EOM colors: The Ease Of Movement ( EoM ) is the the amount of volume required to move prices. EoM was developed by Richard W. Arms, Jr., the creator of Equivolume.
#We will set the brightness of the price according to the Relative Dynamic EOM. Viewing bright EOM prices in a trending distribution indicates that it would be EASY for the trend to continue into that direction after the occasional retracements. Viewing bright EOM Volumes when the market is range-bound indicates which it will be EASY for price to drift in that range.

#DPL Lines:  We take a cautionary View of Difficult Price Lines ( DPLs ) to avoid Volumes where price will chop erratically, as these areas will be DIFFICULT to enter good trends and it is more comfortable to wait so that we may avoid uneccessary stress. The DPL lines are based on the works of Melvin E. Dickover, who developed FreedomOfMovement which takes into account price-volume behavior in order to detect points where movement of price is suddenly restricted. You may consider taking profits a bit before the next DPL line or wating to open your next position until the Difficult Volumes have weakened. You will notice that the DPL caclulations are much more accurate than simply drawing Support & Resistance Lines at recent Highs and Lows, however I would discourage the user from attempting to scalp off of bounces at the DPLs. We must take a long term View Of Volume to understand the price action as a whole.

# It is well known that Volume Accumulates while the market consolidates for the majority of time and Volume Distributes into strong trends. Only with a View of Volume can one understand when it would be more comfortable to wait or

declare upper;
declare hide_on_daily;
def h=high; def l=low; def hlc=hlc3; def c=close; def NAN=double.NAN;
input WinsorizingPercentage =5; #hint WinsorizingPercentage: % percentage to shift Normalized Values to prevent extreme arbitrary skewing.
# Traditionally Winsorizing works by replacing extreme High and Extreme Low values with and upper or lower common percentile median. However in our applicatoin we wish to simplfy the load on our computers and prevent wild shifts.

input DPLthreshold=95; #hint DPLthreshold: The required strength of a DPL where a Volume is expected to bring DIFFICULT erratic chop.

#DefineGlobalColor("1stStrongest", CreateColor(0,230,255));
#DefineGlobalColor("2ndStrongest", CreateColor(0,190,255));
#DefineGlobalColor("3rdStrongest", CreateColor(0,150,255));
#DefineGlobalColor("4thStrongest", CreateColor(0,110,255));
#DefineGlobalColor("5thStrongest", CreateColor(0,70,255));
#DefineGlobalColor("6thStrongest", CreateColor(0,0,200));
#DefineGlobalColor("7thStrongest", CreateColor(0,0,150));
#DefineGlobalColor("8thStrongest", CreateColor(0,0,100));

DefineGlobalColor("1stStrongest", CreateColor(107,177,92));
DefineGlobalColor("2ndStrongest", CreateColor(102,157,90));
DefineGlobalColor("3rdStrongest", CreateColor(93,140,82));
DefineGlobalColor("4thStrongest", CreateColor(90,120,79));
DefineGlobalColor("5thStrongest", CreateColor(81,107,73));
DefineGlobalColor("6thStrongest", CreateColor(76,98,70));
DefineGlobalColor("7thStrongest", CreateColor(71,88,65));
DefineGlobalColor("8thStrongest", CreateColor(60,76,55));

DefineGlobalColor("DifficultPriceLine", Color.RED); #createcolor(75,180,255));
# VOLUME SELECTION
# Unfortunately, tick data is only available for the past 5 days in ThinkScript Servers.
def shares = If(!IsNaN(volume), volume, 1);
def oi = If(!IsNaN(open_interest), open_interest, 1);
def iv = If(!IsNaN(imp_volatility), imp_volatility, .00001);
def v;
#hint volumeSource: Choose to use either Share Volume (normal volume), Shares Per Range which is Share Volume / Range chosen below, or Trades Per Range which is Trade Volume / Range chosen below. ToS servers only store tick data for 5 days...
input volumeSource = {
    default "Share Volume",  
    "OpenInterest",
    "Shares/OI",  
    "ImpliedVolatility",  
    "Shares/IV",
    "Shares*IV",
    "Trades/IV"
 
};
switch (volumeSource) {
case "Share Volume":
    v = shares;
case "OpenInterest":
    v = oi;
case "Shares/OI":
    v = shares / oi;
case "ImpliedVolatility":
    v = iv;
case "Shares/IV":
    v = shares / iv;
case "Shares*IV":
    v = shares * iv;
case "Trades/IV":
    v = shares / iv;
}

script prior {
    input of = close;
    def priorOf = if of != of[1] then of[1] else priorOf[1];
    plot
    prior = priorOf;
}

def x = BarNumber();
def x0 = if isNaN(close[-1]) and !isNaN(close) then x else x0[1]; # X0 periodization is required for the Winsorizing operation required later. Please read a bit about "Winsorization"
def rteBar = if GetTime() crosses above RegularTradingStart(GetYYYYMMDD()) then
               x else rteBar[1];
def priorRTEbar1  = prior(rteBar);
def priorRTEbar2  = prior(priorRTEbar1);
def priorRTEbar3  = prior(priorRTEbar2);
def priorRTEbar4  = prior(priorRTEbar3);
def priorRTEbar5  = prior(priorRTEbar4);
def priorRTEbar6  = prior(priorRTEbar5);
def priorRTEbar7  = prior(priorRTEbar6);

#Relative VOLUME portion
def pV1  = GetValue(v, rteBar - priorRTEbar1);
def pV2  = GetValue(v, rteBar - priorRTEbar2);
def pV3  = GetValue(v, rteBar - priorRTEbar3);
def pV4  = GetValue(v, rteBar - priorRTEbar4);
def pV5  = GetValue(v, rteBar - priorRTEbar5);
def pV6  = GetValue(v, rteBar - priorRTEbar6);
def pV7  = GetValue(v, rteBar - priorRTEbar7);

def avgPriorVol = (pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7) / 7;
def StdDevPriorVol = StDev(pV1 + pV2 + pV3 + pV4 + pV5 + pV6 + pV7);

def relVol = ( v - avgPriorVol ) / StdDevPriorVol;
def minVol = LowestAll(relVol);
def maxVol = HighestAll(relVol);
def normalizedRelativeVolume = 1 + (((relVol - minVol) / (maxVol - minVol)) * (100));

def relVolWinsorizeBaseline =  simpleMovingAvg(normalizedRelativeVolume, 1440);
def WinsorizingMin =  relVolWinsorizeBaseline + WinsorizingPercentage;
def WinzoringForcedMax=100 - WinsorizingMin;
def WinsorizedRelVol = if normalizedRelativeVolume> WinzoringForcedMax then WinzoringForcedMax else if normalizedRelativeVolume < WinsorizingMin then WinsorizingMin else normalizedRelativeVolume;
def minNormalizedRelVol=min(Lowestall(WinsorizedRelVol),WinsorizingPercentage);
def maxNormalizedRelVol=Highestall(WinsorizedRelVol);
def ViewOfVolumeRelativeRelVol = 1 + (((WinsorizedRelVol - minNormalizedRelVol) / (maxNormalizedRelVol - minNormalizedRelVol)) * 100); # Plot as Histogram


#Relative PRICE MOVE
input PastPriceMovePercent=50; #hint PastPriceMovePercent: The 0-100% normalized% of the price move which is compared relative to priceActionIndicator moves of previous days. Preferably greater than 50%.
def PriorDayPriceMOVE = AbsValue((hlc - hlc[1]) / (hlc[1]));
def pM1  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar1);
def pM2  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar2);
def pM3  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar3);
def pM4  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar4);
def pM5  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar5);
def pM6  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar6);
def pM7  = GetValue(PriorDayPriceMOVE, rteBar - priorRTEbar7);

def avgPriorMOVE = (pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7 ) / 7;
def StdDevPriorMOVE = StDev(pM1 + pM2 + pM3 + pM4 + pM5 +  pM6 + pM7);
def relMOVE = ((( PriorDayPriceMOVE - avgPriorMOVE) / StdDevPriorMOVE) * (PastPriceMovePercent)) + ((PriorDayPriceMOVE) * (100 - PastPriceMovePercent));
def minMOVE = LowestAll(relMOVE);
def maxMOVE = HighestAll(relMOVE);
def normalizedMOVE = 1 + (((relMOVE - minMOVE) / (maxMOVE - minMOVE)) * (100));

# Final EASEOfMovement solution to highlight price moves which may occur in smooth trends from low orderflow....
# Strong EOMs from trends are likely to continue in the direction of that trend after the occasional pause.
# Strong EOMs that do not outside of strong trends are likely to revisit the same prices.
def EaseOfMovement = normalizedMOVE / ViewOfVolumeRelativeRelVol;
def minEoM = LowestAll(EaseOfMovement);
def maxEoM = HighestAll(EaseOfMovement);
def normalizedEase = 1 + (((EaseOfMovement - minEoM) / (maxEoM - minEoM)) * 100);
 # Nice to plot as Histogram
def WinsorizingMinEOM =  simpleMovingAvg(normalizedEase, 144);;
def WinzoringForcedMaxEOM=100 - WinsorizingMinEOM;
def WinsorizedEOM = if normalizedEase> WinzoringForcedMaxEOM then WinzoringForcedMaxEOM else if normalizedEase < WinsorizingPercentage then WinsorizingPercentage else normalizedEase;
def minNormalizedEoM=Lowestall(WinsorizedEOM);
def maxNormalizedEoM=Highestall(WinsorizedEOM);
plot ViewOfVolumeRelativeEoM =1 + (((WinsorizedEOM - minNormalizedEoM) / (maxNormalizedEoM - minNormalizedEoM)) * 100);
# Nice to plot as Histogram

input   FirstEasiestOrderFlow1st= 60; #hint FirstEasiestOrderFlow1st:
input  SecondEasiestOrderFlow2nd= 50; #hint SecondEasiestOrderFlow2nd:
input   ThirdEasiestOrderFlow3rd= 40; #hint ThirdEasiestOrderFlow3rd:
input   FouthEasiestOrderFlow4th= 30; #hint FourthEasiestOrderFlow4th:
input   FifthEasiestOrderFlow5th= 20; #hint FifthEasiestOrderFlow5th:
input   SixthEasiestOrderFlow6th= 15; #hint SixthEasiestOrderFlow6th:
input SeventhEasiestOrderFlow7th= 10; #hint SeventhEasiestOrderFlow7th:
input  EighthEasiestOrderFlow8th= 5; #hint EighthEasiestOrderFlow8th:

AssignPriceColor(
 if ViewOfVolumeRelativeEoM > FirstEasiestOrderFlow1st then GlobalColor("1stStrongest")
 else if ViewOfVolumeRelativeEoM > SecondEasiestOrderFlow2nd then GlobalColor("2ndStrongest")
 else if ViewOfVolumeRelativeEoM > ThirdEasiestOrderFlow3rd then GlobalColor("3rdStrongest")
 else if ViewOfVolumeRelativeEoM > FouthEasiestOrderFlow4th then GlobalColor("4thStrongest")
 else if ViewOfVolumeRelativeEoM > FifthEasiestOrderFlow5th then GlobalColor("5thStrongest")
 else if ViewOfVolumeRelativeEoM > SixthEasiestOrderFlow6th then GlobalColor("6thStrongest")
 else if ViewOfVolumeRelativeEoM > SeventhEasiestOrderFlow7th then GlobalColor("7thStrongest")
 else if ViewOfVolumeRelativeEoM > EighthEasiestOrderFlow8th then GlobalColor("8thStrongest")
 else Color.Black);

# Final FOM solution to draw the 'Defended Price Line' (DPL) where trading is overencumbered with Volumes...
#We expect choppiness and erratic stop outs to randomly provide and restrict liquidity near DPLs and we prefer not to trade in these DIFFICULT DPLs.
def FreedomMOVEMENT = ViewOfVolumeRelativeRelVol / normalizedMOVE;
def relFOM = 1/ViewOfVolumeRelativeEoM;
def minFOM = LowestAll(relFOM);
def maxFOM = HighestAll(relFOM);
def normalizedFOM = 1 + (((relFOM - minFOM) / (maxFOM - minFOM)) * 100); # Plot as volume


def DPLlimitLength = 60;
def DPLcheck =  (MovingAverage(AverageType.WEIGHTED, normalizedFOM, DPLlimitLength));
plot DefendedPriceLineDPL = if normalizedFOM > ((DPLcheck/2)+DPLthreshold) then close else Double.NaN;
def DPLcount= if !isNAN(DefendedPriceLineDPL) then DPLcount[1]+1 else DPLcount[1];
DefendedPriceLineDPL.setPaintingStrategy(PaintingStrategy.Squares);
DefendedPriceLineDPL.SetDefaultColor(GlobalColor("DifficultPriceLine")); DefendedPriceLineDPL.hideBubble(); DefendedPriceLineDPL.hideTitle();
DefendedPriceLineDPL.SetLineWeight(5);
addLabel(1,"| " + DPLcount  + " DPLs (Difficult Price Lines) ◽--- " + DPLthreshold +"% level |",GlobalColor("DifficultPriceLine"));

#Assign DPL lines at specific points
#######################################

rec DPLcounter;
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] < 20) {
DPLcounter =DPLcounter[1] + 1;
} else {
if ( normalizedFOM > ((DPLcheck/2)+DPLthreshold) && DPLcounter[1] == 20) {
DPLcounter = 1;
} else {
DPLcounter =DPLcounter[1];
}
};
rec DifficultPrice1;
if DPLcounter==1 && DPLcounter[1]!=1 {
DifficultPrice1= close; } else {DifficultPrice1=CompoundValue(1, DifficultPrice1[1], NAN);};
plot DPL1=DifficultPrice1;
DPL1.SetPaintingStrategy(PaintingStrategy.DASHES); DPL1.hideBubble(); DPL1.hideTitle();
DPL1.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL1.SetLineWeight(1);

rec DifficultPrice2;
if DPLcounter==2 && DPLcounter[1]!=2 {
DifficultPrice2= close; } else {DifficultPrice2=CompoundValue(1, DifficultPrice2[1], NAN);};
plot DPL2=DifficultPrice2;
DPL2.SetPaintingStrategy(PaintingStrategy.DASHES); DPL2.hideBubble(); DPL2.hideTitle();
DPL2.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL2.SetLineWeight(1);

rec DifficultPrice3;
if DPLcounter==3 && DPLcounter[1]!=3 {
DifficultPrice3= close; } else {DifficultPrice3=CompoundValue(1, DifficultPrice3[1], NAN);};
plot DPL3=DifficultPrice3;
DPL3.SetPaintingStrategy(PaintingStrategy.DASHES); DPL3.hideBubble(); DPL3.hideTitle();
DPL3.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL3.SetLineWeight(1);

rec DifficultPrice4;
if DPLcounter==4 && DPLcounter[1]!=4 {
DifficultPrice4= close; } else {DifficultPrice4=CompoundValue(1, DifficultPrice4[1], NAN);};
plot DPL4=DifficultPrice4;
DPL4.SetPaintingStrategy(PaintingStrategy.DASHES); DPL4.hideBubble(); DPL4.hideTitle();
DPL4.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL4.SetLineWeight(1);

rec DifficultPrice5;
if DPLcounter==5 && DPLcounter[1]!=5 {
DifficultPrice5= close; } else {DifficultPrice5=CompoundValue(1, DifficultPrice5[1], NAN);};
plot DPL5=DifficultPrice5;
DPL5.SetPaintingStrategy(PaintingStrategy.DASHES); DPL5.hideBubble(); DPL5.hideTitle();
DPL5.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL5.SetLineWeight(1);

rec DifficultPrice6;
if DPLcounter==6 && DPLcounter[1]!=6 {
DifficultPrice6= close; } else {DifficultPrice6=CompoundValue(1, DifficultPrice6[1], NAN);};
plot DPL6=DifficultPrice6;
DPL6.SetPaintingStrategy(PaintingStrategy.DASHES); DPL6.hideBubble(); DPL6.hideTitle();
DPL6.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL6.SetLineWeight(1);

rec DifficultPrice7;
if DPLcounter==7 && DPLcounter[1]!=7 {
DifficultPrice7= close; } else {DifficultPrice7=CompoundValue(1, DifficultPrice7[1], NAN);};
plot DPL7=DifficultPrice7;
DPL7.SetPaintingStrategy(PaintingStrategy.DASHES); DPL7.hideBubble(); DPL7.hideTitle();
DPL7.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL7.SetLineWeight(1);

rec DifficultPrice8;
if DPLcounter==8 && DPLcounter[1]!=8 {
DifficultPrice8= close; } else {DifficultPrice8=CompoundValue(1, DifficultPrice8[1], NAN);};
plot DPL8=DifficultPrice8;
DPL8.SetPaintingStrategy(PaintingStrategy.DASHES); DPL8.hideBubble(); DPL8.hideTitle();
DPL8.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL8.SetLineWeight(1);

rec DifficultPrice9;
if DPLcounter==9 && DPLcounter[1]!=9 {
DifficultPrice9= close; } else {DifficultPrice9=CompoundValue(1, DifficultPrice9[1], NAN);};
plot DPL9=DifficultPrice9;
DPL9.SetPaintingStrategy(PaintingStrategy.DASHES); DPL9.hideBubble(); DPL9.hideTitle();
DPL9.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL9.SetLineWeight(1);

rec DifficultPrice10;
if DPLcounter==10 && DPLcounter[1]!=10 {
DifficultPrice10= close; } else {DifficultPrice10=CompoundValue(1, DifficultPrice10[1], NAN);};
plot DPL10=DifficultPrice10;
DPL10.SetPaintingStrategy(PaintingStrategy.DASHES); DPL10.hideBubble(); DPL10.hideTitle();
DPL10.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL10.SetLineWeight(1);

rec DifficultPrice11;
if DPLcounter==11 && DPLcounter[1]!=11 {
DifficultPrice11= close; } else {DifficultPrice11=CompoundValue(1, DifficultPrice11[1], NAN);};
plot DPL11=DifficultPrice11;
DPL11.SetPaintingStrategy(PaintingStrategy.DASHES); DPL11.hideBubble(); DPL11.hideTitle();
DPL11.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL11.SetLineWeight(1);

rec DifficultPrice12;
if DPLcounter==12 && DPLcounter[1]!=12 {
DifficultPrice12= close; } else {DifficultPrice12=CompoundValue(1, DifficultPrice12[1], NAN);};
plot DPL12=DifficultPrice12;
DPL12.SetPaintingStrategy(PaintingStrategy.DASHES); DPL12.hideBubble(); DPL12.hideTitle();
DPL12.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL12.SetLineWeight(1);

rec DifficultPrice13;
if DPLcounter==13 && DPLcounter[1]!=13 {
DifficultPrice13= close; } else {DifficultPrice13=CompoundValue(1, DifficultPrice13[1], NAN);};
plot DPL13=DifficultPrice13;
DPL13.SetPaintingStrategy(PaintingStrategy.DASHES); DPL13.hideBubble(); DPL13.hideTitle();
DPL13.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL13.SetLineWeight(1);

rec DifficultPrice14;
if DPLcounter==14 && DPLcounter[1]!=14 {
DifficultPrice14= close; } else {DifficultPrice14=CompoundValue(1, DifficultPrice14[1], NAN);};
plot DPL14=DifficultPrice14;
DPL14.SetPaintingStrategy(PaintingStrategy.DASHES); DPL14.hideBubble(); DPL14.hideTitle();
DPL14.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL14.SetLineWeight(1);

rec DifficultPrice15;
if DPLcounter==15 && DPLcounter[1]!=15 {
DifficultPrice15= close; } else {DifficultPrice15=CompoundValue(1, DifficultPrice15[1], NAN);};
plot DPL15=DifficultPrice15;
DPL15.SetPaintingStrategy(PaintingStrategy.DASHES); DPL15.hideBubble(); DPL15.hideTitle();
DPL15.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL15.SetLineWeight(1);

rec DifficultPrice16;
if DPLcounter==16 && DPLcounter[1]!=16 {
DifficultPrice16= close; } else {DifficultPrice16=CompoundValue(1, DifficultPrice16[1], NAN);};
plot DPL16=DifficultPrice16;
DPL16.SetPaintingStrategy(PaintingStrategy.DASHES); DPL16.hideBubble(); DPL16.hideTitle();
DPL16.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL16.SetLineWeight(1);


rec DifficultPrice17;
if DPLcounter==17 && DPLcounter[1]!=17 {
DifficultPrice17= close; } else {DifficultPrice17=CompoundValue(1, DifficultPrice17[1], NAN);};
plot DPL17=DifficultPrice17;
DPL17.SetPaintingStrategy(PaintingStrategy.DASHES); DPL17.hideBubble(); DPL17.hideTitle();
DPL17.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL17.SetLineWeight(1);

rec DifficultPrice18;
if DPLcounter==18 && DPLcounter[1]!=18 {
DifficultPrice18= close; } else {DifficultPrice18=CompoundValue(1, DifficultPrice18[1], NAN);};
plot DPL18=DifficultPrice18;
DPL18.SetPaintingStrategy(PaintingStrategy.DASHES); DPL18.hideBubble(); DPL18.hideTitle();
DPL18.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL18.SetLineWeight(1);

rec DifficultPrice19;
if DPLcounter==19 && DPLcounter[1]!=19 {
DifficultPrice19= close; } else {DifficultPrice19=CompoundValue(1, DifficultPrice19[1], NAN);};
plot DPL19=DifficultPrice19;
DPL19.SetPaintingStrategy(PaintingStrategy.DASHES); DPL19.hideBubble(); DPL19.hideTitle();
DPL19.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL19.SetLineWeight(1);

rec DifficultPrice20;
if DPLcounter==20 && DPLcounter[1]!=20 {
DifficultPrice20= close; } else {DifficultPrice20=CompoundValue(1, DifficultPrice20[1], NAN);};
plot DPL20=DifficultPrice20;
DPL20.SetPaintingStrategy(PaintingStrategy.DASHES); DPL20.hideBubble(); DPL20.hideTitle();
DPL20.SetDefaultColor(GlobalColor("DifficultPriceLine"));
DPL20.SetLineWeight(1);

### Caution Relative Volume compares the current OrderFlow to the Volume of the EXACT same time of day for several times. For instance the Volume usually increases in the first minute after 9:30 AM EST as the NewYork WallStreet Opens... It would be completely meaningless to compare the open Volume to any other time of day except the market open of the previous days.
#Testing enough Data is loaded to calculate Relative Volumes
def CalendarDays = GetYYYYMMDD();
def NumberOfCalendarDaysOnChart = DaysFromDate(First(CalendarDays)) + GetDayOfWeek(First(CalendarDays));
AddLabel(NumberOfCalendarDaysOnChart <10, "RelativeVolume Error: Only " + NumberOfCalendarDaysOnChart + " days loaded on chart...Please add more days", Color.RED);


AddLabel(PastPriceMovePercent <40, " Caution: RelativePriceMove is only " + PastPriceMovePercent + " %. Please consider a larger relative price comparison to the past days.", Color.YELLOW);


Dynamic Volume Profile

Code:
#____   ____.__                        _____  ____   ____    .__                      
#\   \ /   /|__| ______  _  __   _____/ ____\ \   \ /   /___ |  |  __ __  _____   ____
# \   V   / |  |/ __ \ \/ \/ /  /  _ \   __\   \   V   /  _ \|  | |  |  \/     \_/ __ \
#  \     /  |  \  ___/\     /  (  <_> )  |      \     (  <_> )  |_|  |  /  | |  \  ___/
#   \___/   |__|\___/  \/\_/    \____/|__|       \___/ \____/|____/____/|__|_|  /\___/
                                                                                                                                                 

#         _                              ___ _ _    
# _ _ ___| |_ _ _____ ___    ___ ___ ___|  _|_| |___
#| | | . | | | |     | -_|  | . |  _| . |  _| | | -_|
# \_/|___|_|___|_|_|_|___|  |  _|_| |___|_| |_|_|___|
#                           |_|                    


# Special thanks to Welkin from UseThinkScript.com

# For any asset, knowing the volume of trades is useless without context.
# We must be include patterns which are out of view of most charts.
# Large spikes and drops of Volume must considered relattive to the delta of price and the time of occurance.

# There is a strong statistical link between the afternoon and overnight volumes and the ease of which the market will trend into the following day.


def h = high;
def l = low;
def hlc = hlc3;
def NAN = Double.NaN;

input SpacesLabels = 10; #hint SpacesLabels: The number of spaces you wish to extend the Labels to make viewing easier.
def b  = SpacesLabels;
def b1 = b + 1;
input MarketOpenTime = 0930;#hint MarketOpenTime: Time to begin the morning session, regular trading hours RTH.
input AfternoonSessionTime = 1515; #hint AfternoonSessionTime: Time to begin the afternoon session that you wish to compare to the next day.

def BeginAfternoonSession = if SecondsTillTime(AfternoonSessionTime) crosses below 1 then yes else no;
def BeginEveningSession = if GetTime() crosses above RegularTradingEnd(GetYYYYMMDD()) then yes else no;
def EndEveningSession = if GetTime() crosses above RegularTradingStart(GetYYYYMMDD()) then yes else no;

def FindAfternoonHigh = if BeginAfternoonSession then h else if !BeginAfternoonSession && h > FindAfternoonHigh[1] then h else if !BeginAfternoonSession  && h <= FindAfternoonHigh[1] then FindAfternoonHigh[1] else h;
def SelectAfternoonHigh = if BeginEveningSession then FindAfternoonHigh[1] else SelectAfternoonHigh[1];
plot AfternoonSessionHigh = SelectAfternoonHigh;
def FindAfternoonLow = if BeginAfternoonSession then l else if !BeginAfternoonSession && l < FindAfternoonLow[1] then l else if !BeginAfternoonSession  && l >= FindAfternoonLow[1] then FindAfternoonLow[1] else l;
def SelectAfternoonLow = if BeginEveningSession then FindAfternoonLow[1] else SelectAfternoonLow[1];
plot AfternoonSessionLow = SelectAfternoonLow;

def FindOvernightHigh = if BeginEveningSession then h else if !BeginEveningSession && h > FindAfternoonHigh[1] then h else if !BeginEveningSession  && h <= FindOvernightHigh[1] then FindOvernightHigh[1] else h;
def SelectOvernightHigh = if EndEveningSession then FindOvernightHigh[1] else SelectOvernightHigh[1];
plot OvernightHigh = SelectOvernightHigh;
def FindOvernightLow = if BeginEveningSession then l else if !BeginEveningSession && l < FindOvernightLow[1] then l else if !BeginEveningSession  && l >= FindOvernightLow[1] then FindOvernightLow[1] else l;
def SelectOvernightLow = if EndEveningSession then FindOvernightLow[1] else SelectOvernightLow[1];
plot OvernightLow = SelectOvernightLow;

input LineWeight = 1;
input ShowSimpleAfternoonTrendlines = yes;
input ShowSimpleOvernightTrendlines = yes;
def SimpleTrendsFromPastVolumes = if h > Min(OvernightHigh, AfternoonSessionHigh) then +1 else if l < Max(OvernightLow, AfternoonSessionLow) then -1 else 0;
AfternoonSessionHigh.SetDefaultColor(Color.LIGHT_GRAY);
#AfternoonSessionHigh.AssignValueColor(if h >= AfternoonSessionHigh && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= AfternoonSessionHigh && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW); #AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), AfternoonSessionHigh[b1], "Yesterday Afternoon High", color.blue, yes);
AfternoonSessionHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
AfternoonSessionHigh.SetLineWeight(LineWeight);
AfternoonSessionHigh.SetHiding(!ShowSimpleAfternoonTrendlines);
AfternoonSessionLow.SetDefaultColor(Color.LIGHT_GRAY);
#AfternoonSessionLow.AssignValueColor(if h >= AfternoonSessionLow && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= AfternoonSessionLow && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW);
#AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), AfternoonSessionLow[b1], "Yesterday Afternoon Low", color.blue, no);
AfternoonSessionLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
AfternoonSessionLow.SetHiding(!ShowSimpleAfternoonTrendlines);
AfternoonSessionHigh.SetLineWeight(LineWeight);
OvernightHigh.SetDefaultColor(Color.LIGHT_GRAY);
#OvernightHigh.AssignValueColor(if h >= OvernightHigh && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= OvernightHigh && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW); #AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]), OvernightHigh[b1], "Overnight High", color.blue, yes);
OvernightHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
OvernightHigh.SetLineWeight(LineWeight);
OvernightHigh.SetHiding(!ShowSimpleOvernightTrendlines);
OvernightLow.SetDefaultColor(Color.LIGHT_GRAY);
#OvernightLow.AssignValueColor(if h >= OvernightLow && SimpleTrendsFromPastVolumes == 1 then Color.GREEN else if l <= OvernightLow && SimpleTrendsFromPastVolumes == -1 then Color.RED else Color.YELLOW); #AddChartBubble( IsNaN(close[b]) and !IsNaN(close[b1]),OvernightLow[b1], "Overnight Low", color.blue, no);
OvernightLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
OvernightLow.SetLineWeight(LineWeight);
OvernightLow.SetHiding(!ShowSimpleOvernightTrendlines);


def isETH = CompoundValue(1, if BeginAfternoonSession then 1 else if EndEveningSession then 0 else isETH[1], 0);
def isAfterHoursSessions  = if isETH then 1 else 0;

input pricePerRowHeightMode = { AUTOMATIC, default TICKSIZE}; #hint pricePerRowHeightMode: There are often advantages to using Tick data when possible.
input multiplier = 1;
def onExpansion = no;
input profiles = 10;
input valueAreaPercent = 65;

def cond          = isAfterHoursSessions[1] != isAfterHoursSessions;
def profilecount  = if cond then profilecount[1] + 1 else profilecount[1];
def profiletoday  = HighestAll(profilecount) - profilecount ;

def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
}

profile OvernightVolume = VolumeProfile("startNewProfile" = cond, "onExpansion" = no, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def OvernightCON = CompoundValue(1, onExpansion, no);

def OvernightPointOfControl = if IsNaN(close) then OvernightPointOfControl[1] else if IsNaN(OvernightVolume.GetPointOfControl()) and OvernightCON then OvernightPointOfControl[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetPointOfControl() else OvernightPointOfControl[1];
def OvernightHVA = if IsNaN(close) then OvernightHVA[1] else if IsNaN(OvernightVolume.GetHighestValueArea()) and OvernightCON then OvernightHVA[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetHighestValueArea() else OvernightHVA[1];
def OvernightLVA = if IsNaN(close) then OvernightLVA[1] else if IsNaN(OvernightVolume.GetLowestValueArea()) and OvernightCON then OvernightLVA[1] else if isAfterHoursSessions == 1 then OvernightVolume.GetLowestValueArea() else OvernightLVA[1];

DefineGlobalColor("Overnight POC Lines", Color.GRAY);
DefineGlobalColor("Overnight VAHigh Lines", Color.GRAY);
DefineGlobalColor("Overnight VALow Lines", Color.GRAY);

input OvernightLineWeight = 1;
input ShowOvernightPOC = yes;
input ShowOvernightHVA = yes;
input ShowOvernightLVA = yes;
plot OvernightPOC    = OvernightPointOfControl;
plot OvernightVAHigh = OvernightHVA;
plot OvernightVALow  = OvernightLVA;
#OvernightPOC.SetDefaultColor(GlobalColor("Point Of Control"));
OvernightPOC.SetDefaultColor(GlobalColor("Overnight POC Lines"));
OvernightPOC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
OvernightPOC.SetLineWeight(OvernightLineWeight);
OvernightPOC.SetHiding(!ShowOvernightPOC);
OvernightVAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
#OvernightVAHigh.SetDefaultColor(GlobalColor("Value Area"));
OvernightVAHigh.SetDefaultColor(GlobalColor("Overnight VAHigh Lines"));
OvernightVAHigh.SetLineWeight(OvernightLineWeight);
OvernightVAHigh.SetHiding(!ShowOvernightHVA);
OvernightVALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
#OvernightVALow.SetDefaultColor(GlobalColor("Value Area"));
OvernightVALow.SetDefaultColor(GlobalColor("Overnight VALow Lines"));
OvernightVALow.SetLineWeight(OvernightLineWeight);
OvernightVALow.SetHiding(!ShowOvernightLVA);

#AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]), OvernightPOC[b1], "Overnight POC Lines", OvernightPOC.TakeValueColor(),yes);
#AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]), OvernightVAHigh[b1], "Overnight POC Lines", OvernightVAHigh.TakeValueColor(),yes);
#AddChartBubble(IsNaN(close[b]) and !IsNaN(close[b1]),OvernightVALow[b1], "Overnight POC Lines",OvernightVALow.TakeValueColor(), no);

plot PointOfControlClouds = NAN;
PointOfControlClouds.HideBubble();
PointOfControlClouds.HideTitle();
PointOfControlClouds.DefineColor("OvernightPointOfControlArea", Color.DARK_GRAY);
#AddCloud(OvernightVAHigh, OvernightVALow, PointOfControlClouds.Color("OvernightPointOfControlArea"));


input RandomWalkDriftingLength = 33;#hint RandomWalkDriftingLength: This is the length the indicator will use to segment volume profiles with Non-repainting pivots.
def bnOK = BarNumber() > RandomWalkDriftingLength;
def isHigher = fold f = 1 to RandomWalkDriftingLength + 1 with p = 1
               while p do h > GetValue(h, -f);
def HH = if bnOK and isHigher
         and h == Highest(h, RandomWalkDriftingLength)
         then h else NAN;
def isLower = fold j = 1 to RandomWalkDriftingLength + 1 with q = 1
              while q do l < GetValue(l, -j);
def LL = if bnOK and isLower
         and l == Lowest(l, RandomWalkDriftingLength)
         then l else NAN;

def PivH = if HH > 0 then 1 else 0;
def PivL = if LL > 0 then 1 else 0;

rec dir = CompoundValue(1, if !IsNaN(PivL) then 1 else if !IsNaN(PivH) then -1 else dir[1], 0);

def Dn = dir crosses above 0;
def Up = dir crosses below 0;

def UpTime = if Up then 1 else UpTime[1] + 1;
def NewUp = if Up then h else NewUp[1]; # Recent High

def DownTime = if Dn then 1 else DownTime[1] + 1;
def NewDown = if Dn then l else NewDown[1]; # Recent Low

##############
### CLOCK ####
##############
def yyyymmdd = GetYYYYMMDD();
def seconds = SecondsFromTime(0);
def month = GetYear() * 12 + GetMonth();
def year = GetYear();
def day_number = DaysFromDate(First(yyyymmdd)) + GetDayOfWeek(First(yyyymmdd));
def dom = GetDayOfMonth(yyyymmdd);
def dow = GetDayOfWeek(yyyymmdd - dom + 1);
def expthismonth = (if dow > 5 then 27 else 20) - dow;
def exp_opt = month + (dom > expthismonth);
def timeOfPhaseProfile = BarNumber() - 1;
####################################
# TICKS: Show true Volume at Price #
####################################
def ExpandTheLinesToNextSegment = no;
input NumberOfVolumeProfiles = 50; #hint NumberOfVolumeProfiles: The number of Volume Profiles you wish to view.
input ProfilevalueAreaPercent = 65;# ProfilevalueAreaPercent: The % of all Volume traded in the profile that you wish to focus on your profiles.
def NewVolumeProfile = if DownTime == 1 or UpTime == 1 then 1 else NAN;
input ShowPOCclouds = no;# hint ShowPOCclouds: Use to highlight the higher Volume areas of the Volume Profile.

profile vol = VolumeProfile("startNewProfile" = (NewVolumeProfile), "onExpansion" = ExpandTheLinesToNextSegment, "numberOfProfiles" = NumberOfVolumeProfiles, "pricePerRow" = PricePerRow.TICKSIZE, "value area percent" = ProfilevalueAreaPercent);
input ProfileTransparency = 50; #75;#hint ProfileTransparency: The Transparency of the Volume Profiles
vol.Show(CreateColor(0, 102, 204), if ShowPOCclouds then CreateColor(0, 102, 204) else Color.CURRENT, if ShowPOCclouds then CreateColor(0, 102, 204) else Color.CURRENT, ProfileTransparency);



def con = CompoundValue(1, ExpandTheLinesToNextSegment, no);
def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
def hVA = if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else vol.GetHighestValueArea();
def lVA = if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else vol.GetLowestValueArea();

def hProfile = if IsNaN(vol.GetHighest()) and con then hProfile[1] else vol.GetHighest();
def lProfile = if IsNaN(vol.GetLowest()) and con then lProfile[1] else vol.GetLowest();
def plotsDomain = IsNaN(close) == ExpandTheLinesToNextSegment;

DefineGlobalColor("Point Of Control", Color.ORANGE);
DefineGlobalColor("Value Area", Color.CYAN);

input MainLineWeight = 1;
input ShowMainPOC = yes;
input ShowMainHVA = yes;
input ShowMainLVA = yes;

plot POC = if plotsDomain then pc else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;

POC.SetDefaultColor(GlobalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC.HideBubble();
POC.HideTitle();
POC.SetLineWeight(MainLineWeight);
POC.SetHiding(!ShowMainPOC);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
VAHigh.SetDefaultColor(GlobalColor("Value Area"));
VAHigh.HideBubble();
VAHigh.HideTitle();
VAHigh.SetLineWeight(MainLineWeight);
VAHigh.SetHiding(!ShowMainHVA);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); #(PaintingStrategy.LINE);
VALow.SetDefaultColor(GlobalColor("Value Area"));
VALow.HideBubble();
VALow.HideTitle();
VALow.SetLineWeight(MainLineWeight);
VALow.SetHiding(!ShowMainLVA);

#plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
#plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
#ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); ProfileHigh.SetDefaultColor(Color.Dark_Green); #ProfileHigh.hideBubble(); ProfileHigh.HideTitle(); ProfileHigh.setLineWeight(1);
#ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL); ProfileLow.SetDefaultColor(Color.Dark_Red); #ProfileLow.hideBubble();  ProfileLow.HideTitle(); ProfileLow.setLineWeight(1);

As for the overall performance, I think the winsorizing has definitely helped...The initial load of the scripts and dataset took 10-15 seconds and subsequent loads took 3-5 seconds...YMMV, but I think the performance is much better, that is depending on what resources you are able to allocate to TOS and what kind of hardware you have...My system is 8 years old now and I'm well aware that I'm overdue for a new box, but it makes for a good benchmark when testing performance...

As for the dreaded Repainting, I didn't see any instances...With that said, the 1-minute chart does do some funky screen painting upon initial loading, but I think that is TOS trying to draw a significant data stream with only one core to work with...FWIW, I think Schwab should seriously consider investing in a multi-core rewrite of TOS instead of creating a doppelganger, but what do I know... 🤣

Bottom Line: I think VoV 2.0 is a big step forward! We'll see what happens at the Open tomorrow... 😎
And here is what I get with @netarchitech's adjustments and changes. Same as above, really. Except for some reason on the exact same ticker, time frame, settings - I get a different # of DPL's...see screen shot two down.
2024-01-31_12h05_26.png


1706722177665.png
 

Attachments

  • 1706722137211.png
    1706722137211.png
    64.4 KB · Views: 93
@MatthewA @khpro59 @Ramisegal

Things seem to be rolling along in terms of VoV 2.0...just waiting on the FED Interest Rate decision @ 2PM...

@MatthewA With respect to Volatility, I went digging through my Script Library and came across Larry Williams' Vix Fix:

Code:
declare lower;
declare zerobase;

input PaintBars = no; #yes; #hint PaintBars: Apply Custom Coloring to Bars
def pd = 22; #hint pd: LookBack Period Standard Deviation High
def bbl = 20; #hint bbl: Bolinger Band Length
def mult = 2.0; #hint mult: Bollinger Band Standard Deviation Up \n minval=1 and maxval=5
def lb = 50; #hint lb: Look Back Period Percentile High
def ph = 0.85; #hint ph: Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%
def sbc = yes; #hint sbc: Show Highlight Bar if WVF WAS True and IS Now False
def sbcc = yes; #hint sbcc: Show Highlight Bar if WVF IS True
def sbcFilt = yes; #hint sbcFilt: Show Highlight Bar For Filtered Entry
def sbcAggr = no; #hint sbcAggr: Show Highlight Bar For AGGRESSIVE Filtered Entry
def sgb = yes; #hint sgb: Turn remaining Bars Gray?

def ltLB = 40; #hint ltLB: Long-Term Look Back Current Bar Has To Close Below This Value OR Medium Term--Default=40 \n minval=25 and maxval=99 
def mtLB = 14; #hint mtLB: Medium-Term Look Back Current Bar Has To Close Below This Value OR Long Term--Default=14 \n minval=10 and maxval=20
def str = 3; #hint str: Entry Price Action Strength--Close > X Bars Back---Default=3 \n minval=1 and maxval=9

def sa1 = no; #hint sa1: Show Alert WVF = True?
def sa2 = no; #hint sa2: Show Alert WVF Was True Now False?
def sa3 = no; #hint sa3: Show Alert WVF Filtered?
def sa4 = no; #hint sa4: Show Alert WVF AGGRESSIVE Filter?


### PriceAction Section ###

def pctP = 66; #hint pctP: range -> 1 to 99 -> % Input For PinBars, What % The Wick Of Candle Has To Be
def pblb = 6; #hint pblb: range -> 1 to 100 -> PinBars Look Back Period To Define The Trend of Highs and Lows
def pctS = 5; #hint pctS: range -> 1 to 99 -> % Input For Shaved Bars, % of Range it Has To Close On The Lows or Highs
def spb = yes; #hint spb: Show PinBars?
def ssb = yes; #hint ssb: Show Shaved Bars?
def sib = no; #hint sib: Show Inside Bars?
def sob = no; #hint sob: Show Outside Bars?
#input sgb = no; #hint sgb: Turn Bars Gray?

# PinBar Percentages
def pctCp = pctP * .01;
def pctCPO = 1 - pctCp;

# Shaved Bar Percentages
def pctCs = pctS * .01;
def pctSPO = pctCs;

def range = high - low;

# PinBars
def pBarUp = if spb and open > high - (range * pctCPO) and close > high - (range * pctCPO) and low <= Lowest(pblb) then 1 else 0;
def pBarDn = if spb and open < high - (range *  pctCp) and close < high - (range * pctCp) and high >= Highest(pblb) then 1 else 0;

# Shaved Bars
def sBarUp = if ssb and (close >= (high - (range * pctCs))) then 1 else 0;
def sBarDown = if ssb and (close <= (low + (range * pctCs))) then 1 else 0;

# Inside/Outside Bars
def insideBar = if sib and (high <= high[1] and low >= low[1]) then 1 else 0;
def outsideBar = if sob and (high > high[1] and low < low[1]) then 1 else 0;


## Volatility ##

plot wvf = ((Highest(close, pd) - close) / (Highest(close, pd))) * 100;

def sDev = mult * StDev(wvf, bbl);
def midLine = Average(wvf, bbl);
#plot midLine = average(wvf, bbl);
#midLine.setDefaultColor(Color.CYAN);
#midLine.setLineWeight(2);
def lowerBand = midLine - sDev;
def upperBand = midLine + sDev;
def rangeHigh = (Highest(wvf, lb)) * ph;

wvf.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
wvf.AssignValueColor(if wvf >= upperBand or wvf >= rangeHigh 
                     then Color.RED 
                     else if sbc and ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh))
                          then CreateColor(0, 192, 0) #Green
                          else Color.DARK_GRAY);
wvf.SetLineWeight(3);

def upRange = low > low[1] and close > high[1];
def upRange_Aggr = close > close[1] and close > open[1];

def filtered = ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh));
def filtered_Aggr = (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh);


def alert1 = if wvf >= upperBand or wvf >= rangeHigh then 1 else 0;
def alert2 = if (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh) then 1 else 0;
def alert3 = if upRange and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered then 1 else 0;
def alert4 = if upRange_Aggr and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered_Aggr then 1 else 0;

202401311335_VoV_2_with_Vix_Fix_.jpg


Back to VoV 2.0 for a minute...there seems to be something going on with the DPL's, I think...on the three charts that I use (15 day 1 minute, 30 day 5 minute and 90 day 30 minute) I only have one DPL showing up, even though the DPL label reports that there are 11...Your thoughts?
 
simplified it a bit for my personal taste
That color scheme looks very nice. 😃👍
will def be interested to see more developments.

I was going to suggest an option for users who do not want to color their bars bright or dark to use EoM as part of a line near price. The reason for that is I know that EoM may seem like its just the inverse of DPL but there are more mathematics possible.

1) On the simple side: you may want to know about areas where price will later coast through Easily , to prevent you from moving into fake moves. . . Please look in the past at days where the SPY futures failed to leave a narrow range of DPLs

2) On the More complex side: the market naturally expands and contacts in irregular cycles, and so the EoM score is unlikely to ever repeat more than 3 bars or so. We could use some calculus to derive a relationship for this or also we may revisit @mashume Curving solution with a nonrepainting version. When the curve of the HullMoving Average was approximated we used a very distant target for the next bar which was difficult to reach. However by shortening the target when the EoM is large and lengthening the target when the EoM is small we could set the curve back a bar and no longer have to deal with repainting. https://usethinkscript.com/threads/...ng-points-and-concavity-2nd-derivatives.1803/

3) Even if you do not need EoM to color the bars for the past to reasons I am using calculus to derive long term polynomials with EoM and Mobiuses Delta Momentums https://usethinkscript.com/threads/tmo-true-momentum-oscillator-for-thinkorswim.9413/page-3

Yes it does seem redundant and inefficient to have EoM and DPL together even if they were written by different people but if we Winsorize both terms separately we still need those for other option 😉👍
 
Status
Not open for further replies.

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
395 Online
Create Post

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