EA using a DEMA indicator

 

Dear Forum,

I've found a DEMA working Indicator, that's working really good by using this code:

Working Indicator with DEMA

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//---- inputs
extern int MA_Period  = 9;
//--- buffers
double EMA[],EMAEMA[],DEMA[];
//+------------------------------------------------------------------+
int init()
{
 IndicatorBuffers(3);
 SetIndexBuffer(2,EMA);
 SetIndexBuffer(1,EMAEMA);
 SetIndexBuffer(0,DEMA);
 IndicatorShortName("DEMA ("+MA_Period+")");
 return(0);
}
//+------------------------------------------------------------------+
int start()
{
 int  i,  counted_bars=IndicatorCounted();
 int  limit=Bars-1,   begin=limit-1;
 double wt = 2.0/(MA_Period+1);
//----
 if(counted_bars==0)
 {
  EMA[limit]=Close[limit];
  EMAEMA[limit]=Close[limit];
  DEMA[limit]=Close[limit];
 }
//----
 i=Bars-1-counted_bars;
 if(i>=begin)i=begin;
 while(i>=0)
 {
  EMA[i] = Close[i]*wt+EMA[i+1]*(1-wt);
  EMAEMA[i] = EMA[i]*wt+EMAEMA[i+1]*(1-wt);
  DEMA[i]=2*EMA[i]-EMAEMA[i];
  i--;
 } 
 return(0);
}

Then I've tryed to integrate it into a basic EA by creating the DEMA() function, 
but this EA doesn't working, but the mql text documentations I see some problem related with the pass from Indicator to EA
this is the code of the EA:
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"
#property description "Moving Average sample expert advisor"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//---- inputs
extern int MA_Period  = 9;
//--- buffers
double EMA[],EMAEMA[],DEMA[];
#define MAGICMA  20131111
//--- Inputs
input double Lots          =0.1;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =9;
input int    MovingShift   =0;
extern int PERIOD  =12;
//---- indicator buffer


void init(){
 IndicatorBuffers(3);
 SetIndexBuffer(2,EMA);
 SetIndexBuffer(1,EMAEMA);
 SetIndexBuffer(0,DEMA);
 IndicatorShortName("DEMA ("+MA_Period+")");
 return(0);
}



//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//--- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//--- calcuulate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
           {
            Print("Error in history!");
            break;
           }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
            continue;
         //---
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma;
   int    res;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
//   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);

   ma=DEMA();
