Experts: Indiana Jones Mean Reversion EA

 

Indiana Jones Mean Reversion EA:

This is a simple mean reversion EA

Indiana Jones Mean Reversion EA

Author: Yashar Seyyedin

 
is it reading the low before it simulates the low ? what am i missing ?
 
Lorentzos Roussos #:
is it reading the low before it simulates the low ? what am i missing ?

I do not know either. I shared it to see if someone knows.

 
Lorentzos Roussos #:
is it reading the low before it simulates the low ? what am i missing ?

Excuse my ignorance,

What is incorrect? 

What does it mean before the simulation?

 
Juan Luis De Frutos Blanco #:

Excuse my ignorance,

What is incorrect? 

What does it mean before the simulation?

The OHLC is simulated like this if i recall : 

For bullish bars : Open->Low->High->Close

For bearish bars : Open->High->Low->Close

So when the ea has to decide to trade it sometimes finds the edge break of a high line on a bearish bar and the opposite . 

i think 

 

would mitigate that if it traded only on candle opens using up to the last formed candle data 

//+------------------------------------------------------------------+
//|                                              MeanReversion.mq5   |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//|                                          Author: Yashar Seyyedin |
//|       Web Address: https://www.mql5.com/en/users/yashar.seyyedin |
//+------------------------------------------------------------------+

#include <Trade\Trade.mqh>
CTrade trade;

input group "EA Setting"
input int lookback = 200;
input double risk_per_trade = 1;

datetime barstamp=0;
int OnInit(void){
barstamp=0;
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(PositionsTotal()>0)
      return;
   if(iTime(_Symbol,_Period,0)>barstamp){
   barstamp=iTime(_Symbol,_Period,0);
   if(iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, lookback, 1)==1)
      Buy();

   if(iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, lookback, 1)==1)
      Sell();
   }
  }
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Buy()
  {
   double Ask=SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double tp=Mean();
   double sl=2*Ask-tp;
   double lot=CalculateLots(Ask, sl, ORDER_TYPE_BUY);
   if(CheckMoneyForTrade(_Symbol, lot, ORDER_TYPE_BUY))
      trade.Buy(lot, _Symbol, Ask,sl,tp);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Sell()
  {
   double Bid=SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double tp=Mean();
   double sl=2*Bid-tp;
   double lot=CalculateLots(Bid, sl, ORDER_TYPE_SELL);
   if(CheckMoneyForTrade(_Symbol, lot, ORDER_TYPE_SELL))
      trade.Sell(lot, _Symbol, Bid,sl,tp);
  }
//+------------------------------------------------------------------+

//|                                                                  |
//+------------------------------------------------------------------+
double CalculateLots(double op, double sl, ENUM_ORDER_TYPE order_type)
  {
   double lot=SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   while(true)
     {
      double pnl=0;
      if(OrderCalcProfit(order_type, _Symbol, lot, op, sl, pnl)==false)
         return lot;
      if(pnl>=0)
         return lot;
      if(pnl<-1*AccountInfoDouble(ACCOUNT_BALANCE)*risk_per_trade/100)
         return lot;
      lot+=SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
     }
   return NormalizeVolume(lot);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double NormalizeVolume(double lot)
  {
   double vol_step=SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   lot=int(lot / vol_step)*vol_step;
   if(lot>SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX))
      return SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   if(lot<SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
      return SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   return lot;

  }

double Mean()
  {
   double high[];
   double low[];
   double highest_price;
   double lowest_price;

   CopyHigh(_Symbol, PERIOD_CURRENT, 0, lookback, high);
   CopyLow(_Symbol, PERIOD_CURRENT, 0, lookback, low);

   highest_price = high[ArrayMaximum(high, 0, lookback)];
   lowest_price = low[ArrayMinimum(low, 0, lookback)];
   return (highest_price+lowest_price)/2;
  }
//+------------------------------------------------------------------+

bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
  {
//--- Getting the opening price
   MqlTick mqltick;
   SymbolInfoTick(symb,mqltick);
   double price=mqltick.ask;
   if(type==ORDER_TYPE_SELL)
      price=mqltick.bid;
//--- values of the required and free margin
   double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   //--- call of the checking function
   if(!OrderCalcMargin(type,symb,lots,price,margin))
     {
      //--- something went wrong, report and return false
      Print("Error in ",__FUNCTION__," code=",GetLastError());
      return(false);
     }
   //--- if there are insufficient funds to perform the operation
   if(margin>free_margin)
     {
      //--- report the error and return false
      Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
      return(false);
     }
//--- checking successful
   return(true);
  }
 
What makes it strange to me is that entry is well distant from exit point (although M1 is chosen)... still the simulation is wrong.
 
Yashar Seyyedin #:
What makes it strange to me is that entry is well distant from exit point (although M1 is chosen)... still the simulation is wrong.

yeah that is the weird part when thinking about it .

I mean a bullish candle can very easily hit the high line (the imaginary lookback high line) which means there will be a raise in price and the sell will go negative . 

 

the question is , is the graph going up and right describing this peculiarity of the tester (which cant do otherwise to be honest with ohlc) 

or does it mean that if the previous candle breaks the lowest of lookback period , and , it is opposite to the line it hit then the trade has potential

Because the tester peculiarity means that bullish bars that start sells are weaker than bearish bars that start sells.

However 

The comparison is not fair because the ea uses a % for entry . If measured in points it would be more accurate

 
Lorentzos Roussos #:

the question is , is the graph going up and right describing this peculiarity of the tester (which cant do otherwise to be honest with ohlc) 

At least Juan Luis knows what is incorrect now(hopefully).
 
Yashar Seyyedin #:
At least Juan Luis knows what is incorrect now(hopefully).

yeah , its not incorrect though . its the max the tester can do