I was yesterday trying to recode a couple of indicators from MQL4 to MQL5. I did the first one with no problem but the second is giving me a serious headache
All work perfectly but it doesn't plot anything. After hours of testing I found that the problem is in the position where I put the arrows.
The following code is a simple code that just paints arrows to see that problem easily.
Code: Select all
//+------------------------------------------------------------------+
//| DRAW_COLOR_ARROW.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <InitMQL4.mqh>
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
//--- plot ColorArrow
#property indicator_label1 "Bar1"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "Bar2"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "Bar3"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrDarkOrchid
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//--- An indicator buffer for the plot
double Bar1[], Bar2[], Bar3[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Bar1,INDICATOR_DATA);
PlotIndexSetInteger(0,PLOT_ARROW,159);
PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,5);
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
SetIndexBuffer(1,Bar2,INDICATOR_DATA);
PlotIndexSetInteger(1,PLOT_ARROW,159);
PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,5);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
SetIndexBuffer(2,Bar3,INDICATOR_DATA);
PlotIndexSetInteger(2,PLOT_ARROW,115);
PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,5);
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
datetime Time[];
int count = 1; // number of elements to copy
ArraySetAsSeries(Time,true);
CopyTime(_Symbol,_Period,0,count,Time);
static datetime Time0; if (Time0 == Time[0]) return(0); Time0 = Time[0];
//Solo continua al comienzo de una barra nueva
//Print("puntoMedio(0): " + puntoMedio(0) );
//--- Block for calculating indicator values
int start=1;
if(prev_calculated>0) start=prev_calculated-1;
//--- Calculation loop
for(int i=1;i<rates_total;i++)
{
double O = open[i];
double C = close[i];
double mediaCuerpo = (C - O)/2; //Tamaño del cuerpo entre 2
double midPoint = mediaCuerpo+O;
//--- If the current Close price is higher than the previous one, draw an arrow
if(close[i]>close[i-1])
{
Bar1[i]=open[i];
Bar2[i]=midPoint;
Bar3[i]=puntoMedio(i);
if(i<10)
Print("i: " + i + ", fecha = " + TimeToString(iTimeMQL4(Symbol(),Period(),i)) + ", puntoMedio = " + puntoMedio(i) + ", midPoint = " + midPoint + ", open = " + open[i] + ", iOpenMQL4 = " + iOpenMQL4(Symbol(),Period(),i));
//Bar3[i]=midPoint;
}
//--- Otherwise specify the null value
else
{
Bar1[i]=0;
Bar2[i]=0;
Bar3[i]=0;
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
double conversion(string symbol)
{
double point = MarketInfoMQL4(symbol, MODE_POINT);
if(symbol=="" || symbol == Symbol())
{
if(point==0.00001) return(0.0001);
else if(point==0.001) return(0.01);
else return(point);
}
else
{
double tPoint = MarketInfoMQL4(symbol,MODE_POINT);
if(tPoint==0.00001) return(0.0001);
else if(tPoint==0.001) return(0.01);
else return(tPoint);
}
}
//+------------------------------------------------------------------+
string TFToStr(int tf)
//+------------------------------------------------------------------+
// Converts a Empty4-numeric timeframe to its descriptor string
// Usage: string s=TFToStr(15) returns s="M15"
{
switch (tf) {
case 1 : return("M1");
case 5 : return("M5");
case 15 : return("M15");
case 30 : return("M30");
case 60 : return("H1");
case 240 : return("H4");
case 1440 : return("D1");
case 10080 : return("W1");
case 43200 : return("MN");
}
return("");
}
//Te dice el valor del punto medio de la vela
double puntoMedio(int shift)
{
int timeFrame = Period(); string par = Symbol();
double O = iOpenMQL4(par, timeFrame, shift);
double C = iCloseMQL4(par, timeFrame, shift);
double mediaCuerpo = (C - O)/2; //Tamaño del cuerpo entre 2
double midPoint = mediaCuerpo+O;
return(midPoint);
} The bar1 = open; is plotted correctly BUT when the value it's printed, it doesn't have any sense.
The bar2 = midpoint; is plotted BUT the value that it prints doesn't have any sense either. It is calculated via the open[] and close[]
The bar3 = puntoMedio; is not plotted BUT the value that it prints is the exact price where it should be painted. It is calculated via the iOpenMQL4 and iCloseMQL4.
I can't understand why it works with the open that gives a crazy value and it doesn't works with the midpoint value, wich gives the value that I want.
You will need the mqh (include folder) file that is attached.