//--- sell conditions
   if(Open[1]>ma && Close[1]<ma)
     {
      res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//--- buy conditions
   if(Open[1]<ma && Close[1]>ma)
     {
      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double ma;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
//   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
   
   ma=DEMA();
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      //--- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma) OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma)
            OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         break;
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//---
  }
//+------------------------------------------------------------------+


// DEMA - Double Exponential Moving Average by Patrick Mulloy
double DEMA()
{
 int  i,  counted_bars=IndicatorCounted();
 int  limit=Bars-1,   begin=limit-1;
 double wt = 2.0/(MA_Period+1);
//----
 if(counted_bars==0)
 {
  EMA[limit]=Close[limit];
  EMAEMA[limit]=Close[limit];
  DEMA[limit]=Close[limit];
 }
//----
 i=Bars-1-counted_bars;
 if(i>=begin)i=begin;
 while(i>=0)
 {
  EMA[i] = Close[i]*wt+EMA[i+1]*(1-wt);
  EMAEMA[i] = EMA[i]*wt+EMAEMA[i+1]*(1-wt);
  DEMA[i]=2*EMA[i]-EMAEMA[i];
  i--;
 } 
 return DEMA;
}

Can someone indicate me how to adapt and correctly execute this EA with the DEMA custom function indicator instead of with the standard EMA function?

thak to all for the help

Giuseppe
 
Your post is difficult to read as you write your comment within the source code.
 

If I understand you correctly, you are trying to use indicator code in an EA complete with buffers

This will not work as you expect.

Use iCustom to call the indicator.

 

I post here the EA dema based that is not working:


#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"
#property description "Moving Average sample expert advisor"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//---- inputs
extern int MA_Period  = 9;
//--- buffers
double EMA[],EMAEMA[],DEMA[];
#define MAGICMA  20131111
//--- Inputs
input double Lots          =0.1;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =9;
input int    MovingShift   =0;
extern int PERIOD  =12;
//---- indicator buffer


void init(){
 IndicatorBuffers(3);
 SetIndexBuffer(2,EMA);
 SetIndexBuffer(1,EMAEMA);
 SetIndexBuffer(0,DEMA);
 IndicatorShortName("DEMA ("+MA_Period+")");
 return(0);
}



//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//--- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//--- calcuulate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
           {
            Print("Error in history!");
            break;
           }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
            continue;
         //---
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma;
   int    res;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
//   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);

   ma=DEMA();
//--- sell conditions
   if(Open[1]>ma && Close[1]<ma)
     {
      res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//--- buy conditions
   if(Open[1]<ma && Close[1]>ma)
     {
      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double ma;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
//   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
   
   ma=DEMA();
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      //--- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma) OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma)
            OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         break;
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//---
  }
//+------------------------------------------------------------------+


// DEMA - Double Exponential Moving Average by Patrick Mulloy
double DEMA()
{
 int  i,  counted_bars=IndicatorCounted();
 int  limit=Bars-1,   begin=limit-1;
 double wt = 2.0/(MA_Period+1);
//----
 if(counted_bars==0)
 {
  EMA[limit]=Close[limit];
  EMAEMA[limit]=Close[limit];
  DEMA[limit]=Close[limit];
 }
//----
 i=Bars-1-counted_bars;
 if(i>=begin)i=begin;
 while(i>=0)
 {
  EMA[i] = Close[i]*wt+EMA[i+1]*(1-wt);
  EMAEMA[i] = EMA[i]*wt+EMAEMA[i+1]*(1-wt);
  DEMA[i]=2*EMA[i]-EMAEMA[i];
  i--;
 } 
 return DEMA;
}
 

The method DEMA() is a custom indicator that out of the EA was working good only as indicator

 
giuseppeloddo:
Then I've tryed to integrate it into a basic EA by creating the DEMA() function, 
Can someone indicate me how to adapt and correctly 
  1. Because only an indicator can use
    =IndicatorCounted();
  2. You DO NOT "integrate it into a EA" You get the values of the indicator using iCustom. Detailed explanation of iCustom - MQL4 forum



 
WHRoeder:
  1. Because only an indicator can use
  2. You DO NOT "integrate it into a EA" You get the values of the indicator using iCustom. Detailed explanation of iCustom - MQL4 forum




thank you!
 

Now it works!


the results changes basing on the period and on the time based used.


//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              https://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"
#property description "Moving Average sample expert advisor"
double EMA[],EMAEMA[],DEMA[];
#define MAGICMA  20131111
//--- Inputs
input double Lots          =0.1;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =14;
input int    MovingShift   =0;
extern int PERIOD  =14;
//---- indicator buffer

//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//--- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//--- calcuulate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
           {
            Print("Error in history!");
            break;
           }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
            continue;
         //---
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma;
   int    res;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
//   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);

 ma=iCustom(NULL,0,"DEMA",9,0,0);
//--- sell conditions
   if(Open[1]>ma && Close[1]<ma)
     {
      res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//--- buy conditions
   if(Open[1]<ma && Close[1]>ma)
     {
      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double ma;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
//   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
   
   ma=iCustom(NULL,0,"DEMA",MovingPeriod,0,0);
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      //--- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma) OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma)
            OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         break;
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//---
  }
//+------------------------------------------------------------------+


this code works, any suggestion for improve it's efficiency?

 
giuseppeloddo:

Now it works!


the results changes basing on the period and on the time based used.



this code works, any suggestion for improve it's efficiency?

is the LotsOptimized func in the Moving Average MT4 sample EA even sane?
Do more testing run it also on Demo and see it is not running like strategytester

Reason: