EA Help Needed - Creating ex4/mq4 from Code

 

Hi - for some reason, my MT4 is not compiling. I'd be super grateful if someone could help compile this into an ex4.

Any help very gratefully received, thank you.

Love and Light


//+------------------------------------------------------------------+

//| EMA + Stochastic Trend EA with Customisable Filters (MT4)       |

//+------------------------------------------------------------------+

#property strict

 

extern int EMA_Fast = 14;

extern int EMA_Mid = 50;

extern int EMA_Trend = 200;

extern ENUM_TIMEFRAMES HTF = PERIOD_H4;

 

extern int KPeriod = 14;

extern int DPeriod = 3;

extern int Slowing = 3;

extern int StochasticOB = 80;

extern int StochasticOS = 20;

extern bool UseStochasticFilter = true;

 

extern double RiskPercent = 1.0;

extern int StopLoss = 50;

extern int TakeProfit = 100;

extern bool UseTrailingStop = true;

extern int TrailStart = 30;

extern int TrailStep = 10;

 

extern bool UsePriceBuffer = true;

extern int PriceBufferPipsBuy = 5;

extern int PriceBufferPipsSell = 5;

 

extern bool ExitOnOppositeSignal = true;

extern bool UseFixedLotSize = false;

extern double FixedLotSize = 0.01;

 

extern bool UseATRFilter = true;

extern double ATR_Threshold = 0.0007;

extern bool UseADXFilter = true;

extern int ADX_Period = 14;

extern double ADX_Threshold = 20;

extern bool UseCandleBodyFilter = true;

extern double CandleBodyRatio = 0.3;

extern bool UseEMADistanceFilter = true;

extern int EMADistancePips = 10;

 

extern int Slippage = 3;

extern int MagicNumber = 987654;

 

int OnInit() { return INIT_SUCCEEDED; }

 

double CalculateLotSize() {

    double risk = AccountBalance() * RiskPercent / 100.0;

    double slPoints = StopLoss * Point * 10;

    double lot = risk / slPoints;

    return MathMax(MarketInfo(Symbol(), MODE_MINLOT), MathMin(lot, MarketInfo(Symbol(), MODE_MAXLOT)));

}

 

double GetHTF_EMA(int period) {

    return iMA(Symbol(), HTF, period, 0, MODE_EMA, PRICE_CLOSE, 0);

}

 

void OnTick() {

    static datetime lastTime = 0;

    if (Time[0] == lastTime) return;

    lastTime = Time[0];

 

    double emaFastPrev = iMA(NULL, 0, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE, 1);

    double emaFastCurr = iMA(NULL, 0, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE, 0);

    double emaMid = iMA(NULL, 0, EMA_Mid, 0, MODE_EMA, PRICE_CLOSE, 0);

    double emaTrendHTF = GetHTF_EMA(EMA_Trend);

 

    double pricePrev = Close[1];

    double priceCurr = Close[0];

    double k = iStochastic(NULL, 0, KPeriod, DPeriod, Slowing, MODE_SMA, 0, MODE_MAIN, 0);

    double d = iStochastic(NULL, 0, KPeriod, DPeriod, Slowing, MODE_SMA, 0, MODE_SIGNAL, 0);

 

    double bufferBuy = UsePriceBuffer ? PriceBufferPipsBuy * Point * 10 : 0;

    double bufferSell = UsePriceBuffer ? PriceBufferPipsSell * Point * 10 : 0;

 

    // Filters

    if (UseATRFilter && iATR(Symbol(), 0, 14, 0) < ATR_Threshold) return;

    if (UseADXFilter && iADX(Symbol(), 0, ADX_Period, PRICE_CLOSE, MODE_MAIN, 0) < ADX_Threshold) return;

    if (UseCandleBodyFilter) {

        double body = MathAbs(Open[0] - Close[0]);

        if (body < (High[0] - Low[0]) * CandleBodyRatio) return;

    }

    if (UseEMADistanceFilter) {

        if (MathAbs(Close[0] - emaFastCurr) < EMADistancePips * Point * 10) return;

    }

 

    bool buySignal = pricePrev < emaFastPrev && priceCurr > emaFastCurr + bufferBuy &&

                     priceCurr > emaMid && priceCurr > emaTrendHTF &&

                     (!UseStochasticFilter || (k < StochasticOB && d < StochasticOB));

 

    bool sellSignal = pricePrev > emaFastPrev && priceCurr < emaFastCurr - bufferSell &&

                      priceCurr < emaMid && priceCurr < emaTrendHTF &&

                      (!UseStochasticFilter || (k > StochasticOS && d > StochasticOS));

 

    if (ExitOnOppositeSignal && OrdersTotal() > 0) {

        if (OrderSelect(0, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) {

            if (OrderType() == OP_BUY && sellSignal)

                OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrRed);

            if (OrderType() == OP_SELL && buySignal)

                OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrGreen);

        }

    }

 

    if (OrdersTotal() == 0) {

        double lot = UseFixedLotSize ? FixedLotSize : CalculateLotSize();

 

        if (buySignal) {

            double sl = Bid - StopLoss * Point * 10;

            double tp = Bid + TakeProfit * Point * 10;

            OrderSend(Symbol(), OP_BUY, lot, Ask, Slippage, sl, tp, "EMA Buy", MagicNumber, 0, clrGreen);

        }

 

        if (sellSignal) {

            double sl = Ask + StopLoss * Point * 10;

            double tp = Ask - TakeProfit * Point * 10;

            OrderSend(Symbol(), OP_SELL, lot, Bid, Slippage, sl, tp, "EMA Sell", MagicNumber, 0, clrRed);

        }

    }

 

    if (UseTrailingStop) ManageTrailingStops();

}

 

