//+------------------------------------------------------------------+
//|                               TradingLab_NewsSpecial_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 "News Special Institutional Straddle & Volatility Event EA"

#include <Trade/Trade.mqh>

//--- Inputs (Injected dynamically per setup)
input group "=== News Event Parameters ==="
input string   InpSymbol          = "{{SYMBOL}}";             // Trading Symbol
input string   InpTimeframe       = "{{TIMEFRAME}}";          // Execution Timeframe
input double   InpRRTarget        = {{RR_TARGET}};           // Target Risk-to-Reward Ratio (1:RR)
input double   InpSLBufferATR     = {{SL_BUFFER}};           // ATR Stop Loss Buffer Multiplier
input int      InpStraddleDistancePips = {{STRADDLE_PIPS}};  // Straddle Pending Order Distance (Pips)
input int      InpNewsWindowMins  = {{NEWS_WINDOW}};         // News Expiry Window (Minutes)
input ulong    InpMagicNumber     = 999777;                  // Magic Number

input group "=== Trailing & Risk Protection ==="
input bool     InpInstantBreakeven = true;                    // Enable Instant Momentum Breakeven
input double   InpMaxDailyLoss     = {{MAX_DAILY_LOSS}};      // Max Daily Loss ($)

//--- Global Variables
CTrade   g_trade;
int      g_handle_atr = INVALID_HANDLE;

int OnInit()
{
   g_trade.SetExpertMagicNumber(InpMagicNumber);
   g_handle_atr = iATR(_Symbol, _Period, 14);
   if(g_handle_atr == INVALID_HANDLE) {
      Print("Error initializing ATR indicator!");
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   IndicatorRelease(g_handle_atr);
}

void OnTick()
{
   double atr[]; ArraySetAsSeries(atr, true);
   if(CopyBuffer(g_handle_atr, 0, 0, 3, atr) <= 0) return;

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

   // Manage straddle trailing SL
   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 riskP = MathAbs(openP - slP);

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