Monitore-The-Spread

Author: Copyright 2022, Thomas Nowotny
0 Views
0 Downloads
0 Favorites
Monitore-The-Spread
ÿþ//+------------------------------------------------------------------+

//|                                          Monitore-The-Spread.mq5 |

//|                                   Copyright 2022, Thomas Nowotny |

//|                                             https://www.mql5.com |

//+------------------------------------------------------------------+

#define ATTEMPTS  10

#define DELAY     Sleep(2000)



#property copyright     "Copyright 2022, Thomas Nowotny"

#property version       "1.02"

#property description   "Multisymbol spread monitoring."

#property description   "Stores the max spread of each selected symbol during a period."

#property description   "The spread is checked x-times per second."

#property strict



#include <errordescription.mqh>



//+------------------------------------------------------------------+

//| Input variable                                                   |

//+------------------------------------------------------------------+

input string I = "";    //+---------- Inputs ----------+

input ENUM_TIMEFRAMES   Interval             = PERIOD_H1;                                    // Output period

input string            SymbolsToMonitore    = "AUDCAD|AUDJPY|AUDNZD|AUDUSD|EURUSD";         // Symbol(s) or ALL

input string            DefaultString        = "Account-Number";                             // Free string for filename

input int               CheckPerSecond       = 4;                                            // Checks per second



//+------------------------------------------------------------------+

//| global variables                                                 |

//+------------------------------------------------------------------+

string   AllSymbols           = "AUDCAD|AUDJPY|AUDNZD|AUDUSD|CADJPY|EURAUD|EURCAD|EURGBP|EURJPY|EURNZD|EURUSD|GBPAUD|GBPCAD|GBPJPY|GBPNZD|GBPUSD|NZDCAD|NZDJPY|NZDUSD|USDCAD|USDCHF|USDJPY";

datetime StoredBarOpenTime    = 0;                    // stored open time

string   OutputFileName       = "";

int      failureCount         = 0;

int      Timer                = 1000/CheckPerSecond;  // get the timer in milliseconds

int      NumberOfSymbols;                             // how much symbols do we check?

string   SymbolArray[];                               // each symbol (eg AUDCAD) is stored as string in each element of SymbolArray[]

double   SpreadPerSymbol[];                           // store the max spread (during a period) per symbol in each element of SpreadPerSymbol[]



//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit(){

   EventSetMillisecondTimer(Timer);

   // do the init only once

   static bool initOnce = false;

   if(!initOnce){

      initOnce = true;

      // init the variables 

      return InitTheStuff()? INIT_SUCCEEDED : INIT_FAILED;

   }

   // in case of changing timeframe or so...

   return(INIT_SUCCEEDED);

}



//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason){

   EventKillTimer();

}



//+------------------------------------------------------------------+

//| Expert OnTimer function                                          |

//+------------------------------------------------------------------+

void OnTimer(){   

   // get the opening time of the actual bar from the actual chart

   datetime actualBarOpenTime  = iTime(_Symbol,Interval,0);



   // if the bar open time is known --> get the spread and store the max spread for each symbol

   if(actualBarOpenTime == StoredBarOpenTime){

      // get all the information for each sysmbol

      for(int i = 0; i < NumberOfSymbols; i++){

         string currentSymbol = SymbolArray[i];         

         int    digits        = (int)SymbolInfoInteger(currentSymbol,SYMBOL_DIGITS);

         double ask           = SymbolInfoDouble(currentSymbol,SYMBOL_ASK);

         double bid           = SymbolInfoDouble(currentSymbol,SYMBOL_BID);

         double spread        = NormalizeDouble(ask-bid,digits);  // yes, its manually done

         

         // store only the maximum spread for that sysmbol

         if(spread > SpreadPerSymbol[i]){

            SpreadPerSymbol[i] = spread;

         }

      }

   }

   // if the bar open time is new --> print the collected spreads in the file, update the StoredBarOpenTime, reset the SpreadPerSymbol

   else ExportTheValues();

}



//+------------------------------------------------------------------+

//| general functions                                                |

//+------------------------------------------------------------------+

