VEE STRATEGY ROBOT

Specification

//+------------------------------------------------------------------+
//| M5 Trend Pullback EA |
//| Exness / MT5 |
//| Forex + XAUUSD |
//| Risk: 0.5% per trade |
//+------------------------------------------------------------------+
#property strict
#property version "1.00"
#property description "M5 EMA50/EMA200 + RSI + ATR Trend Pullback EA"

#include <Trade/Trade.mqh>

CTrade trade;

//==================================================================
// INPUTS
//==================================================================

//--- General
input ulong MagicNumber = 20260922;
input ENUM_TIMEFRAMES TradingTF = PERIOD_M5;

//--- Risk
input double RiskPercent = 0.50;
input double RewardRiskRatio = 2.00;
input double ATR_SL_Multiplier = 1.50;

//--- Indicators
input int FastEMA = 50;
input int SlowEMA = 200;
input int RSIPeriod = 14;
input int ATRPeriod = 14;

//--- Entry filters
input double RSI_Buy_Level = 50.0;
input double RSI_Sell_Level = 50.0;
input double PullbackToleranceATR = 0.50;

//--- Spread
input double MaxSpreadPoints = 40;

//--- Daily protection
input double MaxDailyLossPercent = 2.0;
input int MaxConsecutiveLosses = 3;

//--- Break-even
input bool UseBreakEven = true;
input double BreakEvenAtR = 1.0;
input double BreakEvenOffsetPoints = 5;

//--- Trading session
input bool UseSessionFilter = true;
input int StartHour = 7;
input int EndHour = 19;

//--- Execution
input int SlippagePoints = 20;

//==================================================================
// GLOBAL VARIABLES
//==================================================================

int emaFastHandle = INVALID_HANDLE;
int emaSlowHandle = INVALID_HANDLE;
int rsiHandle = INVALID_HANDLE;
int atrHandle = INVALID_HANDLE;

datetime lastBarTime = 0;

double dayStartEquity = 0.0;
int consecutiveLosses = 0;
int currentDay = -1;

//==================================================================
// INITIALIZATION
//==================================================================

int OnInit()
{
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetDeviationInPoints(SlippagePoints);

   emaFastHandle = iMA(
      _Symbol,
      TradingTF,
      FastEMA,
      0,
      MODE_EMA,
      PRICE_CLOSE
   );

   emaSlowHandle = iMA(
      _Symbol,
      TradingTF,
      SlowEMA,
      0,
      MODE_EMA,
      PRICE_CLOSE
   );

   rsiHandle = iRSI(
      _Symbol,
      TradingTF,
      RSIPeriod,
      PRICE_CLOSE
   );

   atrHandle = iATR(
      _Symbol,
      TradingTF,
      ATRPeriod
   );

   if(emaFastHandle == INVALID_HANDLE ||
      emaSlowHandle == INVALID_HANDLE ||
      rsiHandle == INVALID_HANDLE ||
      atrHandle == INVALID_HANDLE)
   {
      Print("ERROR: Failed to create indicator handles.");
      return(INIT_FAILED);
   }

   ResetDailyStats();

   Print("M5 Trend Pullback EA initialized.");
   Print("Symbol: ", _Symbol);
   Print("Risk: ", DoubleToString(RiskPercent, 2), "%");

   return(INIT_SUCCEEDED);
}

//==================================================================
// DEINITIALIZATION
//==================================================================

void OnDeinit(const int reason)
{
   if(emaFastHandle != INVALID_HANDLE)
      IndicatorRelease(emaFastHandle);

   if(emaSlowHandle != INVALID_HANDLE)
      IndicatorRelease(emaSlowHandle);

   if(rsiHandle != INVALID_HANDLE)
      IndicatorRelease(rsiHandle);

   if(atrHandle != INVALID_HANDLE)
      IndicatorRelease(atrHandle);
}

//==================================================================
// MAIN
//==================================================================

