//+------------------------------------------------------------------+
//|                                 TradingLab_EMACross_EA.mq5     |
//|                     Copyright 2026, Trading Lab Precision Suite |
//|                                      https://localhost:8080/    |
//+------------------------------------------------------------------+
#property copyright "Trading Lab Precision Suite"
#property link      "https://localhost:8080/"
#property version   "1.20"
#property description "EMA Crossover Special Institutional Momentum Expert Advisor"

#include <Trade/Trade.mqh>

//--- Inputs (Injected dynamically per setup)
input group "=== EMA Crossover Parameters ==="
input string   InpSymbol          = "{{SYMBOL}}";             // Trading Symbol
input string   InpTimeframe       = "{{TIMEFRAME}}";          // Execution Timeframe
input int      InpFastEMA         = {{FAST_EMA}};            // Fast EMA Period
input int      InpSlowEMA         = {{SLOW_EMA}};            // Slow EMA Period
input int      InpTrendEMA        = {{TREND_EMA}};           // Trend EMA Filter Period
input double   InpRRTarget        = {{RR_TARGET}};           // Target Risk-to-Reward Ratio (1:RR)
input double   InpSLBufferATR     = {{SL_BUFFER}};           // ATR Stop Loss Buffer Multiplier
input ulong    InpMagicNumber     = 999666;                  // Magic Number

enum ENUM_EMA_TRAIL {
   TRAIL_BE_HALF,     // Breakeven @ 50% TP
   TRAIL_BE_15R,      // Breakeven @ +1.5R
   TRAIL_DYNAMIC      // Dynamic ATR Trailing
};

input group "=== Risk & Trailing Management ==="
input ENUM_EMA_TRAIL InpTrailMode = {{TRAIL_MODE}};
input double InpMaxDailyLoss       = {{MAX_DAILY_LOSS}};      // Max Daily Loss ($)
input double InpFixedLot           = 0.01;                    // Trade Lot Size

//--- Global Variables
CTrade   g_trade;
int      g_handle_fast = INVALID_HANDLE;
int      g_handle_slow = INVALID_HANDLE;
int      g_handle_trend = INVALID_HANDLE;
int      g_handle_atr = INVALID_HANDLE;

int OnInit()
{
   g_trade.SetExpertMagicNumber(InpMagicNumber);
   g_handle_fast  = iMA(_Symbol, _Period, InpFastEMA, 0, MODE_EMA, PRICE_CLOSE);
   g_handle_slow  = iMA(_Symbol, _Period, InpSlowEMA, 0, MODE_EMA, PRICE_CLOSE);
   g_handle_trend = iMA(_Symbol, _Period, InpTrendEMA, 0, MODE_EMA, PRICE_CLOSE);
   g_handle_atr   = iATR(_Symbol, _Period, 14);

   if(g_handle_fast == INVALID_HANDLE || g_handle_slow == INVALID_HANDLE || g_handle_atr == INVALID_HANDLE) {
      Print("Error initializing EMA indicators!");
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   IndicatorRelease(g_handle_fast);
   IndicatorRelease(g_handle_slow);
   if(g_handle_trend != INVALID_HANDLE) IndicatorRelease(g_handle_trend);
   IndicatorRelease(g_handle_atr);
}

void OnTick()
{
   double fastBuf[]; ArraySetAsSeries(fastBuf, true);
   double slowBuf[]; ArraySetAsSeries(slowBuf, true);
   double atrBuf[];  ArraySetAsSeries(atrBuf, true);

   if(CopyBuffer(g_handle_fast, 0, 0, 3, fastBuf) <= 0) return;
   if(CopyBuffer(g_handle_slow, 0, 0, 3, slowBuf) <= 0) return;
   if(CopyBuffer(g_handle_atr, 0, 0, 3, atrBuf) <= 0) return;

   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   // Active position management
   for(int i = PositionsTotal() - 1; i >= 0; i--) {
      if(PositionGetTicket(i) > 0 && PositionGetInteger(POSITION_MAGIC) == InpMagicNumber) {
         double openP = PositionGetDouble(POSITION_PRICE_OPEN);
         double slP   = PositionGetDouble(POSITION_SL);
         double tpP   = PositionGetDouble(POSITION_TP);
         long dir     = PositionGetInteger(POSITION_TYPE);
         double targetDist = MathAbs(tpP - openP);

         if(dir == POSITION_TYPE_BUY && bid >= openP + 0.5 * targetDist && slP < openP) {
            g_trade.PositionModify(PositionGetTicket(i), openP + 0.1, tpP);
         } else if(dir == POSITION_TYPE_SELL && ask <= openP - 0.5 * targetDist && slP > openP) {
            g_trade.PositionModify(PositionGetTicket(i), openP - 0.1, tpP);
         }
         return;
      }
   }

   bool bullCross = (fastBuf[2] <= slowBuf[2]) && (fastBuf[1] > slowBuf[1]);
   bool bearCross = (fastBuf[2] >= slowBuf[2]) && (fastBuf[1] < slowBuf[1]);

   if(bullCross) {
      double sl = ask - InpSLBufferATR * atrBuf[0];
      double risk = ask - sl;
      double tp = ask + InpRRTarget * risk;
      g_trade.Buy(InpFixedLot, _Symbol, ask, sl, tp, "EMA Cross Buy");
   }
   else if(bearCross) {
      double sl = bid + InpSLBufferATR * atrBuf[0];
      double risk = sl - bid;
      double tp = bid - InpRRTarget * risk;
      g_trade.Sell(InpFixedLot, _Symbol, bid, sl, tp, "EMA Cross Sell");
   }
}
