|
|
|
|
|
|
|
|
|
Let's creat a real indicator on crossing of two moving averages (MA). File CrossMA.csv contains columns «Up arrow» and «Down arrow». Bar opening time (Time[]), bar number (which will increase with a new finished bar) and values from two columns/arrays, pointing at the presence of a red or blue arrow or their absence (zero value) correspond univocally to each bar at the current moment of time. Let's creat a custom indicator with the help of «Advisor Creation Wizard».
|
|
|
|
Let's specify the name of the indicator (CrossMA), author, link. Close the parameters table and press the «Add» button, a new parameter ExtParam1 (parameter name by default) appears, give a new name, LongPeriod, to this new parameter, as in our previous script, type int remains unchanged, let the initial value be equal to 21.
|
|
|
|
Let's add another parameter ShortPeriod, external parameters of our indicator are ready. Move to the «Next». We do not need «Indicator in a separate window» check-box. We will place our arrows in the price chart (that's why check-boxes «Minimum» and «Maximum» are not available for us). Let's click «Add» once again. A red index («Red») of type «Line» appears in the list of indices in the first line, now change the type to the «Arrow» one and the color to the «Blue».. Let's change symbol type 217 (up arrow) to 241 to make it more similar to the script.
|
|
|
|
Let's add the second index and change its data (type, color, symbol).
|
|
|
|
#property copyright "MetaQuotes"
#property link "http://forum.alpari-idc.ru/viewtopic.php?t=48186"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern int LongPeriod=21;
extern int ShortPeriod=13;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//----
int init()
{
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,241);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,0.0);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,242);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(1,0.0);
//----
return(0);
}
//----
int deinit()
{
//----
//----
return(0);
}
//----
int start()
{
int counted_bars=IndicatorCounted();
return(0);
}
Advisors creation wizard has done the preparatory work. We see that the indicator will be displayed on the price chart, there are two utility buffers in the indicator, their colors have been specified, arrays were declared
double ExtMapBuffer1[];
double ExtMapBuffer2[];
where the indicators values will be stored.
Also two input parameters have been created.
|
|
|
|
When the indicator was created function init() was also created. In this function the final setting of our indicator is carried out. Indicators in MT4 are flexible, each indicator can have up to 8 utility (indicator) buffers. The only thing we have to do is to declare these buffers correctly. These buffers are also called indices, a custom indicator may give values for the zero index, first, second etc up to the seventh one. The number of indices is set by the directive
#property indicator_buffers N
colors are set beginning with one
#property indicator_color1 Blue
#property indicator_color2 Red
With the help of SetIndexStyle(index_number, mode) we set a necessary style for every index (there may be several indices with different styles of drawing), having specified the Arrow style we also indicate the symbol code (241 and 242) for each index, then it is specified that index 0 is ExtMapBuffer1 array, index 1 is the data from ExtMapBuffer2 array. If we do not join the index and array with function SetIndexBuffer(index_number, buffer_array_name) the indicator won't work. This is the first mistake when an indicator is created. The second one is that a buffer is declared as a type different from the double one, for example, int.
|
|
|
|
The SetIndexEmptyValue(index_number, Blank_Value) function is in the last line. Usually there is no “absence of value” notion in the programming languages. That is why some definite value will indicate the absence of it (in our case it will be the lack of an arrow), usually 0.0 value is used for it, though other values are also possible. We should write an algorithm which will fill out the indicator buffers (indices) with the values where arrows will be placed.
For it let's refer to the last script CrossMASignals-5, copy everything from the start() block, delete the operations of arrows marking in the chart and a record into the file. I have also added Print() functions into the init() and deinit() blocks.
We have almost created an indicator without writing a code. If we put /* at the beginning of the fragment, it will become a comment which is not compiled. It is convenient when mistakes are looked for and when it is necessary to switch off large pieces of a code.
|
|
|
|
#property copyright "MetaQuotes"
#property link "http://forum.alpari-idc.ru/viewtopic.php?t=48186"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern int LongPeriod=21;
extern int ShortPeriod=13;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//----
int init()
{
//---- indicators
Print("init() is executed");
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,241);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,0.0);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,242);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(1,0.0);
return(0);
}
//----
int deinit()
{
Print("deinit() is executed");
return(0);
}
//----
int start()
{
int counted_bars=IndicatorCounted();
//----
double maLongCur, maLongPrev, maShortCur, maShortPrev;
/*
string arrowName; // here a unique name of the object-arrow will be given
int arrowCounter=0;// arrow counter
*/
// let's declare utility variables where arrows price coordinates will be stored
double value1,value2;
Print("start() is executed");
for(int i=Bars-1;i>=0;i--)
{
// let's zero utility variables
value1=0.0;
value2=0.0;
maLongCur=iMA(NULL,0,LongPeriod,0,MODE_SMA,PRICE_CLOSE,i+1);// slow average on the previous bar
maLongPrev=iMA(NULL,0,LongPeriod,0,MODE_SMA,PRICE_CLOSE,i+2);// slow average on the bar two bars before
maShortCur=iMA(NULL,0,ShortPeriod,0,MODE_SMA,PRICE_CLOSE,i+1);// quick average on the bar two bars before
maShortPrev=iMA(NULL,0,ShortPeriod,0,MODE_SMA,PRICE_CLOSE,i+2);// quick average on the previous bar
//If there is a buy signal on the previous bar let's put a blue up arrow
// at the bar opening price
if((maShortCur>maLongCur)&&(maShortPrev<maLongPrev))
{
/*
// Let's put an arrow
// object name - arrowName
// object type - OBJ_ARROW
// horizontal coordinate - Time[i] bar opening time
// vertical coordinate - Open[i] bar opening price
arrowName="arrow"+arrowCounter;
ObjectCreate(arrowName,OBJ_ARROW,0,Time[i],Open[i]);
// let's set the arrow type - 241 , up arrow
ObjectSet(arrowName,OBJPROP_ARROWCODE,241);
// let's set the arrow color - blue
ObjectSet(arrowName,OBJPROP_COLOR,Blue);
// increase the arrow counter
arrowCounter++;
*/
value1=Open[i];//let's remember the price of the blue arrow
}
//If there is a sell signal on the previous bar let's put a red down arrow
// at the bar opening price
if((maShortCur<maLongCur)&&(maShortPrev>maLongPrev))
{
/*
// Put an arrow
// object name - arrowName
// object type - OBJ_ARROW
// horizontal coordinate - Time[i] bar opening time
// vertical coordinate - Open[i] bar openig price
arrowName="arrow"+arrowCounter;
ObjectCreate(arrowName,OBJ_ARROW,0,Time[i],Open[i]);
// let's set the arrow type - 242, down arrow
ObjectSet(arrowName,OBJPROP_ARROWCODE,242);
// let's set the arrow color - red
ObjectSet(arrowName,OBJPROP_COLOR,Red);
// increase the arrow counter
arrowCounter++;
*/
value2=Open[i];//remeber the price of the red arrow
}
/*
//let's write down the data for the current bar into the file
FileWrite(FileHandle,TimeToStr(Time[i]),i,value1,value2);
*/
}
return(0);
}
The code is compiled very well, but the indicator does not draw anything. For this only two lines should be added:
ExtMapBuffer1[i]=value1;
ExtMapBuffer2[i]=value2;
As far as we remember, CrossMA.csv (once script CrossMASignals-5 is executed) contains two columns: «Up arrow» and «Down arrow». Now these columns are in buffers ExtMapBuffer1[] and ExtMapBuffer2[].
Let's compile the indicator and start it in the chart EURUSD D1 again. There are again two sets of arrows (red and blue) in the chart, but they are of a smaller size and not graphic objects, available for editing. The arrows are an inseparable part of the indicator and they will be redrawn when a time frame is changed.
Let's open the bar «Data window» and point the crosses to the last blue up arrow (to get the crosses mode press the mouse wheel or middle button). In front of CrossMA there is 1.1886 value, this is a value of ExtMapBuffer1 on this bar, value2 is a value of ExtMapBuffer2 buffer on this bar, there is no value for it as 0.0 is an empty value
(
remember
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
?
)
|
|
|
|
As you see, it is quite easy to creat an indicator.
You can download the indicator here
Go to article «Indicator Optimisation».
|
|
|
|
|
|