NextSignal's Market Volume Profile For ThinkOrSwim

NextSignal's Market Volume Profile For ThinkOrSwim
Per @itsjt562 request
Ruby:
plot zero = 0;
zero.setdefaultcolor(color.black);

addlabel(yes," POC ",createcolor(100,0,255));

input pricePerRowHeightMode = {default TICKSIZE, AUTOMATIC};
input timePerProfile = {default Bar, CHART};
def onExpansion = no;
def period;
switch (timePerProfile) {
case CHART:
period = 0;
case Bar:
period = BarNumber() - 1;}
rec count = if period != period[1] then (count[1] + period - period[1]) % 20 else count[1];
def cond = count < count[1] + period - period[1];
def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
height = PricePerRow.AUTOMATIC;
case TICKSIZE:
height = PricePerRow.TICKSIZE;}
profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);
def con = CompoundValue(1, onExpansion, no);
def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
def plotsDomain = IsNaN(close) == onExpansion;
vol.Show(CreateColor(40,60,80));

plot POC = if plotsDomain then pc else Double.NaN;
POC.setpaintingstrategy(paintingstrategy.horizontal);
POC.setdefaultcolor(createcolor(100,0,255));
POC.setlineweight(3);
POC.hidebubble();
POC.hidetitle();

profile tpo = timeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);
def tpoPC = if IsNaN(tpo.getPointOfControl()) and con then tpoPC[1] else tpo.getPointOfControl();
plot tpoPOC = if plotsDomain then tpoPC else Double.NaN;
tpoPOC.setpaintingstrategy(paintingstrategy.horizontal);
tpoPOC.setdefaultcolor(createcolor(100,0,255));
tpoPOC.setlineweight(3);
tpoPOC.hidebubble();
tpoPOC.hidetitle();

### POC extensions

def y= if !IsNaN(pc) then pc else y[1];
plot vpocext = y[20];
vpocext.SetDefaultColor(CreateColor(100,0,255));
vpocext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
vpocext.SetStyle(Curve.SHORT_DASH);
vpocext.HideBubble();
vpocext.HideTitle();

def x = if !IsNaN(tpoPC) then tpopc else x[1];
plot tpoext = x[20];
tpoext.SetDefaultColor(CreateColor(100,0,255));
tpoext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
tpoext.SetStyle(Curve.SHORT_DASH);
tpoext.HideBubble();
tpoext.HideTitle();
 
Last edited by a moderator:
This is a great script and a unique way of looking at volume profile. Highly recommend more people check it out. The POCExt lines are simply extensions of the POC and TPO_POC lines for the 'next' set of candles. I actually hide the POC and TPO_POC lines and ONLY use the EXT lines...but that's just me.
 
Agreed!

I'm trying to figure out, is each profile based on either a accumulation phase or a trend phase? It doesn't appear to be based upon a specific period of time...
 
@bigboss is corrrect. There is a setting for the number of bars - this will change the length of the profile. There is another setting to show/hide the profile. If you turn that on and adjust the number of bars, you will get a better sense of what is happening 'under the covers'.
 
Interestingly, the option to adjust the number of bars isn't showing up in my settings window. Is there any advantage to manually adjusting the number of bars rather than using a daily profile (I'm relatively new to learning about/using the volume profile)?
 
Interestingly, the option to adjust the number of bars isn't showing up in my settings window. Is there any advantage to manually adjusting the number of bars rather than using a daily profile (I'm relatively new to learning about/using the volume profile)?
This particular indicator has the options to create the profile every 20 bars, or show a profile for the entire chart. You could modify the line that determines the "rec count" to mod (%) by any number of bars, then change the extensions to look back the same number of bars.

As @FutureTony alluded to, a very powerful use of the tpo (market) and volume profiles is to project the current day's point of control, value area high, and value area low onto the next day. If you'd like a good resource on how to effectively trade the market profile and volume profiles in this way, I'd recommend you pick up a copy of the book Secrets of a Pivot Boss. The first section of the book discusses the concept of the Money Zone, which is all about Market Profile.

Other folks like to split up the profiles between ETH and RTH. I don't think this next signals indicator is a particularly great way to trade market profiles, but I've gone ahead and modified it to rollover profiles at RTH and ETH, or at the day break so you can study it a bit differently. In particular take a look at how today's price is attracted toward yesterdays POCs.


Code:
plot zero = 0;
zero.SetDefaultColor(Color.BLACK);

def today = getyyyymmdd();
def c = today <> today[1];
def rth = gettime() > regulartradingstart(today);
def r = rth and !rth[1];
input rollover = {default day, eth_rth};
AddLabel(yes, " POC ", CreateColor(100, 0, 255));

input pricePerRowHeightMode = {default TICKSIZE, AUTOMATIC};
def onExpansion = no;
def cond = if rollover==rollover.day then c else c or r;
def bar_ext = if cond then barnumber() else bar_ext[1];
def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
}
profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);
def con = CompoundValue(1, onExpansion, no);
def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
def plotsDomain = IsNaN(close) == onExpansion;
vol.Show(CreateColor(40, 60, 80));

plot POC = if plotsDomain then pc else Double.NaN;
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC.SetDefaultColor(CreateColor(100, 0, 255));
POC.SetLineWeight(3);
POC.HideBubble();
POC.HideTitle();

profile tpo = TimeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);
def tpoPC = if IsNaN(tpo.GetPointOfControl()) and con then tpoPC[1] else tpo.GetPointOfControl();
plot tpoPOC = if plotsDomain then tpoPC else Double.NaN;
tpoPOC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
tpoPOC.SetDefaultColor(CreateColor(100, 0, 255));
tpoPOC.SetLineWeight(3);
tpoPOC.HideBubble();
tpoPOC.HideTitle();

### POC extensions

def y = if !IsNaN(pc) then pc else y[1];
plot vpocext = getvalue(y,barnumber()-bar_ext+1);
vpocext.SetDefaultColor(CreateColor(100, 0, 255));
vpocext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
vpocext.SetStyle(Curve.SHORT_DASH);
vpocext.HideBubble();
vpocext.HideTitle();

def x = if !IsNaN(tpoPC) then tpoPC else x[1];
plot tpoext = getvalue(x,barnumber()-bar_Ext+1);
tpoext.SetDefaultColor(CreateColor(100, 0, 255));
tpoext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
tpoext.SetStyle(Curve.SHORT_DASH);
tpoext.HideBubble();
tpoext.HideTitle();
 
BWiLEOQ.png


Is there any easy way to remove the blue cloud part from the script? I've got it set on each candle poc so the shade area isn't necessary.

Code:
zero.setdefaultcolor(color.black);



addlabel(no," POC ",createcolor(100,0,255));



input pricePerRowHeightMode = {default TICKSIZE, AUTOMATIC};

input timePerProfile = {default Bar, CHART};

def onExpansion = no;

def period;

switch (timePerProfile) {

case CHART:

    period = 0;

case Bar:

    period = BarNumber() - 1;}

rec count = if period != period[1] then (count[1] + period - period[1]) % 1 else count[1];

def cond = count < count[1] + period - period[1];

def height;

switch (pricePerRowHeightMode) {

case AUTOMATIC:

    height = PricePerRow.AUTOMATIC;

case TICKSIZE:

    height = PricePerRow.TICKSIZE;}

profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);

def con = CompoundValue(1, onExpansion, no);

def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();

def plotsDomain = IsNaN(close) == onExpansion;

vol.Show(CreateColor(40,60,80));



plot POC = if plotsDomain then pc else Double.NaN;

POC.setpaintingstrategy(paintingstrategy.horizontal);

POC.setdefaultcolor(createcolor(100,0,255));

POC.setlineweight(3);

POC.hidebubble();

POC.hidetitle();



profile tpo = timeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);

def tpoPC = if IsNaN(tpo.getPointOfControl()) and con then tpoPC[1] else tpo.getPointOfControl();

plot tpoPOC = if plotsDomain then tpoPC else Double.NaN;

tpoPOC.setpaintingstrategy(paintingstrategy.horizontal);

tpoPOC.setdefaultcolor(createcolor(100,0,255));

tpoPOC.setlineweight(3);

tpoPOC.hidebubble();

tpoPOC.hidetitle();



###  POC extensions



def y= if !IsNaN(pc) then pc else y[1];

plot vpocext = y[20];

vpocext.SetDefaultColor(CreateColor(100,0,255));

vpocext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

vpocext.SetStyle(Curve.SHORT_DASH);

vpocext.HideBubble();

vpocext.HideTitle();



def x = if !IsNaN(tpoPC) then tpopc else x[1];

plot tpoext = x[20];

tpoext.SetDefaultColor(CreateColor(100,0,255));

tpoext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

tpoext.SetStyle(Curve.SHORT_DASH);

tpoext.HideBubble();

tpoext.HideTitle();
 
Ruby:
vol.Show(CreateColor(40,60,80));
BWiLEOQ.png


Is there any easy way to remove the blue cloud part from the script? I've got it set on each candle poc so the shade area isn't necessary.

Code:
zero.setdefaultcolor(color.black);



addlabel(no," POC ",createcolor(100,0,255));



input pricePerRowHeightMode = {default TICKSIZE, AUTOMATIC};

input timePerProfile = {default Bar, CHART};

def onExpansion = no;

def period;

switch (timePerProfile) {

case CHART:

    period = 0;

case Bar:

    period = BarNumber() - 1;}

rec count = if period != period[1] then (count[1] + period - period[1]) % 1 else count[1];

def cond = count < count[1] + period - period[1];

def height;

switch (pricePerRowHeightMode) {

case AUTOMATIC:

    height = PricePerRow.AUTOMATIC;

case TICKSIZE:

    height = PricePerRow.TICKSIZE;}

profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);

def con = CompoundValue(1, onExpansion, no);

def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();

def plotsDomain = IsNaN(close) == onExpansion;

vol.Show(CreateColor(40,60,80));



plot POC = if plotsDomain then pc else Double.NaN;

POC.setpaintingstrategy(paintingstrategy.horizontal);

POC.setdefaultcolor(createcolor(100,0,255));

POC.setlineweight(3);

POC.hidebubble();

POC.hidetitle();



profile tpo = timeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);

def tpoPC = if IsNaN(tpo.getPointOfControl()) and con then tpoPC[1] else tpo.getPointOfControl();

plot tpoPOC = if plotsDomain then tpoPC else Double.NaN;

tpoPOC.setpaintingstrategy(paintingstrategy.horizontal);

tpoPOC.setdefaultcolor(createcolor(100,0,255));

tpoPOC.setlineweight(3);

tpoPOC.hidebubble();

tpoPOC.hidetitle();



###  POC extensions



def y= if !IsNaN(pc) then pc else y[1];

plot vpocext = y[20];

vpocext.SetDefaultColor(CreateColor(100,0,255));

vpocext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

vpocext.SetStyle(Curve.SHORT_DASH);

vpocext.HideBubble();

vpocext.HideTitle();



def x = if !IsNaN(tpoPC) then tpopc else x[1];

plot tpoext = x[20];

tpoext.SetDefaultColor(CreateColor(100,0,255));

tpoext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

tpoext.SetStyle(Curve.SHORT_DASH);

tpoext.HideBubble();

tpoext.HideTitle();
This line:
vol.Show(CreateColor(40,60,80));
creates the cloud. Comment it out or remove it to remove the shading.
 
This particular indicator has the options to create the profile every 20 bars, or show a profile for the entire chart. You could modify the line that determines the "rec count" to mod (%) by any number of bars, then change the extensions to look back the same number of bars.

As @FutureTony alluded to, a very powerful use of the tpo (market) and volume profiles is to project the current day's point of control, value area high, and value area low onto the next day. If you'd like a good resource on how to effectively trade the market profile and volume profiles in this way, I'd recommend you pick up a copy of the book Secrets of a Pivot Boss. The first section of the book discusses the concept of the Money Zone, which is all about Market Profile.

Other folks like to split up the profiles between ETH and RTH. I don't think this next signals indicator is a particularly great way to trade market profiles, but I've gone ahead and modified it to rollover profiles at RTH and ETH, or at the day break so you can study it a bit differently. In particular take a look at how today's price is attracted toward yesterdays POCs.


Code:
plot zero = 0;
zero.SetDefaultColor(Color.BLACK);

def today = getyyyymmdd();
def c = today <> today[1];
def rth = gettime() > regulartradingstart(today);
def r = rth and !rth[1];
input rollover = {default day, eth_rth};
AddLabel(yes, " POC ", CreateColor(100, 0, 255));

input pricePerRowHeightMode = {default TICKSIZE, AUTOMATIC};
def onExpansion = no;
def cond = if rollover==rollover.day then c else c or r;
def bar_ext = if cond then barnumber() else bar_ext[1];
def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
}
profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);
def con = CompoundValue(1, onExpansion, no);
def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
def plotsDomain = IsNaN(close) == onExpansion;
vol.Show(CreateColor(40, 60, 80));

plot POC = if plotsDomain then pc else Double.NaN;
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC.SetDefaultColor(CreateColor(100, 0, 255));
POC.SetLineWeight(3);
POC.HideBubble();
POC.HideTitle();

profile tpo = TimeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = 1000, "pricePerRow" = height, "value area percent" = 68);
def tpoPC = if IsNaN(tpo.GetPointOfControl()) and con then tpoPC[1] else tpo.GetPointOfControl();
plot tpoPOC = if plotsDomain then tpoPC else Double.NaN;
tpoPOC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
tpoPOC.SetDefaultColor(CreateColor(100, 0, 255));
tpoPOC.SetLineWeight(3);
tpoPOC.HideBubble();
tpoPOC.HideTitle();

### POC extensions

def y = if !IsNaN(pc) then pc else y[1];
plot vpocext = getvalue(y,barnumber()-bar_ext+1);
vpocext.SetDefaultColor(CreateColor(100, 0, 255));
vpocext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
vpocext.SetStyle(Curve.SHORT_DASH);
vpocext.HideBubble();
vpocext.HideTitle();

def x = if !IsNaN(tpoPC) then tpoPC else x[1];
plot tpoext = getvalue(x,barnumber()-bar_Ext+1);
tpoext.SetDefaultColor(CreateColor(100, 0, 255));
tpoext.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
tpoext.SetStyle(Curve.SHORT_DASH);
tpoext.HideBubble();
tpoext.HideTitle();
Whats tpoPOC, vpocext, tpoext???
 
Whats tpoPOC, vpocext, tpoext???
tpoPOC is the Time Price Opportunity (TPO) Point of Control (POC). For a given period, it's the price where the most time was spent. TPO Profile is also known as Market Profile.

vpoext is the line for the volume point of control extended into the next period, and tpoext is the line for the tpo point of control extended into the next period.
 
I'd like to ask a favor of any of you coders. Could someone please add an 'input' variable that would allow me to change the number of bars that this study uses through the 'Edit Studies' function of TOS?

Or, maybe point out what needs to be altered in the script.

Thank You for reading.
 
I'd like to ask a favor of any of you coders. Could someone please add an 'input' variable that would allow me to change the number of bars that this study uses through the 'Edit Studies' function of TOS?

Or, maybe point out what needs to be altered in the script.

Thank You for reading.
No, it is not possible to customize the "number of bars in this study.
 
Has Stephen Harlin shared code for the new Volume Profile. Apologies if the code is posted I just don't see it.

I am sure he does not share all indicators with the community.

leC1sm0.jpg
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
303 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

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

Frequently Asked Questions

What is useThinkScript?

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

How do I get started?

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

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

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