bool InitTheStuff(){

      

      // show the ea is alive

      Print("Let's start... \n"__FILE__," is starting at: ",TimeToString(TimeLocal(),TIME_DATE|TIME_SECONDS));

      

      // which symbols to monitore? ... many

      string symbolsToMonitore = "";

      if(SymbolsToMonitore == "ALL") symbolsToMonitore = AllSymbols;

      else symbolsToMonitore = SymbolsToMonitore;

      

      // fill the SymbolArray and get the NumberOfSymbols

      NumberOfSymbols = StringSplit(symbolsToMonitore, '|', SymbolArray);

      Print(__FILE__," will monitore: ", symbolsToMonitore);

            

      // resize SpreadPerSymbol acording to NumberOfSymbols

      ArrayResize(SpreadPerSymbol,NumberOfSymbols);

      

      // set all SpreadPerSymbol elements to 0 and add the symbols to the marketwatch

      for(int i=0; i < NumberOfSymbols; i++){

         SpreadPerSymbol[i]= 0;  

         if(SymbolSelect(SymbolArray[i], true));

         else{Print("Cannot add ",SymbolArray[i]," to the marketwatch!"); return (false);}         

      }

      

      // store the opening time of the actual bar

      StoredBarOpenTime = iTime(_Symbol,Interval,0);

      

      // get the date for the filename

      string creation_date = TimeToString(TimeLocal(),TIME_DATE|TIME_SECONDS);

      StringReplace(creation_date,".","-");

      StringReplace(creation_date,":","-");

      StringReplace(creation_date," ","_");

      

      // define the filename

      OutputFileName = "Spread-"+DefaultString+"-"+creation_date+".csv";

      Print ("Values will be stored in: ",OutputFileName);

      

      // open the file, write first line, close the file

      int file_handle = OpenTheFile(OutputFileName);

      if(file_handle != INVALID_HANDLE){

         string str = "";

         for(int i = 0; i < NumberOfSymbols; i++){

            str = str+";"+SymbolArray[i];

         }

         FileWriteString(file_handle,str+"\r\n");  

         FileClose(file_handle); 

      } else return false;

   

   //nothing bad happend?   

   return true;

}



// print the collected values into the file

void ExportTheValues(){

   // print the spreads per symbol in the file

   int file_handle = OpenTheFile(OutputFileName);

   if(file_handle != INVALID_HANDLE){

      FileSeek(file_handle,0,SEEK_END);



      // first comes timestamp in str

      string str = TimeToString(StoredBarOpenTime);

      // go through the symbols

      for(int i = 0; i < NumberOfSymbols; i++){

         string sub = DoubleToString(SpreadPerSymbol[i],5);

         StringReplace(sub,".",",");

         // expand the str with each symbol spread value

         str = str+";"+sub;

      }

   // write the str in the file

   FileWriteString(file_handle,str+"\r\n");  

   FileClose(file_handle);

   }

   

   // update the StoredBarOpenTime

   StoredBarOpenTime = iTime(_Symbol,Interval,0);

   // reset the SpreadPerSymbol

   for(int i=0; i < NumberOfSymbols; i++){

      SpreadPerSymbol[i]= 0;

   }

}



// translate the error code into a description

string WhatsUp(const int retcode){

   if(retcode >= 10004 && retcode <= 10046){

      return (TradeServerReturnCodeDescription(retcode));

   }

   else{

      return(ErrorDescription(retcode));

   }   

}



// open the file and return the handle

int OpenTheFile(string fileName){

   failureCount = 0; // reset the failure count



   for (int i = 0; i < ATTEMPTS; i++){

      ResetLastError();

      int fileHandle = FileOpen(fileName,FILE_READ|FILE_WRITE|FILE_ANSI|FILE_TXT);

      if(fileHandle==INVALID_HANDLE){

         PrintFormat("Attempt: %i Failed to open %s file, Error: %s",failureCount+1, fileName, WhatsUp(GetLastError()));

         ErrorCount(__FUNCTION__);

      }

      else return(fileHandle);

   }

   return(INVALID_HANDLE);

}



// count the attemps and print after full attempts

void ErrorCount(const string func){

   failureCount++;

   DELAY;

   if(failureCount >= ATTEMPTS){

      Print("ERROR call in function: ",func);

      PrintFormat("Attempt: %i from %i. Stop of Attempts.",failureCount, ATTEMPTS);

      // SendNotification(__FILE__," ERROR call in function: ",func);

   }

}

Comments