Thomas DeMark Pivot Lines

 
Hi,

After checking out all the attempts to write this code in the forum, I decided to do it myself. thanks for all the help from previous posts.

Here is the code to insert the Pivot, S1/R1 & S2/R2. Any comments or improvements welcomed.

Des

//+------------------------------------------------------------------+
//| DialyPivot.mq4 |
//| These are the main pivots used by Thomas DeMark |
//| Written by: Ice |
//| |
//+------------------------------------------------------------------+
#property copyright "2005 Free software for trader"

#property indicator_chart_window
#property indicator_buffers 7

#property indicator_color1 Blue
#property indicator_color2 Yellow
#property indicator_color3 Red
#property indicator_color4 Green
#property indicator_color5 Lime

//---- input parameters\

datetime BT[];
double YesterdayHigh[50];
double YesterdayLow[50];
double YesterdayClose[50];
//---- buffers

double PivotArray[];
double R1Array[];
double S1Array[];
double R2Array[];
double S2Array[];
double R3Array[];
double S3Array[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
// Pivot
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,PivotArray);
IndicatorShortName("TDPivot");
SetIndexLabel(0,"Pivot");

// Resistance 1
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,R1Array);
SetIndexLabel(1,"R1");

// Support 1
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,S1Array);
SetIndexLabel(2,"R1");

// Resistance 2
SetIndexStyle(3,DRAW_LINE);
SetIndexBuffer(3,R2Array);
SetIndexLabel(3,"R2");

// Support 2
SetIndexStyle(4,DRAW_LINE);
SetIndexBuffer(4,S2Array);
SetIndexLabel(4,"S2");


return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();

ArrayResize(BT, Bars); Print("Bars = " + Bars);
// Fill BT with bar open TIME
ArrayCopySeries(BT, MODE_TIME);
// Fill temp arrays with High, Low and Close prices per day
ArrayCopySeries(YesterdayHigh, MODE_HIGH, Symbol(), PERIOD_D1);
ArrayCopySeries(YesterdayLow, MODE_LOW, Symbol(), PERIOD_D1);
ArrayCopySeries(YesterdayClose, MODE_CLOSE, Symbol(), PERIOD_D1);

int od = 0;
int dd = 0;


double Pivot;
double R1;
double S1;
double R2;
double S2;

//Cycle through all the bars and fill the indicator bars with the Pivot point values
for (int i = 0; i <= Bars; i++) {
if (TimeDay(BT[i]) != od) {
dd++;
Pivot = (YesterdayHigh[dd] + YesterdayLow[dd] + YesterdayClose[dd])/3;
R1 = (2*Pivot)-YesterdayLow[dd];
S1 = (2*Pivot)-YesterdayHigh[dd];
R2 = Pivot-S1+R1;
S2 = Pivot-R1+S1;
od = TimeDay(BT[i]);
}

PivotArray[i] = Pivot;
R1Array[i]=R1;
S1Array[i]=S1;
R2Array[i]=R2;
S2Array[i]=S2;
}
//----
return(0);
}
//+------------------------------------------------------------------+
 
Update....

Removed the following line to avoid error "Cannot resize array" & print messages.

int start()
{
int counted_bars=IndicatorCounted();

ArrayResize(BT, Bars); Print("Bars = " + Bars);

Des
 
Hi Desiderius!!

This is exactly what I was looking for and just like you wanted to program it. I sort of got stuck... Just beginning.

You've done a great job!

There are a number of pivot calculator indicators programmed already,
but they draw the lines only for the current day based on the previous
day data. the position of these lines changes everyday and you can't
know the pivot values for previous days.

I am interested to see on the day to day historical value of the
pivots and how relevant they are to the currency pair or in function
of the time they were calculated at (00 GMT, NY close...). What's the time start for the calculation of the data? Is it the "chart day"? Mine is at GMT +2... how can we change that to 00 GMT or say the NY close time? Time could be a user selectable parameter...


I am no match to you as far as programing is concerned. Just some humble suggestions:

Could be nice to insert a comment line to give today's calculated pivots:

Comment("Today Pivots","\nR2=",R2,"\nR1=",R1,"\nP=",Pivot,"\nS1=",S1,"\nS2=",S2,);


Very minor copy/paste typo...
// Support 1
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,S1Array);
SetIndexLabel(2,"R1"); // Modify to "S1"

Cool Work!!
 
Domino

Coll thanks. Yeah, I realised that the time is based on the server time and I am looking for a way to chage it. There have been a number of requests to make the time client based and thus provide an offset, but no luck from the guys.

This is always going to throw indicators off as long as the server time is used. Yet again a request to change this please!