void ManageTrailingStops() {

    for (int i = OrdersTotal() - 1; i >= 0; i--) {

        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) {

            if (OrderType() == OP_BUY) {

                double newSL = Bid - TrailStep * Point * 10;

                if (Bid - OrderOpenPrice() > TrailStart * Point * 10 && OrderStopLoss() < newSL)

                    OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrAqua);

            } else if (OrderType() == OP_SELL) {

                double newSL = Ask + TrailStep * Point * 10;

                if (OrderOpenPrice() - Ask > TrailStart * Point * 10 && OrderStopLoss() > newSL)

                    OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrOrange);

            }

        }

    }

}
 

What does the error message say? As there's likely a typo on a line somewhere.

Other than that, the obvious issue (which it would compile either way) is the way you calculate lot size. You can, but it's highly recommended that you don't, use point * 10 as that's not going to work for all pairs. Ex: EUR/USD has 5 decimal points and USD/JPY has 3 which would screw up your calculations. The better way to do the calculation would be:

double CalculateLotSize() {
    if (StopLoss == 0) return 0.0; // avoid division by zero
    double risk = AccountBalance() * RiskPercent / 100.0;
    double slPoints = StopLoss * MarketInfo(Symbol(), MODE_POINT);
    double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
    double lot = risk / (slPoints * tickValue / MarketInfo(Symbol(), MODE_TICKSIZE));
    return MathMax(MarketInfo(Symbol(), MODE_MINLOT), MathMin(lot, MarketInfo(Symbol(), MODE_MAXLOT)));
}

Compiling as you've given would, on quick glance (I didn't go line by line as you should have an error message indicating the line with a problem), work but it wouldn't work well.

 
  1. Show the code, the error messages, and point to the specific lines.

  2. benedictwellstood: for some reason, my MT4 is not compiling.

    Why did you post your MT4 question in the MT5 EA section instead of the MQL4 section, (bottom of the Root page)?
              General rules and best pratices of the Forum. - General - MQL5 programming forum? (2017)
    Next time, post in the correct place. I have moved this thread.

  3.     double slPoints = StopLoss * Point * 10;

    There is no predefined variable Point in MT4 or MT5. Use the real variable or call the function.

  4.         if (OrderSelect(0, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) { 

    No select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum (2013)

 
I don't see the issue in compiling except the warning about checking the OrderSend and OrderModify. However, your CalculateLotSize() function is not correct.