Market Profile study

Studies that have been contributed to the community by other users. If you’ve got something useful to share, that’s great!
server

Market Profile study

Postby server » 31 Oct 2006

Hi everyone,
I found another indicator which I believe can be quite useful, but unfortunately it doesn't work. The code compiles and verifies alright, but when applied to a chart nothing happens. I'm using the lates build (I think), 644.1126. Tried to change some parameters to "true", and still nothing. Here it is, in case someone would like to point me in the right direction.


code starts here:

-----------------------------------
{Indicator: gkMtkProfileTL

gkMtkProfileTL Histogram Plot

Poor Man's Market Profile and Value Area Indicator

This indicator plots a rough estimate of a volume histogram for a user specified
number of bars using Trendlines. The indicator approximates the volume
distribution within a bar by use of a sin or uniform distribution. This approximated
distribution is then accumulated over the user specified number of bars to form the histogram.

For intraday charts the user may specify a fixed length moving window for the histogram (e.g.,
the last hour's number of bars) or one that starts a 1 to 5 days prior and includes all the data
up through the current bar. A feature not yet implemented is same as the latter except that today's
data is not used.

The histogram uses color to identify two Value Zones based upon user specified area percentages (e.g.,
70% (Zone1) and 90% (Zone2)).


Inputs:
ProfileLength : number of bars to use for the profile (<= 2000)
HistoWindowType : 0: use a fixed length (ProfileLength) window that moves with each new bar, otherwise (v2.6)
1: histogram from 1st bar NbrDaysBack through current bar (uses todays data)
2: histogram from 1st bar NbrDaysBack through close of prior day (doesn't use todays data) ***NOT YET IMPLEMENTED***
NbrDaysBack : Number of days back to start the histogram (range: 1 to 5 days) (v2.6)
Zone1 and Zone2 : Value zone areas in percent (Must be between 0 and 100); Zone1 Prob < Zone2 Prob
Zone1Color : Color of 1st (Inter) Zone: 111111111111111
Zone2Color : Color of 2nd (Middle)Center Zone: 22222---------------22222
Zone3Color : Color of 3rd (Outer) Zone: 3333-------------------------33333
MedianColor : Color of Median Volume Histogram bar (set it the same as the Zone2Color if you don't want it)
HistoWidth : User specified histogram bar width, 0 = thinnest, 6 thickest
HistoStyle : User specified bar style, 1: solid, 2: dashed, 3: dotted, etc., max value: 5
DeltaPrice : Histogram bar resolution in (e.g., 0.05 means plot a histogram bar every 5 cents of price)
HistoBars : number of bars (time axis) used to plot volume histogram
SinDistVol : true = use a sin distribution for volume in a bar; false = use a uniform distribution


This indicator has only been tested on TS2000i.

v1, ghkramer, 12Sep04
v1.1 ghkramer, 14Oct04
added logic to prevent divide by zero when there's no range or volume
v2.0 ghkramer, 24 Oct04 Beta Test
Converted from Probability Map plot to Trendline plotting and added Value Area Colors
v2.1 ghkramer 30Jan05, Corrected bug in sin distribution calc: chged '*' to '/' in
calculation of dp; additionally, moved calc of dp outside of loop.
v2.2 ghkramer 31Jan05, changed histogram array dimension from '1:N' to '0:N'
v2.3 ghkramer 31Jan05, Test for case where all trades are at 1 price for bar (i.e., H = L)
v2.4 ghkramer 12Feb05, Replaced PriceRows input variable with dPrice; now compute NbrPriceRows
and increased Histo array size
v2.5 ghkramer 21Mar06, removed debug statements and cleaned-up code
v2.6 ghkramer 23Mar06, allowed user to fix start of histogram at NbrDaysBack
}



inputs: ProfileLength(51),
HistoWindowType(1), {v2.6}
NbrDaysBack(1), {v2.6}
Zone1(70), Zone2(90),
Zone1Color(Blue), Zone2Color(Red), Zone3Color(White), MedianColor(Yellow),
HistoWidth(0), {v2.5 User specified bar width}
HistoStyle(1), {v2.5 User specified bar style}
DeltaPrice(0.05), {v2.4 Replaced PriceRows input variable with DeltaPrice}
HistoBars(30), SinDistVol(true);

var: jBar(0), jCol(0), jPrice(0), jLow(0), jHigh(0), NbrPriceRows(0),
MinPrice(0), MaxPrice(0), HistoPrice(0), dPrice(0), dP2(0),
dVol(0), TotVol(0), dp(0), DisplayIntensity(0), MaxHisto(0),
vZone1(0), vZone2(0),
Prob1Upper(0), Prob2Upper(0), Prob2Lower(0), Prob1Lower(0), TailProb(0), CDF(0), CDF1(0),
Price1Upper(0), Price2Upper(0), Price2Lower(0), Price1Lower(0), MedianHisto(0),
iHistoWidth(0), iHistoStyle(0),
NotYetFound1Up(false), NotYetFound2Up(false), NotYetFound2Lo(false), NotYetFound1Lo(false),
BeginDate(0), BeginTime(0), BeginVal(0), EndDate(0), EndTime(0), EndVal(0),
jDate(0), TLRef(0), j(0), Temp(0), yPrice(0),
MaxPriceRows(1000), {v2.4 Must be = dim(Histo[]) - 1}
FirstTimeThru(true), NbrTLs(0), iTL(0),
nDaysBack(0), xProfileLength(0), {v2.6}
BarsPerSession(0), BarsToday(0), MinutesPerSession(0), MinutesToday(0); {v2.6}

array: Dates[2000](0), Times[2000](0);
array: Histo[2001](0); {Dim must be >= MaxPriceRows+1} {v2.4, increased array size}
array: iTLRef[2000](0);



{========Initialization=========}
if (CurrentBar = 1) then
begin
{Constrain inputs}
if (Zone1 < 1) then
vZone1 = 1
else if (Zone1 > 99) then
vZone1 = 99
else
vZOne1 = Zone1;

if (Zone2 < 1) then
vZone1 = 1
else if (Zone2 > 99) then
vZone2 = 99
else
vZOne2 = Zone2;

if (vZone1 > vZone2) then
begin
Temp = vZone1;
vZone1 = vZone2;
vZone2 = Temp;
end;

iHistoWidth = HistoWidth;
if (HistoWidth < 0) then
iHistoWidth = 0
else if (HistoWidth > 6) then
iHistoWidth = 6;

iHistoStyle = HistoStyle;
if (HistoStyle < 1) then
iHistoStyle = 1
else if (HistoStyle > 5) then
iHistoStyle = 5;

if (HistoWindowType = 0) then {v2.6}
begin
xProfileLength = ProfileLength;
end
else
begin
{if (DataCompression < 2) then {TS2000i}}
if (BarType < 2) then {TS8}
begin
MinutesPerSession = TimeToMinutes(Sess1EndTime) - TimeToMinutes(Sess1StartTime);
BarsPerSession = round(MinutesPerSession/BarInterval, 0);
xProfileLength = BarsPerSession*nDaysBack;
end;

if (NbrDaysBack < 1) then
nDaysBack = 1
else if (NbrDaysBack > 5) then
nDaysBack = 5
else
nDaysBack = NbrDaysBack;
end;


{calc histogram probability levels for Value areas:
Zone1: Prob1Upper and Prob1Lower
Zone2: Prob2Upper and Prob2Lower }
TailProb = (100-vZone1)/200;
Prob1Upper = 1 - TailProb; {TailProb;}
Prob1Lower = TailProb; {1 - TailProb;}
TailProb = (100-vZone2)/200;
Prob2Upper = 1 - TailProb; {TailProb;}
Prob2Lower = TailProb; {1 - TailProb;}
end;


{==========Main: Compute Histogram and plot=========}
if (HistoBars > 0) then
begin
{--------Calculate Histogram parameters---------}
if (CurrentBar >= xProfileLength) then
begin
{if (DataCompression < 2) then} {TS2000i}
if (BarType < 2) then {TS8}
begin
if (HistoWindowType = 1) then {histogram from 1st bar NbrDaysBack through current bar}
begin
MinutesToday = TimeToMinutes(Time) - TimeToMinutes(Sess1StartTime);
BarsToDay = round(MinutesToday/BarInterval, 0);
xProfileLength = BarsToDay + BarsPerSession*nDaysBack;
end;
end;

{Find Price limits}
MinPrice = Lowest(L, xProfileLength);
MaxPrice = Highest(H, xProfileLength);
if (DeltaPrice <= 0) then {v2.4 Change}
begin
NbrPriceRows = 100;
dPrice = (MaxPrice - MinPrice)/NbrPriceRows;
end
else {user specified DeltaPrice}
begin
NbrPriceRows = floor((MaxPrice - MinPrice)/DeltaPrice) + 1;
if (NbrPriceRows < 1) then {s/b >= 1, but test anyway to prevent divide by 0}
NbrPriceRows = 1;
if (NbrPriceRows <= MaxPriceRows) then
dPrice = DeltaPrice
else {constrain NbrPriceRows to array limits}
begin
NbrPriceRows = MaxPriceRows;
dPrice = (MaxPrice - MinPrice)/NbrPriceRows;
end;
end;
dP2 = dPrice/2;

{-------Initialize Histogram Cells--------}
for jPrice = 0 to NbrPriceRows
begin
Histo[jPrice] = 0;
end;
{dPrice must be > 0, otherwise exit without Plotting v1.1 fix}
if (dPrice > 0) then
begin
{-------Compute Histogram---------}
TotVol = 0;
for jBar = 0 to (xProfileLength-1)
begin
jLow = floor((L[jBar] - MinPrice)/dPrice); {31Jan05, removed +1 , v2.2 fix}
jHigh = floor((H[jBar] - MinPrice)/dPrice); {31Jan05, removed +1 , v2.2 fix}
if ((jHigh - jLow) > 0) then {31Jan05, case where all trades at 1 price, v2.3}
begin
if (SinDistVol) then {use Sin on a pedestal distributed volume}
begin
dp = 180/(jHigh - jLow); {30Jan05,chged * to /, moved out of loop, v2.1}
for jPrice = jLow to jHigh
begin
{scale by area of sin pedestal = 1/2.785}
dVol = 0.35991*V[jBar]*(sine((jPrice-jLow)*dp) + 0.25);
TotVol = TotVol + dVol;
Histo[jPrice] = Histo[jPrice] + dVol;
end;
end
else {use Uniformly distributed volume}
begin
dVol = V[jBar]/(jHigh - jLow); {31Jan05, removed +1 , v2.2 fix}
for jPrice = jLow to jHigh
begin
Histo[jPrice] = Histo[jPrice] + dVol;
TotVol = TotVol + dVol;
end;
end;
end
else {jHigh = jLow for this bar, no need to distribute}
Histo[jLow] = Histo[jLow] + V[jBar];
end; {for jBar}


{==========Plot Histogram================}

{Volume must be > 0, otherwise, exit without plotting v1.1 fix}
if (TotVol > 0) then
begin
{--------Normalize Histogram---------}
MaxHisto = -100000;
for jPrice = 0 to NbrPriceRows
begin
Histo[jPrice] = Histo[jPrice]/TotVol;
if (Histo[jPrice] > MaxHisto) then
MaxHisto = Histo[jPrice];
end;

{---------Plot Profile using trendlines v2.0 fix-----------}
if LastBarOnChart then
begin
{Find price levels that correspond to Value Area percentages}
CDF = 0; CDF1 = 0;
HistoPrice = MinPrice;
NotYetFound1Up = true;
NotYetFound2Up = true;
NotYetFound2Lo = true;
NotYetFound1Lo = true;
for jPrice = 0 to NbrPriceRows {fix v2.2}
begin
CDF = CDF + Histo[jPrice];
if ((CDF >= Prob1Lower) and NotYetFound1Lo) then
begin
Price1Lower = HistoPrice;
NotYetFound1Lo = false;
end;
if ((CDF >= Prob2Lower) and NotYetFound2Lo) then
begin
Price2Lower = HistoPrice;
NotYetFound2Lo = false;
end;
if ((CDF >= Prob2Upper) and NotYetFound2Up) then
begin
Price2Upper = HistoPrice;
NotYetFound2Up = false;
end;
if ((CDF >= Prob1Upper) and NotYetFound1Up) then
begin
Price1Upper = HistoPrice;
NotYetFound1Up = false;
end;
if ((CDF >= 0.5) and (CDF1 < 0.5)) then
MedianHisto = HistoPrice;
CDF1 = CDF;
HistoPrice = HistoPrice + dPrice;
end;

{---------Scale Histogram-----------}
for jPrice = 0 to NbrPriceRows
begin
Histo[jPrice] = round(HistoBars*Histo[jPrice]/MaxHisto, 0);
end;

{set Date/Times}
BeginDate = Date[HistoBars];
BeginTime = Time[HistoBars];
for j = 0 to NbrPriceRows {fix v2.2}
begin
Dates[j] = Date[HistoBars - Histo[j]];
Times[j] = Time[HistoBars - Histo[j]];
end;

{Delete prior set of TLs}
if ((FirstTimeThru = false) and (NbrTLs > 0)) then
begin
for iTL = 1 to NbrTLs
begin
TL_Delete(iTLRef[iTL]);
end;
end;

{--------Plot Market Profile-----------}
for j = 0 to NbrPriceRows {fix v2.2}
begin
yPrice = MinPrice + j*dPrice;
BeginVal = yPrice;
EndDate = Dates[j];
EndTime = Times[j];
EndVal = yPrice;

if ((BeginDate <> EndDate) or (BeginTime <> EndTime)) then
begin
{plot histogram as trendline}
TLRef = TL_New(BeginDate, BeginTime, yPrice, EndDate, EndTime, yPrice) ;

{Save TLRef}
NbrTLs = NbrTLs + 1;
iTLRef[NbrTLs] = TLRef;

TL_SetSize(TLRef, iHistoWidth) ;
TL_SetStyle(TLRef, iHistoStyle) ;

{set zone colors}
if (yPrice < Price2Lower) then
TL_SetColor(TLRef, Zone3Color)
else if (yPrice < Price1Lower) then
TL_SetColor(TLRef, Zone1Color)
else if (yPrice < Price1Upper) then
TL_SetColor(TLRef, Zone2Color)
else if (yPrice < Price2Upper) then
TL_SetColor(TLRef, Zone1Color)
else
TL_SetColor(TLRef, Zone3Color);

{plot median volume}
if ((yPrice > (MedianHisto-dP2)) and (yPrice < (MedianHisto+dP2))) then
TL_SetColor(TLRef, MedianColor);
end; {if BeginDate...}
end; {for j}
FirstTimeThru = false;
end; {LastBarOnChart}
end; {TotVol > 0}
end; {dPrive > 0}
end; {CurrentBar >= xProfileLength}
end; {(HistoBars > 0) v1.1 fix}



--------------------------------------------------
code ends here
Thanks in advance!

User avatar
Alex Kramer
Posts: 834
Joined: 23 Feb 2006

Postby Alex Kramer » 31 Oct 2006

I compiled this code and applied it to a chart, the indicator shows up something like volume histograms, looks really nice (see screenshot).
Maybe you were just not applying it to suitable data?
Attachments
colors.png
colors.png (34.09 KiB) Viewed 938 times

SP
Posts: 444
Joined: 06 Feb 2006
Has thanked: 36 times
Been thanked: 280 times

Postby SP » 31 Oct 2006

@server

You have to asure that the underlying/symbol has a "Session End" mark at Quote Manager --> Sessions.

Otherwise you have to adjust the lines

MinutesPerSession = TimeToMinutes(Sess1EndTime) - TimeToMinutes(Sess1StartTime);

and
MinutesToday = TimeToMinutes(Time) - TimeToMinutes(Sess1StartTime);

with the correct underlying time settings.


Also it could be useful to change the input Deltaprice(0.05) to DeltaPrice(MinMove / PriceScale ).

SP
Posts: 444
Joined: 06 Feb 2006
Has thanked: 36 times
Been thanked: 280 times

Postby SP » 03 Nov 2006

....
Last edited by SP on 06 Nov 2006, edited 1 time in total.

server
Posts: 3
Joined: 04 Nov 2006

Postby server » 04 Nov 2006

Got it. Changing the symbol time zone from "local" to "exchange" did the trick.
Thanks again, guys!

server
Posts: 3
Joined: 04 Nov 2006

Postby server » 04 Nov 2006

SP, thank you very much for your help, I really appreciate it.

server
Posts: 3
Joined: 04 Nov 2006

Postby server » 04 Nov 2006

SP, thank you very much for your help, I really appreciate it.


Return to “User Contributed Studies and Indicator Library”