Hope you don't mind, I have taken the opportunity to learn a little about mql5 using your code . . . I have learned that a lot of things are different compared to mql4 and that not having a Book, as there is for mql4, is a pain in the behind.
This is where I got to, it seems to be OK in terms of changing timeframes and it will update the bar to the right of the currently forming bar when a new bar is formed. It does not update the currently forming bar, not sure if you wanted it to or not.
Not at all RaptorUK :) I am learning from your code too :) Very nice code and it is working perfectly. It is still a little bit weird that we must clear the values as it is not stated anywhere in the references, at least I have not come a cross anything like that...
Br, Candles
EDIT: I will take my word back see bold part of code below taken from references. The buffers are indeed initialized with 0.0 prior to filling them with values:
//+------------------------------------------------------------------+//| DRAW_COLOR_CANDLES.mq5 |//| Copyright 2011, MetaQuotes Software Corp. |//| http://www.mql5.com |//+------------------------------------------------------------------+#property copyright "Copyright 2011, MetaQuotes Software Corp."#property link "http://www.mql5.com"#property version "1.00"#property description "An indicator to demonstrate DRAW_COLOR_CANDLES."#property description "It draws candlesticks of a selected symbol in a separate window"#property description " "#property description "The color and width of candlesticks, as well as the symbol are changed"#property description "randomly every N ticks"#property indicator_separate_window#property indicator_buffers 5#property indicator_plots 1//--- plot ColorCandles#property indicator_label1 "ColorCandles"#property indicator_type1 DRAW_COLOR_CANDLES//--- Define 8 colors for coloring candlesticks (they are stored in the special array)#property indicator_color1 clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange#property indicator_style1 STYLE_SOLID#property indicator_width1 1//--- input parametersinputint N=5; // The number of ticks to change the typeinputint bars=500; // The number of candlesticks to showinputbool messages=false; // Show messages in the "Expert Advisors" log//--- Indicator buffersdouble ColorCandlesBuffer1[];
double ColorCandlesBuffer2[];
double ColorCandlesBuffer3[];
double ColorCandlesBuffer4[];
double ColorCandlesColors[];
int candles_colors;
//--- Symbol namestring symbol;
//--- An array for storing colors contains 14 elementscolor colors[]=
{
clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrMagenta,clrCyan,clrMediumPurple
};
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- If bars is very small - complete the work ahead of timeif(bars<50)
{
Comment("Please specify a larger number of bars! The operation of the indicator has been terminated");
return(-1);
}
//--- indicator buffers mappingSetIndexBuffer(0,ColorCandlesBuffer1,INDICATOR_DATA);
SetIndexBuffer(1,ColorCandlesBuffer2,INDICATOR_DATA);
SetIndexBuffer(2,ColorCandlesBuffer3,INDICATOR_DATA);
SetIndexBuffer(3,ColorCandlesBuffer4,INDICATOR_DATA);
SetIndexBuffer(4,ColorCandlesColors,INDICATOR_COLOR_INDEX);
//--- An empty valuePlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- The name of the symbol, for which the bars are drawn
symbol=_Symbol;
//--- Set the display of the symbolPlotIndexSetString(0,PLOT_LABEL,symbol+" Open;"+symbol+" High;"+symbol+" Low;"+symbol+" Close");
IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_COLOR_CANDLES("+symbol+")");
//---- The number of colors to color candlesticks
candles_colors=8; // see. a comment to the #property indicator_color1 property//--- return(0);
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
staticint ticks=INT_MAX-100;
//--- Count ticks to change the style and color
ticks++;
//--- If a sufficient number of ticks has been accumulatedif(ticks>=N)
{
//--- Select a new symbol from the Market watch window
symbol=GetRandomSymbolName();
//--- Change the form
ChangeLineAppearance();
//--- Change the colors used to draw the candlesticks
ChangeColors(colors,candles_colors);
int tries=0;
//--- Make 5 attempts to fill in the buffers of plot1 with the prices from symbolwhile(!CopyFromSymbolToBuffers(symbol,rates_total,0,
ColorCandlesBuffer1,ColorCandlesBuffer2,ColorCandlesBuffer3,
ColorCandlesBuffer4,ColorCandlesColors,candles_colors)
&& tries<5)
{
//--- A counter of calls of the CopyFromSymbolToBuffers() function
tries++;
}
//--- Reset the counter of ticks to zero
ticks=0;
}
//--- return value of prev_calculated for next callreturn(rates_total);
}
//+------------------------------------------------------------------+//| Fills in the specified candlestick |//+------------------------------------------------------------------+bool CopyFromSymbolToBuffers(string name,
int total,
int plot_index,
double &buff1[],
double &buff2[],
double &buff3[],
double &buff4[],
double &col_buffer[],
int cndl_colors
)
{
//--- In the rates[] array, we will copy Open, High, Low and CloseMqlRates rates[];
//--- The counter of attemptsint attempts=0;
//--- How much has been copiedint copied=0;
//--- Make 25 attempts to get a timeseries on the desired symbolwhile(attempts<25 && (copied=CopyRates(name,_Period,0,bars,rates))<0)
{
Sleep(100);
attempts++;
if(messages) PrintFormat("%s CopyRates(%s) attempts=%d",__FUNCTION__,name,attempts);
}
//--- If failed to copy a sufficient number of barsif(copied!=bars)
{
//--- Form a message stringstring comm=StringFormat("For the symbol %s, managed to receive only %d bars of %d requested ones",
name,
copied,
bars
);
//--- Show a message in a comment in the main chart windowComment(comm);
//--- Show the messageif(messages) Print(comm);
return(false);
}
else
{
//--- Set the display of the symbol PlotIndexSetString(plot_index,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Close");
IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_COLOR_CANDLES("+symbol+")");
}
//--- !!!!!!!Initialize buffers with empty values!!!!!ArrayInitialize(buff1,0.0);
ArrayInitialize(buff2,0.0);
ArrayInitialize(buff3,0.0);
ArrayInitialize(buff4,0.0);//--- On each tick copy prices to buffersfor(int i=0;i<copied;i++)
{
//--- Calculate the appropriate index for the buffersint buffer_index=total-copied+i;
//--- Write the prices to the buffers
buff1[buffer_index]=rates[i].open;
buff2[buffer_index]=rates[i].high;
buff3[buffer_index]=rates[i].low;
buff4[buffer_index]=rates[i].close;
//--- Set the candlestick colorint color_index=i%cndl_colors;
col_buffer[buffer_index]=color_index;
}
return(true);
}
//+------------------------------------------------------------------+//| Randomly returns a symbol from the Market Watch |//+------------------------------------------------------------------+string GetRandomSymbolName()
{
//--- The number of symbols shown in the Market watch windowint symbols=SymbolsTotal(true);
//--- The position of a symbol in the list - a random number from 0 to symbolsint number=MathRand()%symbols;
//--- Return the name of a symbol at the specified positionreturnSymbolName(number,true);
}
//+------------------------------------------------------------------+//| Changes the color of the candlestick segments//+------------------------------------------------------------------+void ChangeColors(color &cols[],int plot_colors)
{
//--- The number of colorsint size=ArraySize(cols);
//--- string comm=ChartGetString(0,CHART_COMMENT)+"\r\n\r\n";
//--- For each color index define a new color randomlyfor(int plot_color_ind=0;plot_color_ind<plot_colors;plot_color_ind++)
{
//--- Get a random valueint number=MathRand();
//--- Get an index in the col[] array as a remainder of the integer devisionint i=number%size;
//--- Set the color for each index as the property PLOT_LINE_COLORPlotIndexSetInteger(0, // The number of a graphical stylePLOT_LINE_COLOR, // Property identifier
plot_color_ind, // The index of the color, where we write the color
cols[i]); // A new color//--- Write the colors
comm=comm+StringFormat("CandleColorIndex[%d]=%s \r\n",plot_color_ind,ColorToString(cols[i],true));
ChartSetString(0,CHART_COMMENT,comm);
}
//---
}
//+------------------------------------------------------------------+//| Changes the appearance of candlesticks |//+------------------------------------------------------------------+void ChangeLineAppearance()
{
//--- A string for the formation of information about the candlestick propertiesstring comm="";
//--- Write the symbol name
comm="\r\n"+symbol+comm;
//--- Show the information on the chart using a commentComment(comm);
}
But being the obsessive person I am I would still like to know why indicator buffer arrays can initially have so weird values like in the below pic although it is probably irrelevant:
... And thus the below code also works flawlessly.... I think:
But being the obsessive person I am I would still like to know why indicator buffer arrays can initially have so weird values like in the below pic although it is probably irrelevant:
An array is just a bunch of memory locations that hold the values in the array. When the memory is allocated for the array is it cleared/zeroed ? I don't know if it is or isn't, maybe it isn't, so that could explain the strange values.
RaptorUK: An array is just a bunch of memory locations that hold the values in the array. When the memory is allocated for the array is it cleared/zeroed ? I don't know if it is or isn't, maybe it isn't, so that could explain the strange values.
Yeah, that its what I think as well. Maybe it is just the number of the memory cell or something...
... And thus the below code also works flawlessly.... I think:
You may still get issues with the currently forming bar, I think. The four arrays you are using are dynamic arrays, they are not defined with a pre-set size and are not resized using ArrayResize(), they grow as needed and new memory is allocated when needed. Using ArrayInitialise() will, I assume, initialise the array elements that exist at the time . . . what about new elements that get added as new bars are added to the chart ?
but what it doesn't do, because of the limit of the for loop, is clear the array values for the currently forming bar. That position is rates_total-1 the for loop exits when i == rates_total-1 this was why I added
o[i] = 0.0; h[i] = 0.0; l[i] = 0.0; c[i] = 0.0; // clear values for currently forming bar
You may still get issues with the currently forming bar, I think. The four arrays you are using are dynamic arrays, they are not defined with a pre-set size and are not resized using ArrayResize(), they grow as needed and new memory is allocated when needed. Using ArrayInitialise() will, I assume, initialise the array elements that exist at the time . . . what about new elements that get added as new bars are added to the chart ?
This code also sets the Array values to 0.0
but what it doesn't do, because of the limit of the for loop, is clear the array values for the currently forming bar. That position is rates_total-1 the for loop exits when i == rates_total-1 this was why I added
immediately after the loop.
I believe you are right. I tested my previous code on the M1 chart and indeed problems occur when new bar is completed and refresh clicked. The underlined part is very well put I get it now :) ArrayInitialize() no good as the arrays grow in time and thus initialization is performed only for the array of the current size.
Hope you don't mind, I have taken the opportunity to learn a little about mql5 using your code . . . I have learned that a lot of things are different compared to mql4 and that not having a Book, as there is for mql4, is a pain in the behind.
This is where I got to, it seems to be OK in terms of changing timeframes and it will update the bar to the right of the currently forming bar when a new bar is formed. It does not update the currently forming bar, not sure if you wanted it to or not.
Not at all RaptorUK :) I am learning from your code too :) Very nice code and it is working perfectly. It is still a little bit weird that we must clear the values as it is not stated anywhere in the references, at least I have not come a cross anything like that...
Br, Candles
EDIT: I will take my word back see bold part of code below taken from references. The buffers are indeed initialized with 0.0 prior to filling them with values:
... And thus the below code also works flawlessly.... I think:
EDIT: Code not working after new bar is completed.
But being the obsessive person I am I would still like to know why indicator buffer arrays can initially have so weird values like in the below pic although it is probably irrelevant:
... And thus the below code also works flawlessly.... I think:
But being the obsessive person I am I would still like to know why indicator buffer arrays can initially have so weird values like in the below pic although it is probably irrelevant:
An array is just a bunch of memory locations that hold the values in the array. When the memory is allocated for the array is it cleared/zeroed ? I don't know if it is or isn't, maybe it isn't, so that could explain the strange values.
... And thus the below code also works flawlessly.... I think:
You may still get issues with the currently forming bar, I think. The four arrays you are using are dynamic arrays, they are not defined with a pre-set size and are not resized using ArrayResize(), they grow as needed and new memory is allocated when needed. Using ArrayInitialise() will, I assume, initialise the array elements that exist at the time . . . what about new elements that get added as new bars are added to the chart ?
This code also sets the Array values to 0.0
but what it doesn't do, because of the limit of the for loop, is clear the array values for the currently forming bar. That position is rates_total-1 the for loop exits when i == rates_total-1 this was why I added
immediately after the loop.
You may still get issues with the currently forming bar, I think. The four arrays you are using are dynamic arrays, they are not defined with a pre-set size and are not resized using ArrayResize(), they grow as needed and new memory is allocated when needed. Using ArrayInitialise() will, I assume, initialise the array elements that exist at the time . . . what about new elements that get added as new bars are added to the chart ?
This code also sets the Array values to 0.0
but what it doesn't do, because of the limit of the for loop, is clear the array values for the currently forming bar. That position is rates_total-1 the for loop exits when i == rates_total-1 this was why I added
immediately after the loop.