void OnTick()
{
   UpdateDailyStats();

   ManageBreakEven();

   if(!IsNewBar())
      return;

   if(!TradingAllowed())
      return;

   if(HasOpenPosition())
      return;

   if(!SpreadIsAcceptable())
      return;

   if(!SessionAllowed())
      return;

   CheckForEntry();
}

//==================================================================
// NEW BAR DETECTION
//==================================================================

bool IsNewBar()
{
   datetime currentBar = iTime(_Symbol, TradingTF, 0);

   if(currentBar == 0)
      return false;

   if(currentBar != lastBarTime)
   {
      lastBarTime = currentBar;
      return true;
   }

   return false;
}

//==================================================================
// ENTRY LOGIC
//==================================================================

void CheckForEntry()
{
   double emaFast[3];
   double emaSlow[3];
   double rsi[3];
   double atr[3];
   double closePrice[3];

   ArraySetAsSeries(emaFast, true);
   ArraySetAsSeries(emaSlow, true);
   ArraySetAsSeries(rsi, true);
   ArraySetAsSeries(atr, true);
   ArraySetAsSeries(closePrice, true);

   if(CopyBuffer(emaFastHandle, 0, 0, 3, emaFast) < 3)
      return;

   if(CopyBuffer(emaSlowHandle, 0, 0, 3, emaSlow) < 3)
      return;

   if(CopyBuffer(rsiHandle, 0, 0, 3, rsi) < 3)
      return;

   if(CopyBuffer(atrHandle, 0, 0, 3, atr) < 3)
      return;

   if(CopyClose(_Symbol, TradingTF, 0, 3, closePrice) < 3)
      return;

   // Use the LAST CLOSED candle: index 1
   double price = closePrice[1];
   double previousPrice = closePrice[2];

   double currentATR = atr[1];

   if(currentATR <= 0)
      return;

   //==============================================================
   // BUY CONDITIONS
   //==============================================================

   bool bullishTrend =
      price > emaSlow[1] &&
      emaFast[1] > emaSlow[1];

   bool pullbackBuy =
      price <= emaFast[1] + (currentATR * PullbackToleranceATR);

   bool rsiBuy =
      rsi[2] <= RSI_Buy_Level &&
      rsi[1] > RSI_Buy_Level;

   bool bullishCandle =
      price > previousPrice;

   if(bullishTrend &&
      pullbackBuy &&
      rsiBuy &&
      bullishCandle)
   {
      OpenBuy(currentATR);
      return;
   }

   //==============================================================
   // SELL CONDITIONS
   //==============================================================

   bool bearishTrend =
      price < emaSlow[1] &&
      emaFast[1] < emaSlow[1];

   bool pullbackSell =
      price >= emaFast[1] - (currentATR * PullbackToleranceATR);

   bool rsiSell =
      rsi[2] >= RSI_Sell_Level &&
      rsi[1] < RSI_Sell_Level;

   bool bearishCandle =
      price < previousPrice;

   if(bearishTrend &&
      pullbackSell &&
      rsiSell &&
      bearishCandle)
   {
      OpenSell(currentATR);
      return;
   }
}

//==================================================================
// BUY
//==================================================================

void OpenBuy(double atr)
{
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   if(ask <= 0)
      return;

   double stopDistance = atr * ATR_SL_Multiplier;

   double sl = ask - stopDistance;
   double tp = ask + (stopDistance * RewardRiskRatio);

   AdjustStopsForBroker(ORDER_TYPE_BUY, ask, sl, tp);

   double lot = CalculateLotSize(
      ORDER_TYPE_BUY,
      ask,
      sl
   );

   if(lot <= 0)
      return;

   bool result = trade.Buy(
      lot,
      _Symbol,
      ask,
      sl,
      tp,
      "M5 Trend Pullback BUY"
   );

   if(result)
   {
      Print(
         "BUY opened | Lot=",
         DoubleToString(lot, 2),
         " | SL=",
         DoubleToString(sl, _Digits),
         " | TP=",
         DoubleToString(tp, _Digits)
      );
   }
   else
   {
      Print("BUY failed. Error: ", GetLastError());
   }
}

//==================================================================
// SELL
//==================================================================

void OpenSell(double atr)
{
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   if(bid <= 0)
      return;

   double stopDistance = atr * ATR_SL_Multiplier;

   double sl = bid + stopDistance;
   double tp = bid - (stopDistance * RewardRiskRatio);

   AdjustStopsForBroker(ORDER_TYPE_SELL, bid, sl, tp);

   double lot = CalculateLotSize(
      ORDER_TYPE_SELL,
      bid,
      sl
   );

   if(lot <= 0)
      return;

   bool result = trade.Sell(
      lot,
      _Symbol,
      bid,
      sl,
      tp,
      "M5 Trend Pullback SELL"
   );

   if(result)
   {
      Print(
         "SELL opened | Lot=",
         DoubleToString(lot, 2),
         " | SL=",
         DoubleToString(sl, _Digits),
         " | TP=",
         DoubleToString(tp, _Digits)
      );
   }
   else
   {
      Print("SELL failed. Error: ", GetLastError());
   }
}

//==================================================================
// LOT SIZE CALCULATION
//==================================================================

double CalculateLotSize(
   ENUM_ORDER_TYPE orderType,
   double entryPrice,
   double stopLoss
)
{
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);

   double riskMoney =
      equity * (RiskPercent / 100.0);

   if(riskMoney <= 0)
      return 0;

   double tickSize =
      SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

   double tickValue =
      SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

   if(tickSize <= 0 || tickValue <= 0)
      return 0;

   double priceDistance =
      MathAbs(entryPrice - stopLoss);

   double ticks =
      priceDistance / tickSize;

   double lossPerLot =
      ticks * tickValue;

   if(lossPerLot <= 0)
      return 0;

   double lot =
      riskMoney / lossPerLot;

   return NormalizeVolume(lot);
}

//==================================================================
// VOLUME NORMALIZATION
//==================================================================

double NormalizeVolume(double volume)
{
   double minLot =
      SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);

   double maxLot =
      SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);

   double lotStep =
      SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   if(lotStep <= 0)
      return 0;

   volume =
      MathFloor(volume / lotStep) * lotStep;

   volume =
      MathMax(volume, minLot);

   volume =
      MathMin(volume, maxLot);

   int digits = 2;

   if(lotStep == 0.1)
      digits = 1;

   if(lotStep == 0.01)
      digits = 2;

   if(lotStep == 0.001)
      digits = 3;

   return NormalizeDouble(volume, digits);
}

//==================================================================
// OPEN POSITION CHECK
//==================================================================

bool HasOpenPosition()
{
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      ulong ticket =
         PositionGetTicket(i);

      if(ticket == 0)
         continue;

      if(!PositionSelectByTicket(ticket))
         continue;

      string symbol =
         PositionGetString(POSITION_SYMBOL);

      long magic =
         PositionGetInteger(POSITION_MAGIC);

      if(symbol == _Symbol &&
         magic == (long)MagicNumber)
      {
         return true;
      }
   }

   return false;
}

//==================================================================
// SPREAD FILTER
//==================================================================

bool SpreadIsAcceptable()
{
   double ask =
      SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   double bid =
      SymbolInfoDouble(_Symbol, SYMBOL_BID);

   if(ask <= 0 || bid <= 0)
      return false;

   double spreadPoints =
      (ask - bid) / _Point;

   if(spreadPoints > MaxSpreadPoints)
   {
      Print(
         "Spread too high: ",
         DoubleToString(spreadPoints, 1),
         " points"
      );

      return false;
   }

   return true;
}

//==================================================================
// SESSION FILTER
//==================================================================

bool SessionAllowed()
{
   if(!UseSessionFilter)
      return true;

   MqlDateTime dt;
   TimeToStruct(TimeCurrent(), dt);

   if(StartHour < EndHour)
   {
      if(dt.hour >= StartHour &&
         dt.hour < EndHour)
         return true;

      return false;
   }

   // Handles sessions crossing midnight
   if(dt.hour >= StartHour ||
      dt.hour < EndHour)
      return true;

   return false;
}

//==================================================================
// DAILY PROTECTION
//==================================================================

bool TradingAllowed()
{
   if(dayStartEquity <= 0)
      return false;

   double equity =
      AccountInfoDouble(ACCOUNT_EQUITY);

   double dailyLossPercent =
      ((dayStartEquity - equity) /
       dayStartEquity) * 100.0;

   if(dailyLossPercent >= MaxDailyLossPercent)
   {
      Print("Daily loss limit reached.");

      return false;
   }

   if(consecutiveLosses >= MaxConsecutiveLosses)
   {
      Print("Maximum consecutive losses reached.");

      return false;
   }

   return true;
}

//==================================================================
// DAILY STATS
//==================================================================

void ResetDailyStats()
{
   MqlDateTime dt;
   TimeToStruct(TimeCurrent(), dt);

   currentDay = dt.day;

   dayStartEquity =
      AccountInfoDouble(ACCOUNT_EQUITY);

   consecutiveLosses = 0;
}

void UpdateDailyStats()
{
   MqlDateTime dt;
   TimeToStruct(TimeCurrent(), dt);

   if(dt.day != currentDay)
   {
      ResetDailyStats();
   }
}

//==================================================================
// BREAK-EVEN
//==================================================================

void ManageBreakEven()
{
   if(!UseBreakEven)
      return;

   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      ulong ticket =
         PositionGetTicket(i);

      if(ticket == 0)
         continue;

      if(!PositionSelectByTicket(ticket))
         continue;

      string symbol =
         PositionGetString(POSITION_SYMBOL);

      long magic =
         PositionGetInteger(POSITION_MAGIC);

      if(symbol != _Symbol ||
         magic != (long)MagicNumber)
         continue;

      long type =
         PositionGetInteger(POSITION_TYPE);

      double openPrice =
         PositionGetDouble(POSITION_PRICE_OPEN);

      double currentSL =
         PositionGetDouble(POSITION_SL);

      double currentTP =
         PositionGetDouble(POSITION_TP);

      double currentPrice;

      if(type == POSITION_TYPE_BUY)
         currentPrice =
            SymbolInfoDouble(_Symbol, SYMBOL_BID);
      else
         currentPrice =
            SymbolInfoDouble(_Symbol, SYMBOL_ASK);

      if(currentPrice <= 0)
         continue;

      double riskDistance =
         MathAbs(openPrice - currentSL);

      if(riskDistance <= 0)
         continue;

      if(type == POSITION_TYPE_BUY)
      {
         double profitDistance =
            currentPrice - openPrice;

         if(profitDistance >=
            riskDistance * BreakEvenAtR)
         {
            double newSL =
               openPrice +
               BreakEvenOffsetPoints * _Point;

            if(currentSL < newSL)
            {
               trade.PositionModify(
                  ticket,
                  NormalizeDouble(newSL, _Digits),
                  currentTP
               );
            }
         }
      }

      if(type == POSITION_TYPE_SELL)
      {
         double profitDistance =
            openPrice - currentPrice;

         if(profitDistance >=
            riskDistance * BreakEvenAtR)
         {
            double newSL =
               openPrice -
               BreakEvenOffsetPoints * _Point;

            if(currentSL == 0 ||
               currentSL > newSL)
            {
               trade.PositionModify(
                  ticket,
                  NormalizeDouble(newSL, _Digits),
                  currentTP
               );
            }
         }
      }
   }
}

//==================================================================
// BROKER STOP LEVEL ADJUSTMENT
//==================================================================

void AdjustStopsForBroker(
   ENUM_ORDER_TYPE orderType,
   double entry,
   double &sl,
   double &tp
)
{
   long stopLevel =
      SymbolInfoInteger(
         _Symbol,
         SYMBOL_TRADE_STOPS_LEVEL
      );

   double minimumDistance =
      stopLevel * _Point;

   if(orderType == ORDER_TYPE_BUY)
   {
      if(entry - sl < minimumDistance)
         sl = entry - minimumDistance;

      if(tp - entry < minimumDistance)
         tp = entry + minimumDistance;
   }

   if(orderType == ORDER_TYPE_SELL)
   {
      if(sl - entry < minimumDistance)
         sl = entry + minimumDistance;

      if(entry - tp < minimumDistance)
         tp = entry - minimumDistance;
   }

   sl = NormalizeDouble(sl, _Digits);
   tp = NormalizeDouble(tp, _Digits);
}

//==================================================================
// TRADE TRANSACTION
//==================================================================

void OnTradeTransaction(
   const MqlTradeTransaction &trans,
   const MqlTradeRequest &request,
   const MqlTradeResult &result
)
{
   if(trans.type != TRADE_TRANSACTION_DEAL_ADD)
      return;

   ulong dealTicket = trans.deal;

   if(dealTicket == 0)
      return;

   if(!HistoryDealSelect(dealTicket))
      return;

   long magic =
      HistoryDealGetInteger(
         dealTicket,
         DEAL_MAGIC
      );

   if(magic != (long)MagicNumber)
      return;

   long entryType =
      HistoryDealGetInteger(
         dealTicket,
         DEAL_ENTRY
      );

   if(entryType != DEAL_ENTRY_OUT)
      return;

   double profit =
      HistoryDealGetDouble(
         dealTicket,
         DEAL_PROFIT
      );

   double commission =
      HistoryDealGetDouble(
         dealTicket,
         DEAL_COMMISSION
      );

   double swap =
      HistoryDealGetDouble(
         dealTicket,
         DEAL_SWAP
      );

   double netResult =
      profit + commission + swap;

   if(netResult < 0)
   {
      consecutiveLosses++;

      Print(
         "Losing trade. Consecutive losses: ",
         consecutiveLosses
      );
   }
   else if(netResult > 0)
   {
      consecutiveLosses = 0;

      Print(
         "Winning trade. Consecutive losses reset."
      );
   }
}
//+------------------------------------------------------------------+

Responded

