How can I calculate MAE/MFE for currency crosses in script?

 

Hi, I'm writing a script for calculating the MAE/MFE (maximum adverse excursion, maximum favorable excursion) with the strategy tester. So far, my script works great for currency pairs that are either quoted in USD (ie - GBPUSD, EURUSD, etc) or when the USD is the base (ie - USDJPY). By the way, my account currency is the USD. But I'm having trouble figuring out how to get the script to calculate the correct value for currency cross pairs (ie - GBPJPY, EURGBP, etc)

Lets say I'm testing on the GBPJPY, is it pssible to use:

MarketINfo("GBPJPY", MODE_TICKVALUE)

for a previous bar? (ie - the bar that corresponds to the MAE/MFE for each trade generated by the tester during the backtest?)

 

AFAIK

MarketInfo (Symbol(), MODE_TICKVALUE);

is 4 the current tick

 

but it's not so hard to calculate it

if the close[1] on GBPJPY = 124.96

u have to find out what's the close[1] for USDJPY let's say 78.35

& do the math

 
outofdebt:

Hi, I'm writing a script for calculating the MAE/MFE (maximum adverse excursion, maximum favorable excursion) with the strategy tester. So far, my script works great for currency pairs that are either quoted in USD (ie - GBPUSD, EURUSD, etc) or when the USD is the base (ie - USDJPY). By the way, my account currency is the USD. But I'm having trouble figuring out how to get the script to calculate the correct value for currency cross pairs (ie - GBPJPY, EURGBP, etc)

Lets say I'm testing on the GBPJPY, is it pssible to use:

for a previous bar? (ie - the bar that corresponds to the MAE/MFE for each trade generated by the tester during the backtest?)


Try looking through Phillip's codes, updated version at the bottom of page-1. https://www.mql5.com/en/forum/129553
 
 

Thanks for the ideas everyone. sorry I haven't responded very quickly - I've been struck by a mild case of influenza. Hopefully today I can get back on track with this. BTW, I have already sort of based my code and used a few of Phillip's ideas (I think?) and Rosh's scripts for MAE/MFE. Let me try the suggestions above and report back. Thanks.

 

After going through most of the suggestions above, I was still not able to find what I need. I started this project by trying to get Phillip's MAE/MFE scripts I found at this link: https://www.mql5.com/en/forum/127663/page2 to work. But after spending way too much time trying to fully understand and make his work (and adapt to what I was after) ... I gave up and I decided to make my own scaled down and simplified version of his scripts for my own testing purposes.

First of all, I am using my own version of Phillip's "GetSymbolType" function, which I have modifed to correctly identify and return an integer (1 to 4) assigned to 4 different types of currency symbol pairs as follows:

Type 1: USD is the base (on the left) currency (ie - USDJPY)

Type 2: USD is the quoted (on the right) currency (ie - EURUSD)

And now the two types of crosses:

Type 3: The base is either GBP, AUD, or NZD and the quoted currency is something OTHER than USD (ie - EURGBP, EURAUD) NOTE: in these examples (and all other in this type) the GBP, AUD, and NZD are normally the base to the USD. ALSO NOTE: that the EUR is never (or almost never, AFAIK) the quoted currency in ANY pair, major or otherwise; it is always a BASE (on the left) currency).

Type 4: Any other cross (meaning the USD is NIETHER base or the quoted currency) and doesn't fit into Type 3.

The formulas I am using to calculate the pip values in my account currency (USD) come from this link: http://www.forexnewbies.com/pip-value-formula/ and I have checked each one manually by placing trades with my MT4 platform and also by using the 'pip value calculator' from this link: http://www.earnforex.com/pip-value-calculator They are 100% correct for all currency pairs (AFAIK), and all types can fit into 1 of 4 symbol types.

My version of this script is different from Phillip's (for those who are familiar with his method). I decided to use Rosh's idea to calculate MAE/MFE (in $) simply by multiplying:

pip value in USD * MAEinPips (or MFEinPips)

For example, using GBPJPY: This is a Type 4 formula and in order to get "pip value in USD" you would need to multiply the currency units (ie - 100,000 for a full standard lot) by the point value (ie - 0.001) and then divide the product by what I call an "intermediate" rate (because it is essentially an intermediate calculation), specifically the ASK rate of USDJPY, to make the pip value calculation in USD. Now going one step further, to get MAE/MFE, you then multiply the result obtained in the first step by the "MAEinPips" (or MFEinPips).

MY PROBLEM

So far, I can get the MAE/MFE (in pips) for all pairs, majors and the crosses, and in $ for Types 1 and 2. Where I am having trouble is with Type 3 and 4 as far as getting the correct intermediate value (ie - the ASK rate of USDJPY) that corresponds to the MAE/MFE value at the time the MAE/MFE values occurred for each trade during the backtest. My version of this script picks the correct 'intermediate symbol type' (represented by the variable "SymbolType") and is passed to the "CrossPair" function which correctly returns the intermediate pair, represented by the variable "IntPairForCross" to be used in the pip value calculation.

HOWEVER ... the WRONG value is obtained from the chart belonging to the intermediate pair. In other words, the value it returns is no where NEAR the time of the MAE/MFE that occured on the cross pair. The two times (bar #'s) should be the same, and they are NOT. In fact the value that the script reurns is not even on the same chart.

For example, let's say the GBPJPY hypothetically had an MAE at 135.156 and this occured at 2011.03.14 09:45. The value that is ruturned will be quoted in USDJPY but the value (any value) will NOT be for the time the MAE occurred in GBPPJY. How do I get these to "synchronize" correctly so that the correct intermediate USDJPY value that occured at the same time the MAE occurred in the GBPJPY ... so that I can make the correct 'pip value in $" calculation?

You follow me?

Here is my version of the functions that identify and return the symbol type (1 to 4) and find the correct intermediate pair used in the pip value calculations:

//+--------------------------------------+
//|           Gets SymbolType            | 
//+======================================+

int SymType()
   {  
   int      SymbolType=5;
   string   CurrentSymbol="",SymbolLeft="",SymbolRight="",IntPairForCross="";
   
   CurrentSymbol=Symbol();
   
   SymbolLeft=StringSubstr(CurrentSymbol,0,3);
   SymbolRight=StringSubstr(CurrentSymbol,3,3);
        
   if(SymbolLeft==AccountCurrency()) SymbolType=1;
   if(SymbolRight==AccountCurrency()) SymbolType=2;
   if(SymbolType!=1 && SymbolType!=2)
      {
      if(SymbolRight=="GBP"||SymbolRight=="AUD"||SymbolRight=="NZD") SymbolType=3;
      else SymbolType=4; 
      }
   if(SymbolType==5) Print("Error occurred while identifying SymbolType ",SymbolType);
   return(SymbolType);
   } // end SymType()  

// --------------------------------------------------------------- CounterPairForCross() -------------------------------------------------

string CrossPair(int symBol)
   {  
   string   CurrentSymbol="",SymbolRight="",IntPairForCross="";
   
   CurrentSymbol=Symbol();
   SymbolRight=StringSubstr(CurrentSymbol,3,3);
     
   switch(symBol) 
      {
      case 1   :  break;
      case 2   :  break;
      case 3   :  IntPairForCross=StringConcatenate(SymbolRight,AccountCurrency()); //ie - EURGBP ==> GBPUSD ... xxxUSD, etc...
      case 4   :  IntPairForCross=StringConcatenate(AccountCurrency(),SymbolRight); //ie - GBPJPY ==> USDJPY ... USDxxx, etc...
      default  :  Print("Error encountered in IntPairForCross on ",CurrentSymbol); 
      }
   return(IntPairForCross);
   } // end CrossPair() 

Now for the main part which uses the 'symbol type' and 'intermediate pair' obtained above as input to do MAE/MFE calculations:

   // --- variable declaration and #include section --- (omitted here)
   
   CurrentPoint=Point;
   CurrentDigits=Digits;
   SymbolType=SymType();
   IntPairForCross=CrossPair(SymbolType);
      
  // ---- ArrayResize() section ---- (omitted here)
   
         CloseBar=iBarShift(NULL,0,OrderCloseTime(),false);                   //the order was closed on this bar 
         OpenBar=iBarShift(NULL,0,OrderOpenTime(),false);                     //the order was opened on this bar
         HighestBar=iHighest(NULL,0,MODE_HIGH,OpenBar-CloseBar,CloseBar+1);   //highest bar between order open and close

         HighestBarTime=iTime(NULL,0,HighestBar);                             //time of highest bar
         LowestBar=iLowest(NULL,0,MODE_LOW,OpenBar-CloseBar,CloseBar+1);      //lowest bar between order open and close
         LowestBarTime=iTime(NULL,0,LowestBar);                               //time of lowest bar
         OPrice=NormalizeDouble(OrderOpenPrice(),CurrentDigits)/CurrentPoint;
         CPrice=NormalizeDouble(OrderClosePrice(),CurrentDigits)/CurrentPoint;
         hiPips=NormalizeDouble(iHigh(NULL,0,HighestBar),CurrentDigits)/CurrentPoint;
         loPips=NormalizeDouble(iLow(NULL,0,LowestBar),CurrentDigits)/CurrentPoint;
         hiDollars=iHigh(NULL,0,HighestBar);
         loDollars=iLow(NULL,0,LowestBar);
         lotSize=MarketInfo(CurrentSymbol,MODE_LOTSIZE);
         spread=MarketInfo(CurrentSymbol,MODE_SPREAD);
         
         intLowestBarTime=iTime(IntPairForCross,0,LowestBar);
         intHighestBarTime=iTime(IntPairForCross,0,HighestBar);
         intLoDollars=iLow(IntPairForCross,0,LowestBar); 
         intHiDollars=iHigh(IntPairForCross,0,HighestBar);
         intPoint=MarketInfo(IntPairForCross,MODE_POINT);
         
   // Calculate the MAE (maximum adverse excursion) and MFE (maximum favorable excursion) 
         
         if(OrderType()==OP_BUY)  // buy or sell order?
         { 
            ProfitLossinPips=CPrice-OPrice;
            MAEinPips=loPips-OPrice; 
            if(hiPips-OPrice<0) MFEinPips=0;
            else MFEinPips=hiPips-OPrice; 
                        
            switch(SymbolType) // calculate MAE/MFE according to SymbolType 
            {
              // The left currency of the pair is the USD
             case 1   :  MAEinDollars=NormalizeDouble((OrderLots()*lotSize*CurrentPoint/loDollars)*MAEinPips,2);
                         MFEinDollars=NormalizeDouble((OrderLots()*lotSize*CurrentPoint/hiDollars)*MFEinPips,2);
                         break;
              // The right currency of the pair is the USD
             case 2   :  MAEinDollars=NormalizeDouble(OrderLots()*lotSize*CurrentPoint*MAEinPips,2);
                         MFEinDollars=NormalizeDouble(OrderLots()*lotSize*CurrentPoint*MFEinPips,2);
                         break;
              // The currency pair is a cross-currency pair
             case 3   :  MAEinDollars=NormalizeDouble(OrderLots()*lotSize*intPoint*intLoDollars*MAEinPips,2);
                         MFEinDollars=NormalizeDouble(OrderLots()*lotSize*intPoint*intHiDollars*MFEinPips,2);
                         break;
             case 4   :  MAEinDollars=NormalizeDouble((OrderLots()*lotSize*intPoint/intLoDollars)/MAEinPips,2);
                         MFEinDollars=NormalizeDouble((OrderLots()*lotSize*intPoint/intHiDollars)/MFEinPips,2);
                         break;
             // The expression did not generate a case value
             default  :  Print("Error encountered in the SWITCH routine for calculating MAE/MFE");
             } // end switch
         } // end if

// --- (OrderType()==OP_SELL) omitted ... same as the "OP_BUY" but is the inverse of the ABOVE ^^

... rest of program which adds the values obtained above to various different arrays and outputs them into a CSV file that will be 
opened in Excel in "tester/files" ... which I have made coded some Excel macros that process all the stats into a spreadsheet where 
additional calculations are made. 
 

OK, I figured out how to get the correct USDJPY price that corresponds to the correct GBPJPY MAE/MFE price. The main problem was that the MT4 platform I was using (IBFX demo) was buggy. Since I am only trying to get the calculations working at this point, I'm not worried about getting 90% or 99% modeling, so I just tried to download basic data from IBFX. It turns out that their USDJPY data I was using is full of holes and is total crap. So, I downloaded a FXDD demo platform and their data, and once I changed a few lines of code, it works correctly.

The code above worked after I changed these lines:

intLoDollars=iLow(IntPairForCross,0,LowestBar); 
intHiDollars=iHigh(IntPairForCross,0,HighestBar);

to these:
intLoDollars=iLow(IntPairForCross,0,iBarShift(IntPairForCross,0,LowestBarTime)); 
intHiDollars=iHigh(IntPairForCross,0,iBarShift(IntPairForCross,0,HighestBarTime));
 
outofdebt:

OK, I figured out how to get the correct USDJPY price that corresponds to the correct GBPJPY MAE/MFE price. The main problem was that the MT4 platform I was using (IBFX demo) was buggy. Since I am only trying to get the calculations working at this point, I'm not worried about getting 90% or 99% modeling, so I just tried to download basic data from IBFX. It turns out that their USDJPY data I was using is full of holes and is total crap. So, I downloaded a FXDD demo platform and their data, and once I changed a few lines of code, it works correctly.

The code above worked after I changed these lines:

That is fantastic! especially being able to Excel it! Are you at all keen on sharing it all? Hope that doesn't sound rude after you have done all of the work ; ) This is sorely missing from MT4!

LW

Reason: