//+------------------------------------------------------------------+
//|                                             History analysis.mq4 |
//|                                                    Steve Hopwood |
//|                                     www.hopwood3,freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Steve Hopwood"
#property link      "www.hopwood3,freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"

/*
void Display()
int start()
void CleanUpInputString()
void CalculateParamatersPassed()
void SetUpGap()
void SetUpExtraGap()

int DisplayMagicNumber()
int ExtractMagicNumber(String FilterPair)
void AnalyseMagicNumberTrades(int MagicNumber)

void DisplayTradeComment()
void AnalyseTradeCommentTrades(string tc)

*/

extern string     MNI1="Separate magic numbers with a comma.";
extern string     MNI2="Include descriptions in brackets.";
extern string     MagicNumber="38952063 (Daily Cross), 427851 (V1.7 4H Cross),387537804 (AshFX),";
extern string     TC1="Enter all or part of a trade comment to search.";
extern string     TC2="Separate inputs with a comma.";
extern string     TradeComment="JPY trigger (Range), GBP trigger (Range),USD trigger (Range),CHF trigger (Range),AUD trigger (Range),EUR trigger (Range),";
extern string     CurrencySymbol="$";

string            Gap;
int               DisplayGapSize = 30;
string            ScreenMessage;
int               OrdersInHistory=0;

string            InputString;//Holds the contents of MagicNumber or TradeComment as appropriate.
int               NoOfParams;// Holds the number of paramaters passed by the user via the inputs screen
string            FilterPair[]; //Array to hold the paramaters passed by the user

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   

   // Force display at start up, so EA will do analysis even when broker is closed
   start();
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   Comment("");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+

void SetUpGap()
{
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }

}//End void SetUpGap()

void SetUpExtraGap()
{
   Gap = StringConcatenate(Gap, "      ");
   
}//End void SetUpExtraGap()

void CleanUpInputString()
{
   // Does any tidying up of the user inputs
   
   //Remove unwanted spaces
   InputString = StringTrimLeft(InputString);
   InputString = StringTrimRight(InputString);

   //Add final comma if ommitted by user
   if (StringSubstr(InputString, StringLen(InputString)-1) != ",") 
      InputString = StringConcatenate(InputString,",");
      
   
}//void CleanUpInputString

void CalculateParamatersPassed()
{
   // Calculates the numbers of paramaters passed in MagicNumber and TradeComment.
   
   int Index = 0;//For searching NoTradePairs
   int LastIndex;//Points the the most recent Index
   
   while(Index > -1)
      {
         Index = StringFind(InputString, ",",LastIndex);
         if (Index > -1)
         {
            NoOfParams ++;
            LastIndex = Index+1;            
         }//if (Index > -1)
      }//while(int cc > -1)
   
   
   
}//End void CalculateParamatersPassed()

int ExtractMagicNumber(string FilterPair)
{
   // Returns the magic number contained within FilterPair.
   
   if (StringLen(FilterPair)==0) return;//User error, so nothing to do
   
   // Extract to a string
   string no="";
   for (int cc=0; cc<StringLen(FilterPair); cc++)
   {
      no = StringConcatenate(no, StringSubstr(FilterPair,cc));
   }//int (cc=0; cc<StringLen(FilterPair); cc++)
   
   
   //Return as an integer 
   return(StrToInteger(no));
   
}//End int ExtractMagicNumber(String FilterPair)

void AnalyseMagicNumberTrades(int MagicNumber)
{
   //Analyses history by magic number and purs the info into ScreenMessage for later display
   
   int Trades, Winners, Losers, Be;
   double Profit;
   
   for (int cc=0; cc < OrdersHistoryTotal(); cc++)
   {
      OrderSelect(cc, SELECT_BY_POS, MODE_HISTORY);
      if (OrderMagicNumber() == MagicNumber && OrderComment() != "cancelled" )
      {
         Profit = Profit + OrderProfit();
         Trades++;
         if (OrderProfit() > 0) Winners ++;
         if (OrderProfit() == 0) Be ++;
         if (OrderProfit() < 0) Losers ++;
      }//if (OrderMagicNumber() = MagicNumber
      
   }//for (int cc=0; cc < OrdersHistoryTotal(); cc++)

   ScreenMessage = StringConcatenate(ScreenMessage, ": Trades = ", Trades,
                  ": Winners = ", Winners, ": Losers = ", Losers,
                  ": Break even = ", Be,
                  ": Profit = ", CurrencySymbol, DoubleToStr(Profit,2), NL);
}//End void AnalyseMagicNumberTrades(int MagicNumber)


int DisplayMagicNumber()
{
   // Displays the results of History trades, searched by their magic numbers
   
   // Cleanup first
   InputString=MagicNumber;
   CleanUpInputString();
   
   // Extract the number of paraaters passed by the user
   CalculateParamatersPassed();
   
   // Resize the array appropriately
   string NewArray = ArrayResize(FilterPair, NoOfParams);
   
   // Display the headings
   SetUpGap();
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "MagicNumber Analysis",NL);
   SetUpExtraGap();
   int Index = 0;//For searching InputString
   int LastIndex = 0;//Points the the most recent Index
   for (int cc = 0; cc < NoOfParams; cc ++)
   {
      Index = StringFind(InputString, ",",LastIndex);
      if (Index > -1)
      {
         FilterPair[cc] = StringSubstr(InputString, LastIndex,Index-LastIndex);
         ScreenMessage = StringConcatenate(ScreenMessage, Gap, FilterPair[cc], " ");
         LastIndex = Index+1;
         // Do the history search
         int mns = ExtractMagicNumber(FilterPair[cc]);//Need to know magic number first
         AnalyseMagicNumberTrades(mns);
         //ScreenMessage = StringConcatenate(ScreenMessage,NL);//Temp to force a lf
         
      }//if (Index > -1)            
   }//for (int cc; cc<NoOfParams; cc ++)
   
}//End int DisplayMagicNumber()

void Display()
{
      if (OrdersHistoryTotal() == 0) 
      {
         Comment(Gap, "No trades in history");
         return;
      }//if (OrdersHistoryTotal() == 0)
      
      // All the setting up of ScreenMessage is done by the EA functions as they are called,
      // so only need to display it.
      Comment(ScreenMessage);
       
}//End void Display()


void AnalyseTradeCommentTrades(string tc)
{
   //Analyses history by magic number and purs the info into ScreenMessage for later display
   
   int Trades, Winners, Losers, Be;
   double Profit;
   
   for (int cc=0; cc < OrdersHistoryTotal(); cc++)
   {
      OrderSelect(cc, SELECT_BY_POS, MODE_HISTORY);
      int Index = StringFind(OrderComment(), tc);
      if (Index > -1)
      {
         Profit = Profit + OrderProfit();
         Trades++;
         if (OrderProfit() > 0) Winners ++;
         if (OrderProfit() == 0) Be ++;
         if (OrderProfit() < 0) Losers ++;
      }//if (Index > -1)
      
   }//for (int cc=0; cc < OrdersHistoryTotal(); cc++)

   ScreenMessage = StringConcatenate(ScreenMessage, ": Trades = ", Trades,
                  ": Winners = ", Winners, ": Losers = ", Losers,
                  ": Break even = ", Be,
                  ": Profit = ", CurrencySymbol, DoubleToStr(Profit,2), NL);
}//End void AnalyseTradeCommentTrades(string tc)



void DisplayTradeComment()
{
   // Displays the results of History trades, searched by their trade comment
   
   // Cleanup first
   InputString=TradeComment;
   CleanUpInputString();
   
   // Extract the number of paraaters passed by the user
   CalculateParamatersPassed();
   
   // Resize the array appropriately
   string NewArray = ArrayResize(FilterPair, NoOfParams);
   
   // Display the headings
   SetUpGap();
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Trade Comment Analysis",NL);
   SetUpExtraGap();
   int Index = 0;//For searching InputString
   int LastIndex = 0;//Points the the most recent Index
   for (int cc = 0; cc < NoOfParams; cc ++)
   {
      Index = StringFind(InputString, ",",LastIndex);
      if (Index > -1)
      {
         FilterPair[cc] = StringSubstr(InputString, LastIndex,Index-LastIndex);
         FilterPair[cc] = StringTrimLeft(FilterPair[cc]);
         FilterPair[cc] = StringTrimRight(FilterPair[cc]);
         ScreenMessage = StringConcatenate(ScreenMessage, Gap, FilterPair[cc], " ");
         LastIndex = Index+1;
         // Do the history search
         AnalyseTradeCommentTrades(FilterPair[cc]);
         //ScreenMessage = StringConcatenate(ScreenMessage,NL);//Temp to force a lf
         
      }//if (Index > -1)            
   }//for (int cc; cc<NoOfParams; cc ++)
   

}//Evd void DisplayTradeComment()

int start()
  {
//----
      
      if (OrdersInHistory != OrdersHistoryTotal())
      {
         ScreenMessage="";
         if (StringLen(MagicNumber) > 0) DisplayMagicNumber();
         if (StringLen(TradeComment) > 0) DisplayTradeComment();
         Display();
         OrdersInHistory = OrdersHistoryTotal();
      }
         
//----
   return(0);
  }
//+------------------------------------------------------------------+