
Alert and Comment for External Indicators. Multi-Currency Analysis Through External Scanning
Introduction
In the previous articles we saw how information can be obtained from indicators that use Wingdings symbols displayed in a chart as a source of information ("Alert and Comment for External Indicators") and how to create indicator-based Alerts in respect of indicators that use indicator buffers to store information ("Alert and Comment for External Indicators. Part Two"), while information output is implemented through the color change.
Crossover of indicator lines that are stored in indicator buffers represents another way of informing the user of the indicator behavior.
As we have already seen, getting values from indicator buffers is in itself not something complicated that can affect processor load. In our indicator, we will therefore implement the possibility of displaying multi-currency information.
If the number of available instruments is large, the trader suffers considerable eye strain caused by constant chart monitoring. So traders often choose just a few symbols and trade exclusively on them.
It may later turn out that there was an opportunity to execute a deal or a number of deals for another currency pair whose chart was not open on the screen at the right moment. That is why we need multi-currency analysis of available instruments.
Based on that I've come up with the idea of using an indicator-based Alert function as a way to quickly display information on changes in the list of available instruments.
Alert Based on Multi-Currency Indicator
Let's first have a look at the code of the data processing block that gets information from indicator buffers of the external indicator.
double buffer1, buffer2, buffer12, buffer22; // Analyze the first and second bars in the charts buffer1 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 1); buffer12 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 2); buffer2 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 1); buffer22 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 2); if(buffer12<=buffer22&&buffer1>buffer2) { Alert (text+"UP"); // There is a crossover send_email (text+"UP"); return (1); } if(buffer12>=buffer22&&buffer1<buffer2) { Alert (text+"DN"); // There is a crossover send_email (text+"DN"); return (1); } return (0);
As we can see, everything here is simple. We have come across the similar logic in our previous article. Last time we used the change in color of displayed buffers, whereas here we use position values of these buffers relative to each other.
The necessary processing will be implemented as a separate block. Multi-currency and multiple time frame analysis will require repeated use of this procedure.
The list of available instruments will be stored in an external file, allowing us to simplify the process of making changes in case any modifications are required in the future. Using this approach, in order to modify the list of available instruments the user can independently re-create or make changes to the file of available instruments, without having to modify the program code of the indicator.
At the end of the article, you will see how you can create a custom file of available instruments.
A subprogram for reading file data is provided below.
//+------------------------------------------------------------------+ //| SymbolList_fromSet.mq4 | //| Copyright © 2006, komposter | //| mailto:komposterius@mail.ru | //+------------------------------------------------------------------+ void LoadFileToSymbol() { { int file_handle = FileOpen(SetFile_name + ".set", FILE_READ); //---- If an error occurred if(file_handle < 0) { Print("Error No.", GetLastError(), " when opening the file!!!"); return(-1); } int SymbolsCount = 0; while(true) { Symbols[SymbolsCount] = FileReadString(file_handle); //---- If you have reached the end of the file, stop if(GetLastError() == 4099) break; if(FileIsEnding(file_handle)) break; SymbolsCount ++; ArrayResize(Symbols, SymbolsCount + 1); } FileClose(file_handle); } } //--------------------------------------------------------------+
Now, after preparing the array of instruments we only need to implement the multiple time frame processing for each instrument.
We will begin the calculations with the current time frame.
// Analyze the array of symbols (Calculations on the current and all lower time frames) for (int i=0; i<ArraySize(Symbols); i++) { Total = 0; switch (Period()) { case 43200: Total = Total + process ( Symbols[i], 43200); case 10080: Total = Total + process ( Symbols[i], 10080); case 1440: Total = Total + process ( Symbols[i], 1440); case 240: Total = Total + process ( Symbols[i], 240); case 60: Total = Total + process ( Symbols[i], 60); case 30: Total = Total + process ( Symbols[i], 30); case 15: Total = Total + process ( Symbols[i], 15); case 5: Total = Total + process ( Symbols[i], 5); // case 1: Total = Total + process ( Symbols[i], 1); }
The calculations are made from the current time frame to the lowest time frame. So if you need to calculate the alert starting from daily time frame, the chart with the attached indicator should be open on daily time frame. If you need to get a signal starting from hourly time frame, the chart time frame must be hourly, and so on. The indicator is recalculated on each new bar only.
Such approach has enabled the user to handle recalculations of the indicator in a more convenient way: you simply change the working time frame, without having to add additional parameters and calculation functions to the code.
The string for working on a minute time frame is commented out. It needs to be uncommented in case you need to use the indicator on a minute time frame.
// case 1: Total = Total + AlertComment ( Symbols[i], 1);
The 2MA_forAlert.mq4 indicator attached to the article is used as the data source for our indicator. 2MA_forAlert is a simple indicator that displays two MA lines. You can also use any other indicator that has two buffers (two lines), e.g. Stochastic, MACD, etc.
This is what the terminal alert looks like when different indicators are used:
The buffers where line values are stored may have different order. For example:
0 - main line
1 - signal line
or
0 - signal line
1 - main line
So, when using the external indicator, you should, on your own, determine the order in which the lines will be used. In case of incorrect alert notification, the input parameters should be changed.
extern int ExtBuff1 = 0; extern int ExtBuff2 = 1;
All 8 available buffers (numbers from 0 to 7) can be used as parameters.
Seeing that the indicator uses the external file with a list of instruments, I will show you how it can be generated in the terminal.
First, we create all the necessary instruments in the data window and for this purpose we:
1. Open all the available instruments.
2. Leave only those of them for which we will get signals.
There should be as many instruments as required to be used in trading.
3. Then right-click on the Market Watch window to save the file.
4. The file should be saved in the folder that contains Expert Advisor files of MetaTrader
The file can be given any name but .set file extension cannot be modified. The example provided in the article uses the forexall.set file.
extern string SetFile_name = "forexall"; // File that contains symbols of user instruments
After creating the file, you should open charts for each symbol one by one in order for the terminal to load the history. Otherwise, any of the instruments may fall out of the processing.
If you saved the file in the default folder \experts\ symbolsets, make sure to copy it to the MetaTrader \experts\files folder since this is the only folder from which the indicator can open the file (MetaTrader limitations). In the indicator, you should further enter the name of the file that will be processed to read data on the available instruments it contains.
You also have the opportunity to get information on the multi-currency scanner operation to your e-mail. Simply set the corresponding parameter value to true and get signals by e-mail.
extern bool Signal_email = false;
There are users who further continue the code development by implementing redirection to get signals via SMS to their mobile phones. Everybody's approach is different.
All the indicators should be in the MetaTrader \experts\indicators folder.
Conclusion
This approach allows you to use Alert functions to build your information space of various modules, without having to learn programming or search for a specialist who can implement your idea in a program. The main thing for us is to get timely information.
In conclusion, I will provide a complete code of the Alert indicator.
//+------------------------------------------------------------------+ //| Alert_MT4.mq4 | //| Copyright © 2009, Fibook.ru | //| http://www.fibook.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, Fibook.ru" #property link "http://www.fibook.ru" #property indicator_chart_window extern string SetFile_name="forexall"; // File that contains symbols of user instruments extern string nameIndicator = "input indicator name"; extern int ExtBuff1 = 0; extern int ExtBuff2 = 1; extern string UserText = "Cross"; extern bool Signal_email = false; string Symbols[1],text; int expBars=0; //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { // If there is no new bar, exit if(!isNewBar()) return; int Total; //---- Check for input parameter errors if(ControlError()==false) return; //---- Load symbols from the file to the Symbols array LoadFileToSymbol(); //---- // Analyze the array of symbols (Calculations on the current and all lower time frames) for(int i=0;i<ArraySize(Symbols);i++) { Total=0; switch(Period()) { case 43200: Total = Total + process ( Symbols[i], 43200); case 10080: Total = Total + process ( Symbols[i], 10080); case 1440: Total = Total + process ( Symbols[i], 1440); case 240: Total = Total + process ( Symbols[i], 240); case 60: Total = Total + process ( Symbols[i], 60); case 30: Total = Total + process ( Symbols[i], 30); case 15: Total = Total + process ( Symbols[i], 15); case 5: Total = Total + process ( Symbols[i], 5); // case 1: Total = Total + process ( Symbols[i], 1); } if(Total>1) { text=StringConcatenate(" Warning!!! ",Symbols[i]," have ",UserText," for ",Total," TF"); Alert(text); send_email(text); } } //---- return(0); } //+------------------------------------------------------------------+ int process(string Sym_,int TF) { text=StringConcatenate(Sym_," ",TF," indicator ",nameIndicator," Crossing line "); double buffer1,buffer2,buffer12,buffer22; // Analyze the first and second bars in the charts buffer1 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 1); buffer12 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 2); buffer2 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 1); buffer22 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 2); if(buffer12<=buffer22 && buffer1>buffer2) { Alert(text+"UP"); // There is a crossover send_email(text+"UP"); return(1); } if(buffer12>=buffer22 && buffer1<buffer2) { Alert(text+"DN"); // There is a crossover send_email(text+"DN"); return(1); } return(0); } //+------------------------------------------------------------------+ //| SymbolList_fromSet.mq4 | //| Copyright © 2006, komposter | //| mailto:komposterius@mail.ru | //+------------------------------------------------------------------+ void LoadFileToSymbol() { { int file_handle=FileOpen(SetFile_name+".set",FILE_READ); //---- If an error occurred if(file_handle<0) { Print("Error No.",GetLastError()," when opening the file!!!"); return(-1); } int SymbolsCount=0; while(true) { Symbols[SymbolsCount]=FileReadString(file_handle); //---- If you have reached the end of the file, stop if(GetLastError()==4099) break; if(FileIsEnding(file_handle)) break; SymbolsCount++; ArrayResize(Symbols,SymbolsCount+1); } FileClose(file_handle); } } //--------------------------------------------------------------+ void send_email(string text) { if(Signal_email==true) SendMail("Alert ",text); } //--------------------------------------------------------------+ bool ControlError() { // Check whether the indicator name has been entered if(nameIndicator=="input indicator name") { Alert("Enter the indicator name "); return(false); } // Check whether the file containing the symbols exists int handle; handle=FileOpen(SetFile_name+".set",FILE_CSV|FILE_READ,';'); if(handle<1) { Alert("The ",SetFile_name,".set file could not be found, last error ",GetLastError()); return(false); } // Check if there is any error in the assignment of input variables of the analyzed indicator buffers if(ExtBuff1>7 || ExtBuff2>7) { Alert("Incorrect parameters of the ExtBuff1 or ExtBuff2 buffer"); return(false); } if(ExtBuff1==ExtBuff2) { Alert("Error: ExtBuff1 and ExtBuff2 cannot be equal"); return(false); } return(true); } /*----------------------------------------------------------------------+ |The function will return true if the new bar appears, otherwise false | +---------------------------------------------------------------------*/ bool isNewBar() { bool res=false; if(expBars!=Bars) { expBars=Bars; res=true; } return(res); } //+------------------------------------------------------------------+
Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/1371





- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
New article Alert and Comment for External Indicators. Multi-Currency Analysis Through External Scanning has been published:
Author: Vladimir
Valdimir . this is one of the best tool for me which I was in search for the last few days but the problem which I face is that it is not recognizing the forexall.set file so can you help me in this regard ?
thanks for such a wonderful tool for trading .
Yogeshkumar
yogeshkumarrameshbhaigajjar@yahoo.com
I am facing same problem which I face is that it is not recognizing the forexall.set file so can you help me in this regard ?