Multi Pair Optimization

 

Hey All,

I want to run optimization algo for multiple currencies. To give example lets assume I will use QQE Histogram to buy or sell. It has following potential input values:

input int                qqeinpRsiPeriod          = 15;          // RSI period
input int                qqeinpRsiSmoothingFactor =  2;          // RSI smoothing factor
input double             qqeinpWPFast             = 3;       // Fast period
input double             qqeinpWPSlow             = 3;       // Slow period

I want to find the most optimized value for those inputs for all 28 pairs.I had several approaches without any success:

1. So my first approach was to use   "All Symbols Select Market Watch" and change indicator 

OnTick -> 
for(int i=13;i<16;i++){
      C1Handle = iCustom(_Symbol,_Period,C1IndicatorName,i,qqeinpRsiSmoothingFactor,qqeinpWPFast,qqeinpWPSlow,qqeinpPrice,qqeinpUpBound,qqeinpDnBound);
      if(shouldBuy()){
         if(shouldLong)openTrade(ORDER_TYPE_BUY,stopLossDistance,takeProfitDistance,i);
      }   
      if(shouldSell()){
         if(shouldShort)openTrade(ORDER_TYPE_SELL,stopLossDistance,takeProfitDistance,i);
      }     }

So for each tick I change one of the inputs and update handler function.

This is how openTrade looks like:

void openTrade(ENUM_ORDER_TYPE orderType,double slDistance,double tpDistance, int i){
   Print("i is: ",i);
    double      openPrice;
    double      stopLossPrice;
         double takeProfitPrice;
         double InpOrderSize=getLotSize(riskPerTrade,slDistance);
    if (orderType == ORDER_TYPE_BUY ){
         openPrice =  NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);   
         stopLossPrice = openPrice - slDistance;
         takeProfitPrice = openPrice + tpDistance;
    }else{
         openPrice =  NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);   
         stopLossPrice = openPrice + slDistance;
         takeProfitPrice = openPrice - tpDistance;
    }
    double stopL = NormalizeDouble(stopLossPrice,3);
    double takeP = NormalizeDouble(takeProfitPrice,3);
    double cantor = (stopL + takeP)*(stopL + takeP +1)/2 + takeP;
    Print("Cantor is ",cantor);
    resultObj.Add(cantor,Symbol() +"," + i);
    PrintObject();
    trade.PositionOpen(Symbol(), orderType, InpOrderSize, openPrice, stopLossPrice, takeProfitPrice, InpTradeComment);
}

I could not find any property that is distinct for each trade action. So I tried to use stoploss and takeprofit and create unique pair(Cantor Pair) out of those values and put indicator information into object.So idea is I will have object like this:
{
122.122 : EURUSD13
12221.122: EURUSD15
}
I will use this object like this:

  void OnTradeTransaction(const MqlTradeTransaction& trans,const MqlTradeRequest& request,const MqlTradeResult& result)
   {   
     if(HistoryDealSelect(trans.deal) == true)
     {
         ENUM_DEAL_REASON deal_reason=(ENUM_DEAL_REASON) HistoryDealGetInteger(trans.deal,DEAL_REASON);
        
         if(EnumToString(deal_reason) == "DEAL_REASON_SL")
         {
            Print("SL");
            double stopL = NormalizeDouble(trans.price_sl,3);
            double takeP = NormalizeDouble(trans.price_tp,3);
            double cantor = (stopL + takeP)*(stopL + takeP +1)/2 + takeP;
            string stuff;
            resultObj.TryGetValue(cantor,stuff);
           // Print(stuff);
            writeToFile(stuff + "SL");
            
         }
         if(EnumToString(deal_reason) == "DEAL_REASON_TP")
         {
            Print("TP");
            double stopL = NormalizeDouble(trans.price_sl,3);
            double takeP = NormalizeDouble(trans.price_tp,3);
            double cantor = (stopL + takeP)*(stopL + takeP +1)/2 + takeP;
            string stuff;
            resultObj.TryGetValue(cantor,stuff);
           // Print(stuff);
            writeToFile(stuff +"TP");
         }      
      }
   }

When Take Profit or Stop Loss is hit, I take stop  losss and take profit infos from MqlTradeTransaction and create cantor unique value like  122.122. Then I get indicator settings from the object(I called it stuff).
So stuff = EURUSD13. Then I write result to some file : EURUSD13SL or EURUSD13TP. I have another scripts which reads this file and understands total number of wins and loses for each pair and settings. 

But the issue is stop loss and take profit values are not unique. For example if RSIPeriod=13 and RSIPeriod=14.All entry points are same. So the question for this method is what property can I use to distunguish each setting when I catch them in Stop Loss or Take Profit

 

My Second approach was to use basic "Slow Complete Algorithm" and run it 28 time for different pairs (As I understand you cant run it for all pairs all together, which sucks). But it has other issue.

This is for AUDCAD

SETTING 1 SETTING 2 SETTING 3 SETTING 4 WIN LOSE NET PROFIT
8 1 1 1 121 85 -9951.08
9 1 1 1 118 86 -15275.7
10 1 1 1 117 87 -18077.98
11 1 1 1 117 81 -7426.18
12 1 1 1 117 81 -7427.41
14 1 1 1 118 82 -7863.16

This is for EURUSD

8 1 1 1 135 81 17852.25
9 1 1 1 137 81 21052.82
10 1 1 1 134 82 14093.7
11 1 1 1 133 83 10414.74
12 1 1 1 131 83 7532.35
13 1 1 1 130 84 4047.51
14 1 1 1 131 83 7661.77

As you can see Setting 1 = 13 is missed in AUDCAD. So  "Slow Complete Algorithm"  misses some indicator values randomly.

 

I also tried to run  "Slow Complete Algorithm"  and change pairs inside of code by using mql5. The issue is when you actually run optimization in MT5 you need to choose some pair. Assume I chose EURUSD and then chose AUDCAD. Results will be completly different.

To summurize I am stuck. How can I optimize indicator inputs for 28 pairs? Is there easier way? May be I am missing something here

 
OnTick -> 

      C1Handle = iCustom(_

Perhaps you should read the manual, especially the examples.
   How To Ask Questions The Smart Way. 2004
      How To Interpret Answers.
         RTFM and STFW: How To Tell You've Seriously Screwed Up.

They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
          Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
          Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
          How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 2020.03.08
          How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 2020.07.05
          How to call indicators in MQL5 - MQL5 Articles 12 March 2010
 
William Roeder:

Perhaps you should read the manual, especially the examples.
   How To Ask Questions The Smart Way. 2004
      How To Interpret Answers.
         RTFM and STFW: How To Tell You've Seriously Screwed Up.

They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
          Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
          Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
          How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 2020.03.08
          How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 2020.07.05
          How to call indicators in MQL5 - MQL5 Articles 12 March 2010
I know jow to use iCustom. As I explained I am tring to find hacky way to optimize indicator values. Probably there are better ways which I could not find in documentation. Fast/Slow Complete Algorithms run for different indicator values, but they run just for one pair.  All Symbols Select Market Watch on the other hand runs for all pairs but does not run for different indicator settings. This small hack was my aproach to solve that problem.
 
Hi, I know it has been a long time since your post,bit Im stuck in the same situation. I think I have an idea though. What if we create single csv 1m candle file containing all the pairs an load it in a custom symbol. The trick would be to mix the data or to put them just one after an other, not sure how that could make a difference. Well, I was looking around and had this idea. I will try it asap. What do you think?
 
Hi, I know it has been a long time since your post, but Im stuck in the same situation. I think I have an idea though. What if we create single csv 1m candle file containing all the pairs an load it in a custom symbol. The trick would be to mix the data or to put them just one after an other, not sure how that could make a difference. Well, I was looking around and had this idea. I will try it asap. What do you think?