1
Developer 1
Rating
(398)
Projects
516
23%
Arbitration
61
57% / 25%
Overdue
60
12%
Working
2
Developer 2
Rating
(1)
Projects
3
0%
Arbitration
0
Overdue
0
Working
3
Developer 3
Rating
(20)
Projects
28
39%
Arbitration
8
25% / 38%
Overdue
2
7%
Loaded
Published: 8 articles, 35 codes
4
Developer 4
Rating
(2)
Projects
2
0%
Arbitration
1
0% / 100%
Overdue
0
Free
5
Developer 5
Rating
(555)
Projects
847
61%
Arbitration
33
27% / 45%
Overdue
24
3%
Free
Published: 1 code
6
Developer 6
Rating
(258)
Projects
269
29%
Arbitration
2
50% / 0%
Overdue
3
1%
Working
Published: 2 codes
7
Developer 7
Rating
Projects
0
0%
Arbitration
0
Overdue
0
Free
8
Developer 8
Rating
(261)
Projects
307
76%
Arbitration
13
77% / 0%
Overdue
5
2%
Loaded
9
Developer 9
Rating
(9)
Projects
11
27%
Arbitration
0
Overdue
2
18%
Working
Published: 1 code
10
Developer 10
Rating
(64)
Projects
144
46%
Arbitration
21
38% / 24%
Overdue
32
22%
Free
Similar orders
Title: MQL5 EA Developer Needed — EUR/USD 15M Scalping Robot (1:1 RR, Rule-Based) Platform: MetaTrader 5 (MQL5) Description: Looking for an experienced MQL5 developer to build a fully automated Expert Advisor for EUR/USD on the 15-minute timeframe. The strategy is a rule-based pullback scalp system with a fixed 1:1 risk/reward ratio, EMA-based trend filtering, session-time restrictions (London open + London/NY
Please may someone assist me with the indicator attached, it has a SERIOUS BUG issue in the sense that when I load it, and activate the template (attached as well) MT4 ALWAYS freezes and then eventually disconnects automatically, ALL THE TIME. It even gets worse to an extent that after disconnecting a number of times mt4 ends up not loading anymore, UNTIL I remove the indicator. Please I WILL NEED A DEMO (FOR A DAY)
I need a MetaTrader 5 (MT5) custom indicator specifically designed for fast scalping on the M5 timeframe for volatile assets like XAUUSD, US30, and BTCUSD. I am based in the UAE (GMT+4). The indicator must run silently in the background and send Mobile Push Notifications and Pop-Up Alerts ONLY. Absolutely NO lines, boxes, objects, or graphic panels should be drawn or left on the trading chart. Core Requirements: 1
I need a skilled and experienced programmer, who is sincere and communicates effectively, to debug my pre-built indicator and EA for me: Bugs to fix - EA & Indicator 1. Fixed lot size not working properly 2. SL too tight 3. Grid not working properly - toggled. When Grid is off, single entries and default inputs apply. 4. Grid starting fixed lot - toggled. When off, ATR lot applies 5. Grid distance - fixed position 6
I’m looking for someone with experience developing Expert Advisors for MetaTrader 5, particularly someone who has a strong understanding of arbitrage, mean reversion, multi-pair trading, and simultaneous order execution. I’m looking to develop an MT5 EA based on a triangular arbitrage strategy that identifies price discrepancies between three related currency pairs and automatically executes trades when the
I am looking for an experienced MQL5 developer to build a fully automated MT5 Expert Advisor for XAUUSD. The trading rules are already defined. I need the developer to implement them accurately in MQL5, not redesign the strategy. Main requirements: XAUUSD Multi-timeframe logic: H1 direction, M15 setup, M5 entry Entry only after candle-close confirmation No repainting / closed-bar logic Configurable Stop Loss and Take
I have an existing order-flow engine for NinjaTrader 8, approximately 25,000 lines of C# code, currently using Rithmic Level 2 data. It detects absorption, iceberg orders, and other order-flow signals. We have also developed an initial bridge prototype ourselves and tested parts of the R|Trader Pro to NinjaTrader connection workflow, but we have not yet established a working MBO data connection. I am specifically
Hi, I have developed an MT5 Expert Advisor called SRX which latest version is R24b47 , and I am looking for an experienced MQL5/MT5 EA developer to perform a thorough technical investigation, fixing and optimization of the EA. 1. The main problem SRX is not stable across different market periods . It can perform extremely well during one period, but the same EA/configuration can perform very poorly or approach Margin
LynxMT5algo 30 - 100 USD
An mt5 add on indicator like gainalgo style to show entrance and exit areas for gold silver and Btc scalping. It will be used to make trading more easy for beginners
I need a professional AI-assisted Forex trading Expert Advisor (EA) for MetaTrader 5. The EA should not be based on a simple single indicator strategy. I want a robust multi-factor trading system that can analyze market conditions, trend, momentum, volatility, price action and risk before entering a trade. Requirements: Forex trading on MT5 Automated analysis and trade execution Dynamic entry and exit decisions Stop

Project information

Budget
30 - 200 USD
Deadline
from 10 to 60 day(s)

Customer

Placed orders1
Arbitrage count0