Thanks for the typo find. Saw that after I posted. Adding comments is cool, and I'll look at it at the same time as the timezone.

Des
 
Yeas Des,

It would be great to have a time adjustment at least in the indicator.

I'll be looking around for it and let you know!
 
Hello;

How would I change this code so that it plots Weekly pivots rather than daily pivots ??

TIA !!
 
Change the following

// Fill temp arrays with High, Low and Close prices per day
ArrayCopySeries(YesterdayHigh, MODE_HIGH, Symbol(), PERIOD_W1);
ArrayCopySeries(YesterdayLow, MODE_LOW, Symbol(), PERIOD_W1);
ArrayCopySeries(YesterdayClose, MODE_CLOSE, Symbol(), PERIOD_W1);

I have not tested this, so try it out.

Des
 
Des;

It did not work ..

Instead of drawing horizontal pivot lines, it drew a bunch of curves ..

Any correction would be appreciated ..

TIA !!
 
Hi Des!

Any chance with solving the time zone issue?

Othyerwise, I think the only way will be to go around the standard "ArrayCopySeries(YesterdayClose, MODE_CLOSE, Symbol(), PERIOD_D1);" function and write a routine that will do the bar counting, the high low determination by comparing and storing in a buffer. One of the external inputs of the indicator will be the time offset that the user will have to specify. I'll see if I can get around to doing that this weekend...

Below is the only indicator I have seen so far where there is a "manual" search of the daily open to integrate the right timezone. This is the indicator written by David Thomas for a popular trading system on Moneytec: the Bunny Cross. The elements in bold refer to the bar counting and daily open determination with timezone correction:
//+------------------------------------------------------------------+
//| Bunnygirl Cross and Daily Open.mq4 |
//| Copyright © 2005, David W. Thomas |
//| mailto:davidwt@usa.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, David W. Thomas"
#property link "mailto:davidwt@usa.net"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 DarkViolet
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Gray

//---- input parameters
extern int PipsForBounce=3;
extern int TimeZoneOfData=2;
extern int ma_method=MODE_LWMA;

//---- buffers
double DailyOpenBuffer[];
double BuyFilterBuffer[];
double SellFilterBuffer[];
double CrossBounceBuffer[];

//---- variables
int indexbegin = 0;
string mastrtype = "";
double dailyopen = 0,
crossamount,
filter = 0;
int crosstime = 0;
bool crossdir = true;
bool FilterTradingTime = true;
int beginfiltertime = 0;
int endfiltertime = 24;

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0, DRAW_LINE);
SetIndexBuffer(0, DailyOpenBuffer);
SetIndexLabel(0, "Daily Open");
SetIndexEmptyValue(0, 0.0);
SetIndexStyle(1, DRAW_LINE);
SetIndexBuffer(1, BuyFilterBuffer);
SetIndexLabel(1, "Buy Filter");
SetIndexEmptyValue(1, 0.0);
SetIndexStyle(2, DRAW_LINE);
SetIndexBuffer(2, SellFilterBuffer);
SetIndexLabel(2, "Sell Filter");
SetIndexEmptyValue(2, 0.0);
SetIndexStyle(3, DRAW_LINE, STYLE_DOT);
SetIndexBuffer(3, CrossBounceBuffer);
SetIndexLabel(3, "Cross/Bounce");
SetIndexEmptyValue(3, 0.0);
//----
indexbegin = Bars - 20;
if (indexbegin < 0)
indexbegin = 0;

if (Symbol() == "EURUSD")
filter = 20 * Point + Bid;
else
filter = 25 * Point + Bid;
if (ma_method == MODE_EMA)
mastrtype = "EMA";
else
mastrtype = "WMA";
if (FilterTradingTime)
{
beginfiltertime = 6 + TimeZoneOfData;
endfiltertime = 17 + TimeZoneOfData;
}
else
{
beginfiltertime = 0;
endfiltertime = 24;
}

return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//---- TODO: add your code here

//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int i;
int counted_bars = IndicatorCounted();
string crossdirstr = "";

//---- check for possible errors
if (counted_bars < 0) counted_bars = 0;
//---- last counted bar will be recounted
if (counted_bars > 0) counted_bars--;
if (counted_bars > indexbegin) counted_bars = indexbegin;

if (Period() == 30)

{
double ma20c, ma20p1, ma20p2,
diff0, diff1, diff2;

for (i = indexbegin-counted_bars; i >= 0; i--)
{
if ((TimeMinute(Time[i]) == 0) && (TimeHour(Time[i]) - TimeZoneOfData == 0))
dailyopen = Open[i];
DailyOpenBuffer[i] = dailyopen;


ma20c = iMA(NULL, PERIOD_M30, 20, 0, ma_method, PRICE_CLOSE, i);
ma20p1 = iMA(NULL, PERIOD_M30, 20, 0, ma_method, PRICE_CLOSE, i+1);
ma20p2 = iMA(NULL, PERIOD_M30, 20, 0, ma_method, PRICE_CLOSE, i+2);
diff0 = iMA(NULL, PERIOD_M30, 5, 0, ma_method, PRICE_CLOSE, i) - ma20c;
diff1 = iMA(NULL, PERIOD_M30, 5, 0, ma_method, PRICE_CLOSE, i+1) - ma20p1;
diff2 = iMA(NULL, PERIOD_M30, 5, 0, ma_method, PRICE_CLOSE, i+2) - ma20p2;

// bull signals:
if (diff0 > 0)
{
if (diff1 < 0) // simple bull cross.
{
crossdir = true;
// determine which bar is closer to the cross:
if (MathAbs(diff0) < MathAbs(diff1))
{
crosstime = Time[i];
crossamount = ma20c;
}
else
{
crosstime = Time[i+1];
crossamount = ma20p1;
}
}
else
if (diff1 == 0 && diff2 < 0) // exact cross on last bar.
{
crossdir = true;
crosstime = Time[i+1];
crossamount = ma20p1;
}
else
if (diff1 > 0 && diff2 > diff1 && diff0 >= diff1 && diff1 <= PipsForBounce*Point) // a bounce.
{
crossdir = true;
crosstime = Time[i+1];
crossamount = ma20p1;
}
}
else
// bear signals:
if (diff0 < 0)
{
if (diff1 > 0) // simple bear cross.
{
crossdir = false;
// determine which bar is closer to the cross:
if (MathAbs(diff0) < MathAbs(diff1))
{
crosstime = Time[i];
crossamount = ma20c;
}
else
crosstime = Time[i+1];
crossamount = ma20p1;
{
}
}
else
if (diff1 == 0 && diff2 > 0) // exact cross on last bar.
{
crossdir = false;
crosstime = Time[i+1];
crossamount = ma20p1;
}
else
if (diff1 < 0 && diff2 < diff1 && diff0 <= diff1 && MathAbs(diff1) <= PipsForBounce*Point) // a bounce.
{
crossdir = false;
crosstime = Time[i+1];
crossamount = ma20p1;
}
}
CrossBounceBuffer[i] = crossamount;
if (TimeHour(Time[i]) >= beginfiltertime && TimeHour(Time[i]) <= endfiltertime)
{
if (crossdir)
{
BuyFilterBuffer[i] = crossamount + filter + Ask - Bid;
SellFilterBuffer[i] = 0;
}
else
{
SellFilterBuffer[i] = crossamount - filter;
BuyFilterBuffer[i] = 0;
}
}
if (crosstime == Time[i+1] && TimeHour(Time[i+1]) >= beginfiltertime && TimeHour(Time[i+1]) <= endfiltertime)
{
CrossBounceBuffer[i+1] = crossamount;
if (crossdir)
BuyFilterBuffer[i+1] = crossamount + filter + Ask - Bid;
else
SellFilterBuffer[i+1] = crossamount - filter;
}
}
}
else
if (Period() < 30)
{
int per30 = 30 / Period();
int j;
for (i = indexbegin-counted_bars; i >= 0; i--)
{
j = (i + per30 - 1)/per30;
dailyopen = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 0, j);
DailyOpenBuffer[i] = dailyopen;
crossamount = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 3, j);
CrossBounceBuffer[i] = crossamount;
if (CrossBounceBuffer[i+1] != crossamount)
crosstime = Time[i];
BuyFilterBuffer[i] = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 1, j);
SellFilterBuffer[i] = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 2, j);
}
crossdir = BuyFilterBuffer[0] != 0.0;
}
else
{
dailyopen = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 0, 0);
crossamount = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 3, 0);
BuyFilterBuffer[0] = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 1, 0);
SellFilterBuffer[0] = iCustom(NULL, PERIOD_M30, "Bunnygirl Cross and Daily Open",
PipsForBounce, TimeZoneOfData, ma_method, 2, 0);
crossdir = BuyFilterBuffer[0] != 0.0;
}

if (crossdir)
crossdirstr = "bull";
else
crossdirstr = "bear";

if (crosstime != 0)
Comment("Current daily open = ", dailyopen, "\nLast ", mastrtype, " cross/bounce: ", TimeToStr(crosstime), ", ", crossdirstr, " at ", crossamount);
else
Comment("Current daily open = ", dailyopen, "\nLast ", mastrtype, " cross/bounce: ", crossdirstr, " at ", crossamount);

return(0);
}
//+------------------------------------------------------------------+
Reason: