//+------------------------------------------------------------------+
//| PAMA GannGrid_indv4.3.mq4 |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright � 2010.01.24, SwingMan"
#property link ""
/*+------------------------------------------------------------------+
v 4.1 draw trading lines
v 4.3 text shift for values
//+-----------------------------------------------------------------*/
string sIndicatorName = "PAMA GannGrid_indv4.3";
//---- window
bool Draw_InMainWindow = true; //set this parameter!
//#property indicator_separate_window
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 DodgerBlue //price line
#property indicator_color2 DodgerBlue //price dots
#property indicator_color3 Silver //max,min; identical with MainGrid_Color
#property indicator_color4 Silver
#property indicator_color5 Green //up arrow
#property indicator_color6 Green //up line
#property indicator_color7 Red //dn arrow
#property indicator_color8 Red //dn line
#property indicator_width1 1 //price line
#property indicator_width2 1 //price dots
#property indicator_width3 1 //max,min; identical with MainGrid_Color
#property indicator_width4 1 //
#property indicator_width5 2 //up arrow
#property indicator_width6 2 //up line
#property indicator_width7 2 //dn arrow
#property indicator_width8 2 //dn line
#property indicator_style3 STYLE_SOLID
#property indicator_style4 STYLE_SOLID
//---- extern inputs
//+------------------------------------------------------------------+
extern string ____GridBegin____ = "";
extern bool UseBeginDate = false;
//extern string BeginDate = "2010.01.21";
//extern string BeginDate = "2009.11.01";
extern string BeginDate = "2010.01.01 00:00";
extern int nBarsBack = 120;//250;
extern string prices = "0=close, 4=median, 5=typical";
extern int Price_Mode = 5;
//-- oscillator (Draw_InMainWindow = false)
//extern bool Show_GridMatrix = true;
//extern bool Show_GannGrid = true;
//-- indicator (Draw_InMainWindow = true)
extern bool Show_GridMatrix = false;
extern bool Show_GannGrid = false;
extern bool Show_HiloArrows = true;
extern bool Show_PriceArrows = false;
extern bool Show_Comments = false;
extern string ____MainGrid____ = "";
extern color MainGrid_Color = Silver;//Green;//Sienna;
extern int MainGrid_Style = STYLE_DOT;
extern int MinMaxGrid_Style = STYLE_SOLID;
extern int MainGrid_Width = 1;
extern int fontSize = 8;
extern bool Draw_AllGrids = false;
extern bool Draw_AdditionalGrids = false;
extern string ____GannGrid____ = "";
extern color GannGrid_Color = Silver;//Gray;
//---- if (Draw_InMainWindow == true)
extern int GannGrid_Style = STYLE_DOT;
//---- if (Draw_InMainWindow == false)
//extern int GannGrid_Style = STYLE_SOLID;
extern int GannGrid_Width = 1;
extern string ____Default_GridParameters____ = "Recomanded GridInterval 35 or 36";
extern int MainGrid_Intervals = 36; //default=35(!)
extern double GannGrid_Interval = 8.0;//with default 8.5 is the time interval not OK; and 9 is too large
extern int Text_Shift = 50;
//+------------------------------------------------------------------+
//---- default input parameters
//string ____DefaultGridInterval____ = "";
//int MainGrid_Intervals = 36; //default=35(!)
//double GannGrid_Interval = 8.0;//with default 8.5 is the time interval not OK; and 9 is too large
//---- buffers
double price[], dotPrice[];
double MaxPriceLine[], MinPriceLine[];
double upArrow[], upLine[], dnArrow[], dnLine[];
//---- variables
int iWindow;
string sWindowName;
datetime firstTime, thisTime, oldTime;
bool bGridOK = false;
int nMainGrid_Intervals;
int iGannGrid_Interval, iHalfInterval;
datetime maxPriceTime, minPriceTime;
double maxPrice, minPrice, gridStep;
bool UseBeginDateOriginal;
int nDigits;
//####################################################################
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexBuffer(0,price); SetIndexStyle(0,DRAW_LINE);
SetIndexLabel(0,"PAMA Price");
SetIndexBuffer(1,dotPrice); SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,159);
SetIndexLabel(1,NULL);
SetIndexBuffer(2,MaxPriceLine); SetIndexStyle(2,DRAW_LINE,MinMaxGrid_Style,MainGrid_Width,MainGrid_Color);
SetIndexLabel(2,"maxPrice");
SetIndexBuffer(3,MinPriceLine); SetIndexStyle(3,DRAW_LINE,MinMaxGrid_Style,MainGrid_Width,MainGrid_Color);
SetIndexLabel(3,"minPrice");
SetIndexBuffer(4,upArrow); SetIndexStyle(4,DRAW_ARROW); SetIndexArrow(4,241);
SetIndexLabel(4,NULL);
SetIndexBuffer(5,upLine); SetIndexStyle(5,DRAW_LINE);
SetIndexLabel(5,"upLine");
SetIndexBuffer(6,dnArrow); SetIndexStyle(6,DRAW_ARROW); SetIndexArrow(6,242);
SetIndexLabel(6,NULL);
SetIndexBuffer(7,dnLine); SetIndexStyle(7,DRAW_LINE);
SetIndexLabel(7,"dnLine");
//----
SetIndexEmptyValue(7,EMPTY_VALUE);
//----
string sName = sIndicatorName + " ";
if (Price_Mode == 0) string sPrice = "(ClosePrices) "; else
if (Price_Mode == 4) sPrice = "(MedianPrices) "; else
if (Price_Mode == 5) sPrice = "(TypicalPrices) ";
sWindowName = sName+sPrice;
IndicatorShortName(sWindowName);
IndicatorDigits(Digits);
//---- initialisations
if (UseBeginDate == true)
{
firstTime = StrToTime(BeginDate + " 00:00");
nBarsBack = 0;
}
else
firstTime = 0;
nMainGrid_Intervals = MainGrid_Intervals;
iGannGrid_Interval = GannGrid_Interval;
iHalfInterval = iGannGrid_Interval / 2;
UseBeginDateOriginal = UseBeginDate;
bGridOK = false;
nDigits = MarketInfo(Symbol(),MODE_DIGITS);
if (nDigits == 5 || nDigits == 3) nDigits--;
//---- window
if (Draw_InMainWindow)
iWindow = 0;
else iWindow = WindowFind(sWindowName);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
Delete_GannObjects();
if (Show_Comments) Comment("");
for (int i=0; i<nBarsBack+20; i++)
{
upArrow[i] = EMPTY_VALUE;
dnArrow[i] = EMPTY_VALUE;
upLine[i] = EMPTY_VALUE;
dnLine[i] = EMPTY_VALUE;
MaxPriceLine[i] = EMPTY_VALUE;
MinPriceLine[i] = EMPTY_VALUE;
}
//----
return(0);
}
//####################################################################
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//datetime testTime1=TimeCurrent();
double dPrice;
if (Draw_InMainWindow==false)
if (iWindow < 1) iWindow = WindowFind(sWindowName);
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
int limit = Bars-counted_bars;
//---- check newBar
thisTime = Time[0];
if (thisTime != oldTime)
{
oldTime = thisTime;
Delete_GannObjects();
if ( (UseBeginDate == false && firstTime != 0) || //-- nBarsBack after first calculation
(UseBeginDate == true && limit < 4) ) //-- Date after first calculation
{
nBarsBack = 0;
bGridOK = false;
UseBeginDate = true; //firstTime is now allowable for nBarsBack
int thisBarShift = iBarShift(Symbol(),Period(),firstTime,false);
limit = thisBarShift;
}
}
//---- first min,max prices
if (bGridOK == false)
{
dPrice = CurrentPrice(Price_Mode, 0);
maxPrice = dPrice; maxPriceTime = Time[0];
minPrice = dPrice; minPriceTime = Time[0];
}
//---- draw prices, caculate min,max prices
//================================================================
for(int i=0; i<limit; i++)
{
dPrice = CurrentPrice(Price_Mode, i);
price[i] = dPrice;
dotPrice[i] = dPrice;
if (bGridOK == false)
{
//---- use fix date as begin
if (UseBeginDate == true)
{
if (Time[i] > firstTime)
{
if (dPrice > maxPrice) {maxPrice = dPrice; maxPriceTime = Time[i];}
if (dPrice < minPrice) {minPrice = dPrice; minPriceTime = Time[i];}
nBarsBack++;
}
}
else
//---- use nBarsBack as begin
if (UseBeginDate == false)
{
if (i < nBarsBack)
{
if (dPrice > maxPrice) {maxPrice = dPrice; maxPriceTime = Time[i];}
if (dPrice < minPrice) {minPrice = dPrice; minPriceTime = Time[i];}
firstTime = Time[i];
}
}
}
}
//---- calculate data for MainGrid
if (bGridOK == false)
{
double diffMinMax = maxPrice - minPrice;
gridStep = NormalizeDouble(diffMinMax / nMainGrid_Intervals,Digits);
}
//---- dummy lines for uper and lower prices
for(i=0; i<limit; i++)
{
MaxPriceLine[i] = maxPrice;// + iHalfInterval *gridStep;
MinPriceLine[i] = minPrice;// - iHalfInterval *gridStep;
Write_PriceValue(maxPrice);
Write_PriceValue(minPrice);
}
//-- adjust nBarsBack
if (UseBeginDate == true)
nBarsBack++;
//---- draw matrix and GannGrid
//===================================================================
if (bGridOK == false)
{
//---- write matrix data
string st;
st = st + "** " + sIndicatorName + " ** " + "\n";
if (UseBeginDateOriginal) string sBegin = " (Date)"; else sBegin = " (nBars)";
st = st + "GridBegin: " + TimeToStr(firstTime,TIME_DATE|TIME_MINUTES) + sBegin + "\n";
st = st + "nBarsBack= " + nBarsBack + "\n";
string sMaxPriceTime = " (" + TimeToStr(maxPriceTime) + ")";
string sMinPriceTime = " (" + TimeToStr(minPriceTime) + ")";
st = st + "maxPrice= " + DoubleToStr(maxPrice,Digits) + sMaxPriceTime + "\n";
st = st + "minPrice= " + DoubleToStr(minPrice,Digits) + sMinPriceTime + "\n";
double percent = 100.0 *( maxPrice - minPrice) / minPrice;
double gridPerc= percent / nMainGrid_Intervals;
string sGridPercent = " ( " + DoubleToStr(gridPerc,2) + " % )";
st = st + "Percent= " + DoubleToStr(percent,2) + " %\n";
st = st + "GridStep= " + DoubleToStr(gridStep,Digits) + sGridPercent + "\n";
string sGridStep = " (" + iHalfInterval + " GridSteps)";
st = st + "mainStep= " + DoubleToStr(gridStep*iHalfInterval,Digits) + sGridStep + "\n";
if (Show_Comments)
Comment(st);
//---- draw horizontal lines (35+1=36 HLines) ----------------------
if (MainGrid_Intervals == 36)
int nMainGrids = nMainGrid_Intervals;
else nMainGrids = nMainGrid_Intervals+1; //nMainGrid_Intervals+1 for 35
if (Show_GridMatrix == true)
for (i=1; i<nMainGrids; i++)
{
if (Draw_AllGrids == true)
Draw_HorizontalLine(maxPrice - i*gridStep);
else
{
if (MathMod(i,iHalfInterval) == 0)
Draw_HorizontalLine(maxPrice - i*gridStep);
}
//---- write price values
if (MathMod(i,iHalfInterval) == 0)
Write_PriceValue(maxPrice - i*gridStep);
}
//-- additional grids
if (Show_GridMatrix == true)
if (Draw_AdditionalGrids)
{
for (int k=1; k<=iHalfInterval; k++)
Draw_HorizontalLine(maxPrice+k*gridStep);
for (k=1; k<=iHalfInterval; k++) //k=2 for 35
Draw_HorizontalLine(minPrice-k*gridStep);
}
//---- draw vertical lines ------------------------------------------
if (Show_GridMatrix == true)
for (i=0; i<nBarsBack; i++)
{
if (Draw_AllGrids == true)
int j = i;
else
j = (nBarsBack-1) - i * iHalfInterval;
if (j>0)
datetime dTime = Time[j];
else
dTime = Time[0];
Draw_VerticalLine(dTime,minPrice,maxPrice);//minPrice-gridStep for 35
}
//---- draw trading lines -------------------------------------------
Draw_TradingLines();
//==== draw GannGrid lines (angle 45�) ==============================
if (Show_GannGrid)
{
datetime time1 = Time[nBarsBack-1];
datetime time2 = Time[nBarsBack-iHalfInterval-1];
double price1 = maxPrice;
double price2 = maxPrice - iHalfInterval*gridStep;
Draw_GannGrid(time1,time2, price1,price2);
}
}
//----
bGridOK = true;
//datetime testTime2=TimeCurrent();
//if (Symbol() == "EURUSD" && Period() == PERIOD_M5)
// Print("### ",TimeToStr(testTime2 - testTime1,TIME_MINUTES|TIME_SECONDS));
return(0);
}
//+------------------------------------------------------------------+
//___________________________________________________________________
void Draw_TradingLines()
{
//int xStep=0;
// xStep++;
int iTrend;
double lineValue;
int iFirstBar = nBarsBack-1;
double firstPriceValue = price[iFirstBar];
double diffBegin = price[iFirstBar] - price[iFirstBar+1];
//---- first value -----------------------------------------------
//---- high at begin
if (diffBegin >= 0)
{
iTrend = 1;
lineValue = firstPriceValue - iGannGrid_Interval*gridStep;
Set_UpLineValue(iFirstBar, lineValue);
}
else
//---- low at begin
{
iTrend = -1;
lineValue = firstPriceValue + iGannGrid_Interval*gridStep;
Set_DnLineValue(iFirstBar, lineValue);
}
//---- main loop
//================================================================
for (int i=nBarsBack-2; i>=0; i--)
{
//---- up trend (blue line) -----------------------------------
if (iTrend == 1)
{
//---- translate up linie
if (price[i] - iGannGrid_Interval*gridStep > lineValue + gridStep)
lineValue = price[i] - iGannGrid_Interval*gridStep;
else lineValue = lineValue + gridStep;
Set_UpLineValue(i, lineValue);
//---- reverse from up-trend / down-trend
if (price[i] < lineValue)
{
iTrend = -1;
lineValue = price[i] + iGannGrid_Interval*gridStep;
Set_DnLineValue(i, lineValue);
if (Show_PriceArrows)
dnArrow[i] = price[i];
if (Show_HiloArrows)
Show_SignalArrows(i, iTrend);
}
}
else
//---- down trend (red line) ----------------------------------
if (iTrend == -1)
{
//---- translate down linie
if (price[i] + iGannGrid_Interval*gridStep < lineValue - gridStep)
lineValue = price[i] + iGannGrid_Interval*gridStep;
else lineValue = lineValue - gridStep;
Set_DnLineValue(i, lineValue);
//---- reverse from down-trend / up-trend
if (price[i] > lineValue)
{
iTrend = 1;
lineValue = price[i] - iGannGrid_Interval*gridStep;
Set_UpLineValue(i, lineValue);
if (Show_PriceArrows)
upArrow[i] = price[i];
if (Show_HiloArrows)
Show_SignalArrows(i, iTrend);
}
}
}
return;
}
//___________________________________________________________________
void Set_UpLineValue(int iBar, double dValue)
{
if (dValue >= MinPriceLine[iBar]-gridStep &&
dValue <= MaxPriceLine[iBar]+gridStep)
{
upLine[iBar] = dValue;
}
else
upLine[iBar] = EMPTY_VALUE;
return;
}
//___________________________________________________________________
void Set_DnLineValue(int iBar, double dValue)
{
if (dValue >= MinPriceLine[iBar]-gridStep &&
dValue <= MaxPriceLine[iBar]+gridStep)
{
dnLine[iBar] = dValue;
}
else
dnLine[iBar] = EMPTY_VALUE;
return;
}
//___________________________________________________________________
void Show_SignalArrows(int i, int iTrend)
{
int iArrow;
color dColor;
double dATR, dHighOffset, dLowOffset, dPrice;
double dFactorOffset = 0.40;
int iHeight = 2;
string sName = "Signal_" + TimeToStr(Time[i]);
dATR = iATR(Symbol(),Period(),34,i);
double dHiloOffset = dATR * dFactorOffset;
//I use a value based on the current height of the window...?
double dHeightWindow = WindowPriceMax(0) - WindowPriceMin(0);
dLowOffset = dHeightWindow / 100;
dHighOffset = dLowOffset + 2*dHiloOffset;
//---- long signal
if (iTrend == 1)
{
iArrow = 233;
dColor = Blue;
dPrice = Low[i] - dLowOffset;
}
else
//---- short signal
if (iTrend == -1)
{
iArrow = 234;
dColor = Red;
dPrice = High[i] + dHighOffset;
}
dPrice = NormalizeDouble(dPrice,Digits);
ObjectCreate(sName,OBJ_ARROW,0,Time[i],dPrice);
ObjectSet(sName,OBJPROP_COLOR,dColor);
ObjectSet(sName,OBJPROP_ARROWCODE,iArrow);
return;
}
//___________________________________________________________________
double CurrentPrice(int priceCode, int i)
{
double dPrice;
switch (priceCode)
{
case PRICE_CLOSE:
{
dPrice = Close[i];
break;
}
case PRICE_OPEN:
{
dPrice = Open[i];
break;
}
case PRICE_MEDIAN:
{
dPrice = (High[i] + Low[i]) / 2.0;
dPrice = NormalizeDouble(dPrice,Digits);
break;
}
case PRICE_TYPICAL:
{
dPrice = (High[i] + Low[i] + Close[i]) / 3.0;
dPrice = NormalizeDouble(dPrice,Digits);
break;
}
}
return(dPrice);
}
//___________________________________________________________________
void Draw_HorizontalLine(double dValue)
{
dValue = NormalizeDouble(dValue,Digits);
string sName = "HLine_" + DoubleToStr(dValue,Digits);
ObjectCreate(sName,OBJ_TREND,iWindow, firstTime,dValue, Time[0],dValue);
ObjectSet(sName,OBJPROP_COLOR,MainGrid_Color);
ObjectSet(sName,OBJPROP_STYLE,MainGrid_Style);
ObjectSet(sName,OBJPROP_WIDTH,MainGrid_Width);
ObjectSet(sName,OBJPROP_RAY,false);
ObjectSet(sName,OBJPROP_BACK,false); //drawn in foreground
return;
}
//___________________________________________________________________
void Draw_VerticalLine(datetime dTime, double minVal, double maxVal)
{
string sName = "VLine_" + TimeToStr(dTime);
ObjectCreate(sName,OBJ_TREND,iWindow, dTime,minVal, dTime,maxVal);
ObjectSet(sName,OBJPROP_COLOR,MainGrid_Color);
ObjectSet(sName,OBJPROP_STYLE,MainGrid_Style);
ObjectSet(sName,OBJPROP_WIDTH,MainGrid_Width);
ObjectSet(sName,OBJPROP_RAY,false);
ObjectSet(sName,OBJPROP_BACK,false); //drawn in foreground
return;
}
//___________________________________________________________________
void Draw_GannGrid(datetime time1, datetime time2, double dValue1, double dValue2)
{
string sName = "Gann_" + dValue1;
double dScale = -gridStep * MathPow(10,Digits);
ObjectCreate(sName,OBJ_GANNGRID,iWindow, time1,dValue1, time2,dValue2);
ObjectSet(sName,OBJPROP_COLOR,GannGrid_Color);
ObjectSet(sName,OBJPROP_STYLE,GannGrid_Style);
ObjectSet(sName,OBJPROP_WIDTH,GannGrid_Width);
ObjectSet(sName,OBJPROP_RAY,true);
ObjectSet(sName,OBJPROP_SCALE,dScale);
ObjectSet(sName,OBJPROP_BACK,true); //drawn in background
return;
}
//___________________________________________________________________
void Write_PriceValue(double dValue)
{
string sTextShift;
for (int i=1; i<= Text_Shift; i++)
sTextShift = sTextShift + " ";
string sValue = DoubleToStr(dValue,Digits);
string sName = "Price_" + sValue;
sValue = sTextShift + sValue;
ObjectCreate(sName,OBJ_TEXT,iWindow, Time[0],dValue);
ObjectSetText(sName,sValue,fontSize);
return;
}
//####################################################################
//____________________________________________________________________
void Delete_GannObjects()
{
Delete_ObjectNames("Gann_");
Delete_ObjectNames("HLine_");
Delete_ObjectNames("VLine_");
Delete_ObjectNames("Price_");
Delete_ObjectNames("Signal_");
}
//____________________________________________________________________
void Delete_ObjectNames(string sName)
{
int nObjects = ObjectsTotal();
for (int i=nObjects; i>=0; i--)
{
string sObjectName = ObjectName(i);
if (StringFind(sObjectName, sName, 0) != -1)
{
ObjectDelete(sObjectName);
}
}
}