How to define

 

EA with 1 moving average.

When have 2 closing bars above moving average to buy.

When have 2 closing bars below moving average to sell

 

When have 2 closing bars above moving average to buy.

double ima1,ima2 ;

ima1 = iMA(Symbol(),0,0,0,MODE_SMA,PRICE_CLOSE,1) ;

ima2 = iMA(Symbol(),0,0,0,MODE_SMA,PRICE_CLOSE,2) ; 

if( (Close[2]>ima2) && (Close[1]>ima1) {//Do actions }

More info about moving average parameters https://docs.mql4.com/indicators/iMA

 

Is it ok

//+------------------------------------------------------------------+
//| Check for open order conditions |
//+------------------------------------------------------------------+
void CheckForOpen()
{
double ima1,ima2;
int res;
//---- go trading only for first tiks of new bar
if(Volume[0]>1) return;
//---- get Moving Average
ima1=iMA(NULL,0,100,0,MODE_SMA,PRICE_CLOSE,1);
ima2=iMA(NULL,0,100,0,MODE_SMA,PRICE_CLOSE,2);
//---- sell conditions
if(Close[2]<ima2) && (Close[1]<ima1)
{
res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",BURLYANOV,0,Red);
return;
}
//---- buy conditions
if(Close[2]>ima2) && (Close[1]>ima1)
{
res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",BURLYANOV,0,Blue);
return;
}
//----
}
//+------------------------------------------------------------------+
//| Check for close order conditions |
//+------------------------------------------------------------------+
void CheckForClose()
{
double ima1,ima2;
//---- go trading only for first tiks of new bar
if(Volume[0]>1) return;
//---- get Moving Average
ima1=iMA(NULL,0,100,0,MODE_SMA,PRICE_CLOSE,1);
ima2=iMA(NULL,0,100,0,MODE_SMA,PRICE_CLOSE,2);
//----
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderMagicNumber()!=BURLYANOV || OrderSymbol()!=Symbol()) continue;
//---- check order type
if(OrderType()==OP_BUY)
{
if(Close[2]<ima2) && (Close[1]<ima1) OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
break;
}
if(OrderType()==OP_SELL)
{
if(Close[2]>ima2) && (Close[1]>ima1) OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
break;
}
}
//----
}
 
//+------------------------------------------------------------------+
//| 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);
//---- sell conditions
if(Open[1]>ma && Close[1]<ma) continue; //Where does execution continue to - we are not in a loop ?
if(Open[2]>ma && Close[2]<ma)
{
res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",BURLYANOV,0,Red);
return;
}
//---- buy conditions
if(Open[1]<ma && Close[1]>ma) continue;
if(Open[2]<ma && Close[2]>ma)
{
res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",BURLYANOV,0,Blue);
return;
}
//----
}
 

  1. if(Volume[0]>1) return;
    Volume is unreliable, always use time
        static datetime Time0;
        if (Time0 != Time[0]){   Time0 = Time[0];
        ...
        }
    

  2. for(int i=0;i<OrdersTotal();i++)
    You must count down in the presence of multiple orders (multiple charts)
    for(int pos=OrdersTotal() -1; pos >= 0; pos--) if (
       OrderSelect(pos,SELECT_BY_POS)
    && OrderMagicNumber() ==BURLYANOV
    && OrderSymbol()      ==Symbol()){
    

  3. if(Open[1]>ma && Close[1]<ma) continue; //Where does execution continu to - we are not in a loop ?
  4. EAs should adjust for 5 digit brokers, TP, SL, and slippage
    //++++ These are adjusted for 5 digit brokers.
    double  pips2points,    // slippage  3 pips    3=points    30=points
            pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
    int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
    int     init(){
        if (Digits == 5 || Digits == 3){    // Adjust for five (5) digit brokers.
                    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
        } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }
        // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
    

 
 
I'm not define Stop Loss order, please help me to define him. And percent of balance in deal - lot size calculations
 
//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                                      Copyright © 2011, Burlyanov | |
//+------------------------------------------------------------------+
#define BURLYANOV  20050610

extern double Lots               = 0.1;
extern double MaximumRisk        = 0.05;
extern double MovingPeriod       = 100;
//+------------------------------------------------------------------+
//| 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()==BURLYANOV)
        {
         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                                       |
//+------------------------------------------------------------------+
extern double LotPercent = 5.0 // mean 5.0%
//-- pass variable
double LotSize;

void LotsCalc() 
   {
   if(MarketInfo(Symbol(),MODE_MINLOT) == 0.1) int LotsDigit = 1;
   else if(MarketInfo(Symbol(),MODE_MINLOT) == 0.01) LotsDigit = 2;
   double MinLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MINLOT),LotsDigit);
   double MaxLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MAXLOT),LotsDigit);
   double AcFrMar = NormalizeDouble(AccountFreeMargin(),2);
   
   LotSize = (AcFrMar*(LotsPercent/100))/1000;
   
   if(LotSize > MaxLots) LotSize = MaxLots;
   if(LotSize < MinLots) LotSize = MinLots; 
   }
//+------------------------------------------------------------------+
//| 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,100,0,MODE_SMA,PRICE_CLOSE,0); 
//---- sell conditions
   if(Open[1]>ma && Close[1]<ma) continue;
   if(Open[2]<ma && Close[2]<ma)
     {
      res=OrderSend(Symbol(),OP_SELL,LotSize(),Bid,3,0,0,"",BURLYANOV,0,Red);
      return;
     }
//---- buy conditions
   if(Open[1]<ma && Close[1]>ma) continue;
   if(Open[2]>ma && Close[2]>ma) 
     {
      res=OrderSend(Symbol(),OP_BUY,LotSize(),Ask,3,0,0,"",BURLYANOV,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,100,0,MODE_SMA,PRICE_CLOSE,0);
//----
   for(int pos=OrderTotal() -1; pos >=0; pos--)
     {
      if(OrderSelect(,SELECT_BY_POS,MODE_TRADES)==false)        break;
      if(OrderMagicNumber()==BURLYANOV || OrderSymbol()==Symbol()) continue;
      //---- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma) continue;
         if(Open[2]<ma && Close[2]<ma)
         OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma) continue;
         if(Open[2]>ma && Close[2]>ma) 
         OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         break;
        }
     }
//----
  }
//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
void start()
  {
//---- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false) return;
//---- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//----
  }

 
//+------------------------------------------------------------------+
//| Lot size computation.                                            |
//+------------------------------------------------------------------+
void    OnInitLotSize(){
    at.risk.equity = 0; at.risk.total = 0;  at.risk.chart = 0;  }
double  LotSize(double risk){
/*double    at.risk.new;                        // Export to init/start
//double    TEF.value,                          // Import from ComputeTEF
//          at.risk.equity                      // \  Import from
//double    at.risk.chart,      at.risk.total;      // _> ModifyStops
//int       op.code; // OP_BUY/OP_SELL          // Import from SetDIR */
    /* This function computes the lot size for a trade.
     * Explicit inputs are SL relative to bid/ask (E.G. SL=30*points,)
     * Implicit inputs are the MM mode, the MM multiplier, count currently
     * filled orders by all EA's vs this EA/pair/period count and history.
     * Implicit inputs are all used to reduce available balance the maximum
     * dollar risk allowed. StopLoss determines the maximum dollar risk possible
     * per lot. Lots=maxRisk/maxRiskPerLot
     **************************************************************************/
    /*++++ Compute lot size based on account balance and MM mode*/{
    double  ab  = AccountBalance() - at.risk.equity;
    switch(MM.F0M1G2){
    case MMMODE_FIXED:                                              double
        perChrt = MM.PerChart,
        maxRisk = MM.MaxRisk;
        break;
    case MMMODE_MODERATE:
        // See https://www.mql5.com/en/articles/1526 Fallacies, Part 1: Money
        // Management is Secondary and Not Very Important.
        maxRisk = MathSqrt(MM.MaxRisk  * ab);
        perChrt = MathSqrt(MM.PerChart * ab);
        break;
    case MMMODE_GEOMETRICAL:
        perChrt = MM.PerChart * ab;
        maxRisk = MM.MaxRisk  * ab;
        break;
    }
    ComputeTEF();
    double  minLot  = MarketInfo(Symbol(), MODE_MINLOT),
            lotStep = MarketInfo(Symbol(), MODE_LOTSTEP),
            perLotPerPoint  = PointValuePerLot(),
            maxLossPerLot   = (risk+Slippage.Pips*pips2dbl) * perLotPerPoint,
            size = perChrt / maxLossPerLot; // Must still round to lotStep.
    /*---- Compute lot size based on account balance and MM mode*/}
    /* The broker doesn't care about the at.risk/account balance. They care
     * about margin. Margin used=lots used*marginPerLot and that must be less
     * than free margin available. Using the lesser of size vs
     * AccountFreeMargin / MODE_MARGINREQUIRED should have been sufficient, but
     * the tester was generating error 134 even when marginFree should have been
     * OK. So I also use AccountFreeMarginCheck < 0 which agrees with the
     * tester. Reported at https://forum.mql4.com/35056
     *
     * Second problem, after opening the new order, if free margin then drops to
     * zero we get a margin call. In the tester, the test stops with: "EA:
     * stopped because of Stop Out" So I make sure that the free margin
     * after is larger then the equity risk so I never get a margin call. */
    string status = "SL>AE";                            // Assume size < minLot
    while (true){   // Adjust for broker, test for margin, combine with TEF...
        size = MathFloor(MathMax(0,size)/lotStep)*lotStep;
        at.risk.new = size * maxLossPerLot;             // Export for Comment
        if (size < minLot){ at.risk.new = 0;    EA.status = status; return(0); }

        /* at.risk.equity  += Direction( OrderType() )
         *                  * (OrderClosePrice()-OrderStopLoss())*perPoint;
         * Summed for all open orders.
         * at.risk.total is summed for all open orders below Break even.
         * at.risk.chart is summed for all open orders below BE, this pair/TF */
        if (at.risk.new+at.risk.chart > perChrt){           // one pair, one TF
            size = (perChrt-at.risk.chart)/maxLossPerLot;   // Re-adjust lotStep
            status = "MaxRisk";     continue;   }

        if (at.risk.new+at.risk.total > maxRisk){           // All charts
            size = (maxRisk-at.risk.total)/maxLossPerLot;
            status = "TotalRisk";   continue;   }

        double  AFMC    = AccountFreeMarginCheck(Symbol(), op.code, size),
                eRisk   = at.risk.equity + at.risk.new;
        if (AFMC*0.99 <= eRisk){
            size *= 0.95;   status = "Free Margin";
            continue;   }   // Prevent margin call if new trade goes against us.
        break;
    }
    if (TEF.Enable01>0){
        size = MathFloor(size*MathMin(1, TEF.value)/lotStep)*lotStep;
        if (oo.count == 0 && size < minLot) size = minLot;  // Not below min
        at.risk.new = size * maxLossPerLot;                 // Export for Comment
        if (size < minLot){ at.risk.new=0;  EA.status = "TEF = "+TEF.value;
                                                                    return(0); }
    }
    return(size);   // We're good to go.
}   // LotSize
double  PointValuePerLot() { // Value in account currency of a Point of Symbol.
    /* In tester I had a sale: open=1.35883 close=1.35736 (0.00147)
     * gain$=97.32/6.62 lots/147 points=$0.10/point or $1.00/pip.
     * IBFX demo/mini       EURUSD TICKVALUE=0.1 MAXLOT=50 LOTSIZE=10,000
     * IBFX demo/standard   EURUSD TICKVALUE=1.0 MAXLOT=50 LOTSIZE=100,000
     *                                  $1.00/point or $10.00/pip.
     *
     * https://forum.mql4.com/33975 CB: MODE_TICKSIZE will usually return the
     * same value as MODE_POINT (or Point for the current symbol), however, an
     * example of where to use MODE_TICKSIZE would be as part of a ratio with
     * MODE_TICKVALUE when performing money management calculations which need
     * to take account of the pair and the account currency. The reason I use
     * this ratio is that although TV and TS may constantly be returned as
     * something like 7.00 and 0.00001 respectively, I've seen this
     * (intermittently) change to 14.00 and 0.00002 respectively (just example
     * tick values to illustrate). */
    return(  MarketInfo(Symbol(), MODE_TICKVALUE)
           / MarketInfo(Symbol(), MODE_TICKSIZE) ); // Not Point.
}
 

EA based on 1SMA, no stop loss, no limit

When have 2 closing price above ma - buy, 2 closing price below - sell

Enter - each deal - 5% of balance. Example: 1000$ balance * 5% = 50 margin sum.

Below i post what i've done, errors and mistakes is everywhere.

Please help, i'm a newbie.

Thanks

 
//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                                            Copyright © 2011, BRO |
//+------------------------------------------------------------------+
#define BRO  20050610

extern double Lots               = 0.1;
extern double MovingPeriod       = 100;
extern double MinLot             = 0.1;
extern double MaxLot             = 5.0;
extern int LotPrecent            = 5;
extern bool DynamicLot           = false;
extern double LotStep            = 0.01;
extern double BalanceStep        = 500;

//+------------------------------------------------------------------+
//| 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()==BRO)
        {
         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 GetLots()
  {
   double lot=Lots
   if (DynamicLot=true)
   {
    lots = NormalizeDouble(LotStep*AccountBalance()/BalanceStep, LotPrecent);  
   }
   lots = MathMax(lots, MinLot);
   lots = MathMin(lots, MaxLot);
   return (lots);
  }
//+------------------------------------------------------------------+
//| 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,0,MODE_SMA,PRICE_CLOSE,0); 
//---- sell conditions
   if(Open[1]>ma && Close[1]<ma) return;
   if(Open[2]<ma && Close[2]<ma);
     {
      res=OrderSend(Symbol(),OP_SELL, GetLots(),Bid,3,0,0,"",BROV,0,Red);
      return;
     }
//---- buy conditions
   if(Open[1]<ma && Close[1]>ma) return;
   if(Open[2]>ma && Close[2]>ma);
     {
      res=OrderSend(Symbol(),OP_BUY,GetLots(),Ask,3,0,0,"",BRO,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,0,MODE_SMA,PRICE_CLOSE,0);
//----
   for(int pos=OrderTotal() -1; pos >=0; pos--)
     {
      if(OrderSelect(,SELECT_BY_POS,MODE_TRADES)==false)        break;
      if(OrderMagicNumber()==BRO || OrderSymbol()==Symbol()) continue;
      //---- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma) continue;
         if(Open[2]<ma && Close[2]<ma);
         OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma) continue;
         if(Open[2]>ma && Close[2]>ma); 
         OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         break;
        }
     }
//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
void start()
  {
//---- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false) return;
//---- calculate open orders by current symbol
   {
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else(CalculateCurrentOrders(Symbol())==0 CheckForClose();
   }
   return(0);
  }
Reason: