//+------------------------------------------------------------------+
//|                                PTL ATR Strategy EA (MT4).mq4      |
//|                                   Based on Post 34 Strategy Rules |
//|                        COMPLETE MT5→MT4 CONVERSION - MASTERPIECE  |
//+------------------------------------------------------------------+
#property copyright "PTL ATR Strategy - Post 34 - MT4 Twin"
#property link      ""
#property version   "6.00"
#property strict

//+------------------------------------------------------------------+
//| Input Parameters                                                  |
//+------------------------------------------------------------------+

//--- Indicator Settings
input string IndSettings = "===== Indicator Settings =====";
input int    ATR_Periods = 100;              // ATR Periods
input int    ATR_MA_Periods = 55;            // ATR MA Periods
input int    ATR_MA_Type = MODE_SMMA;        // ATR MA Type
input double ATR_Mult1 = 2.5; // Inner Band
input double ATR_Mult2 = 4.5; // Middle Band
input double ATR_Mult3 = 6.5; // Outer Band
input int    PTL_SlowLength = 7;             // PTL Slow Length
input int    PTL_FastLength = 3;             // PTL Fast Length

//--- Trade Settings
input string TradeSettings = "===== Trade Settings =====";
input int    StopLossPips = 150;             // Stop Loss (Pips)
input bool   UseTakeProfit = false;          // Use Take Profit?
input int    TakeProfitPips = 300;           // Take Profit (Pips) - if enabled
input bool   UseLocalSwingSL = false;        // Use Local Swing SL?
input int    SwingLookbackBars = 7;          // Swing Lookback Bars
input double SwingBufferPips = 3.0;          // Swing Buffer (Pips)
input double MinimumSLPips = 5.0;           // Minimum SL Distance (Pips)

//--- Exit Settings
input string ExitSettings = "===== Exit Settings =====";
input bool   UseBandExit = true;             // Use Band Exit?
input bool   BandExitOnWick = true;         // Band Exit on Wick (not just close)?
input bool   UseSameDotExit = true;          // Use Same Dot Exit?

//--- Money Management
input string MMSettings = "===== Money Management =====";
enum MM_TYPE
{
   MM_FIXED_LOT,      // Fixed Lot Size
   MM_RISK_PERCENT,   // Risk Percentage
   MM_FIXED_AMOUNT    // Fixed Dollar Amount
};
input MM_TYPE MoneyManagementType = MM_FIXED_LOT;  // Money Management Type
input double  FixedLotSize = 0.01;                 // Fixed Lot Size
input double  RiskPercent = 1.0;                   // Risk Percent (%)
input double  FixedRiskAmount = 100.0;             // Fixed Risk Amount ($)

//--- Trading Control
input string ControlSettings = "===== Trading Control =====";
//--- Aroon Filter Settings
input string AroonSettings = "===== Aroon Filter Settings =====";
input bool   UseAroonFilter = false;         // Use Aroon Trend Filter?
input int    AroonPeriod = 14;               // Aroon Period

input bool   OneTradeAtATime = false;         // Only One Trade at a Time?
input bool   TradeLong = true;               // Trade Long (Buy)?
input bool   TradeShort = true;              // Trade Short (Sell)?
input int    MagicNumber = 123456;           // Magic Number
input string TradeComment = "PTL_ATR";       // Trade Comment
input bool   CloseFriday = true;             // Close All on Friday?
input string FridayCloseTime = "23:55";      // Friday Close Time (HH:MM)

//--- Consecutive Loss Protection
input string LossProtectionSettings = "===== Loss Protection =====";
input bool   UseConsecutiveLossFilter = false;     // Use Consecutive Loss Filter?
input int    MaxConsecutiveLosses = 2;            // Max Consecutive Losses

// Lockout Type Selection
enum LOCKOUT_TYPE
{
   LOCKOUT_TIME_BASED,      // Time-Based Lockout
   LOCKOUT_HTF_DOT,         // Higher Timeframe Dot Confirmation
   LOCKOUT_HYBRID           // Hybrid (Time OR HTF Dot - whichever first)
};
input LOCKOUT_TYPE LockoutType = LOCKOUT_TIME_BASED;  // Lockout Type
input int    LockoutHours = 4;                    // Max Lockout Hours (Time/Hybrid)
input int    HTF_Timeframe = PERIOD_M15;          // Higher Timeframe for Dot Confirmation
input bool   ClosePositionsOnLockout = true;     // Close Existing Positions on Lockout?

//--- Visualization Settings
input string VisSettings = "===== Visualization Settings =====";
input bool   ShowATRBands = true;            // Show ATR Bands?
input bool   ShowPTLLines = false;            // Show PTL Lines?
input bool   ShowPTLArrows = true;           // Show PTL Arrows?
input bool   ShowTradeInfo = true;           // Show Trade Info Panel?

// Drawing Mode Selection
enum DRAWING_MODE
{
   DRAWING_ROLLING_WINDOW,      // Rolling Window (Proximity Zone)
   DRAWING_ACCUMULATE_ALL,      // Accumulate Everything (Full History)
   DRAWING_ACCUMULATE_LIMITED   // Accumulate with Limits
};
input DRAWING_MODE DrawingMode = DRAWING_ACCUMULATE_LIMITED; // Drawing Mode
input int    DrawBarsBack = 100;            // Rolling Window Size (bars)
input int    MaxDrawingObjects = 50000;      // Max Objects (Limited Mode)
input int    MaxDrawingDays = 14;            // Max Days to Keep (Limited Mode)

input color  ATR_MidlineColor = clrRed;    // ATR Midline Color
input color  ATR_BandColor = clrGold;        // ATR Band Color
input int    ATR_LineWidth = 2;              // ATR Line Width
input color  PTL_SlowColor = clrPaleVioletRed; // PTL Slow Line Color
input color  PTL_FastColor = clrLimeGreen;   // PTL Fast Line Color
input int    PTL_LineWidth = 1;              // PTL Line Width
input int    ArrowCodeUp = 159;              // Arrow Code Up (Green)
input int    ArrowCodeDown = 159;            // Arrow Code Down (Pink)
input color  ArrowUpColor = clrLimeGreen;    // Arrow Up Color
input color  ArrowDownColor = clrPaleVioletRed; // Arrow Down Color
input int    ArrowSize = 2;                  // Arrow Size
input int    EntryArrowOffset = 10;          // Entry Arrow Offset (pips from dot)
input color  ExitWinColor = clrWhite;        // Exit Win Marker Color (Checkmark)
input color  ExitLossColor = clrRed;         // Exit Loss Marker Color (X - SL only)

//--- Trade Connection Lines
input string TradeLineSettings = "===== Trade Connection Lines =====";
input bool   ShowTradeLines = true;          // Show Entry-to-Exit Lines?

// Line Coloring Mode
enum LINE_COLOR_MODE
{
   COLOR_BY_DIRECTION,    // Color by Direction (BUY/SELL)
   COLOR_BY_OUTCOME       // Color by Outcome (Win/Loss/SL)
};
input LINE_COLOR_MODE LineColorMode = COLOR_BY_OUTCOME; // Line Coloring Mode

// Direction-based colors (when COLOR_BY_DIRECTION)
input color  BuyLineColor = clrWhite;        // BUY Trade Line Color
input color  SellLineColor = clrRed;         // SELL Trade Line Color

// Outcome-based colors (when COLOR_BY_OUTCOME)
input color  WinLineColor = clrWhite;    // Winning Trade Line Color
input color  SmallLossLineColor = clrOrange; // Small Loss Line Color
input color  SLLossLineColor = clrRed;       // Stop Loss Hit Line Color

// Line Style
input int    TradeLineWidth = 2;             // Trade Line Width
input int    TradeLineStyle = STYLE_SOLID;    // Trade Line Style

//--- Same Color Dot Lockout Settings
input string SameColorLockoutSettings = "===== Same Color Dot Lockout =====";
input bool   UseSameColorDotLockout = false;           // Use Same Color Dot Lockout?
input bool   UseZoneLockout = false;                    // Use Zone SL Lockout? (locks zone after SL hit, unlocks on dot+close in next outer zone)

// Lockout Activation Mode Selection
enum LOCKOUT_ACTIVATION_MODE
{
   ACTIVATE_IMMEDIATE,           // Activate When Dot Appears Outside Bands
   ACTIVATE_AFTER_SL_HIT         // Activate After Stop Loss Hit
};
input LOCKOUT_ACTIVATION_MODE LockoutActivationMode = ACTIVATE_AFTER_SL_HIT;  // Lockout Activation Mode

// Immediate Mode Settings (only used when ACTIVATE_IMMEDIATE selected)
input bool   TakeActivationTrade = false;              // [Immediate] Take the Activation Trade?

// SL-Based Mode Settings (only used when ACTIVATE_AFTER_SL_HIT selected)
input bool   SL_RequireFirstTrade = false;              // [SL Mode] Only First Trade SL Triggers Lockout?
input bool   SL_CloseAllTrades = false;                // [SL Mode] Close All Same-Color Trades on Lockout?

// Common Settings (apply to both modes)
input bool   TradeUnlockSignal = false;                // Trade the Unlock Signal?
input bool   WholeBarUnlock = true;                    // Require ENTIRE Bar Inside Bands to Unlock?
input bool   ShowSameColorLockoutZones = false;        // Show Lockout Zones on Chart?
input color  GreenLockoutColor = clrDarkGreen;         // GREEN Lockout Zone Color
input color  PinkLockoutColor = clrDarkRed;            // PINK Lockout Zone Color
input int    SameColorLockoutMaxHours = 24;            // Max Lockout Hours (0=unlimited)

//--- Daily Trading Hours
input string DailyHoursSettings = "===== Daily Trading Hours =====";
input bool   UseDailyTradingHours = false;          // Enable Daily Trading Hours?
input string DailyStartTime = "01:00";              // Daily Start Time (Broker Time HH:MM)
input string DailyStopTime = "20:00";               // Daily Stop Time (Broker Time HH:MM)
input bool   CloseTradesAtDailyStop = false;         // Close All Trades at Stop Time?
input bool   AllowExitsDuringStopTime = true;       // Allow Exit Signals During Stop Time?

//--- Daily Profit/Loss Limits
input string DailyLimitSettings = "===== Daily Profit/Loss Limits =====";
input bool   UseDailyLimits = false;                     // Enable Daily P/L Limits?
input double DailyLossLimit = 100.0;                     // Daily Loss Limit ($) - 0 = disabled
input double DailyProfitTarget = 200.0;                 // Daily Profit Target ($) - 0 = disabled

// What happens when limit is hit?
enum DAILY_LIMIT_ACTION
{
   LIMIT_STOP_NEW_ONLY,       // Stop New Trades Only (let existing run)
   LIMIT_CLOSE_ALL            // Close All Positions Immediately
};
input DAILY_LIMIT_ACTION LimitAction = LIMIT_CLOSE_ALL;  // Action When Limit Hit

// When does the "day" reset?
enum DAILY_RESET_MODE
{
   RESET_BROKER_MIDNIGHT,     // Broker Server Midnight (00:00)
   RESET_CUSTOM_TIME          // Custom Time (specify below)
};
input DAILY_RESET_MODE ResetMode = RESET_BROKER_MIDNIGHT; // Daily Reset Mode
input string CustomResetTime = "00:00";                   // Custom Reset Time (if Custom Mode)

// P/L Calculation Options
input bool   CountFloatingPL = true;                      // Include Open Positions in Daily P/L?
input bool   CountSwapAndCommission = true;               // Include Swap/Commission in P/L?

// Alert Options
input bool   AlertOnLimitHit = true;                      // Show Alert When Limit Hit?
input bool   PlaySoundOnLimit = true;                     // Play Sound on Limit Hit?
input string LimitHitSoundFile = "alert2.wav";            // Sound File for Limit Hit
input bool   SendEmailOnLimit = false;                    // Send Email When Limit Hit?
input bool   SendPushOnLimit = false;                     // Send Push Notification on Limit?

// Display Options
input bool   ShowDailyPLInPanel = true;                   // Show Daily P/L in Info Panel?
input color  DailyProfitColor = clrLimeGreen;             // Daily Profit Display Color
input color  DailyLossColor = clrRed;                     // Daily Loss Display Color
input color  DailyWarningColor = clrOrange;               // Warning Zone Color (80% of limit)

//--- Pip Detection Settings
input string PipSettings = "===== Pip Detection Settings =====";
input bool   UseAutoPipDetection = true;           // Use Intelligent Pip Detection?
// ────────────────────────────────────────────────────────────────────────────────
// PIP VALUE OVERRIDE - Sets ABSOLUTE pip values for specific symbols
// 
// How to use:
//   Format: "SYMBOL1:VALUE, SYMBOL2:VALUE"
//   Example: "XAUUSD:0.1, BTCUSD:1.0, EURUSD:0.0001"
// 
// What it does:
//   - XAUUSD:0.1  = Each pip = $0.10 (so 150 pips SL = $15 distance)
//   - XAUUSD:1.0  = Each pip = $1.00 (so 15 pips SL = $15 distance)
//   - BTCUSD:10   = Each pip = $10.00 (so 2 pips SL = $20 distance)
// 
// When to use:
//   - If auto-detection is wrong for your broker's symbol naming
//   - To simplify: use "1.0" to make "1 pip" = "1 dollar" of price movement
//   - Leave EMPTY ("") to use automatic detection
// ────────────────────────────────────────────────────────────────────────────────
input string PipValueOverrides = "";                // Absolute Pip Value Overrides (replaces auto-detection)
input bool   ShowPipDetectionInfo = true;           // Show Pip Info in Log?

//+------------------------------------------------------------------+
//| Global Variables                                                  |
//+------------------------------------------------------------------+

//--- Arrays for ATR Channels (embedded logic)
double atrMA[];
double atrUpperBand[];
double atrLowerBand[];

double atrUpper1[], atrLower1[];
double atrUpper2[], atrLower2[];
double atrUpper3[], atrLower3[];

//--- Arrays for PTL Indicator (embedded logic)
double ptlLine1[];      // Slow line
double ptlLine2[];      // Fast line
double ptlTrend[];      // Trend state
double ptlTrena[];      // Trend alternate
double ptlArrowUp[];    // Green dots (BUY)
double ptlArrowDown[];  // Pink dots (SELL)

//--- Higher Timeframe Arrays
double htfAtrMA[];
double htfAtrUpperBand[];
double htfAtrLowerBand[];
double htfPtlLine1[];
double htfPtlLine2[];
double htfPtlTrend[];
double htfPtlTrena[];
double htfPtlArrowUp[];
double htfPtlArrowDown[];

//--- Aroon Arrays
double aroonUp[];       // Aroon Up values (0-100)
double aroonDown[];     // Aroon Down values (0-100)

datetime lastBarTime = 0;
bool newBarFlag = false;

// Drawing tracking
datetime lastDrawnBarTime = 0;
int totalDrawnObjects = 0;
datetime oldestDrawnBarTime = 0;

// Consecutive Loss Tracking
int consecutiveLosses = 0;
datetime lockoutStartTime = 0;
bool inLockout = false;
int lastKnownPositionsCount = 0;
int lockoutDirection = -1;  // Track which direction caused lockout (OP_BUY or OP_SELL)
datetime lastHTFBarTime = 0;

// Same Color Dot Lockout Tracking
bool greenDotLockoutActive = false;   // GREEN dot lockout status (legacy/same-color mode)
bool pinkDotLockoutActive = false;    // PINK dot lockout status (legacy/same-color mode)
datetime greenLockoutStartTime = 0;   // When GREEN lockout started
datetime pinkLockoutStartTime = 0;    // When PINK lockout started

// Zone-based SL lockout system (new)
// Stores which zone is locked out: 0=none, -1 to -4=buy zone locked, +1 to +4=sell zone locked
int greenZoneLockout = 0;   // Buy-side zone that triggered lockout (negative zone number, 0=none)
int pinkZoneLockout  = 0;   // Sell-side zone that triggered lockout (positive zone number, 0=none)

// SL-Based Activation Tracking
int greenFirstTradeTicket = 0;        // Ticket of first GREEN trade in sequence
int pinkFirstTradeTicket = 0;         // Ticket of first PINK trade in sequence
bool greenSequenceActive = false;     // Is GREEN sequence currently running?
bool pinkSequenceActive = false;      // Is PINK sequence currently running?

// Time tracking
bool wasInTradingHours = true;

// Panel optimization tracking
datetime lastPanelUpdate = 0;
bool panelNeedsFullRedraw = true;

// For tracking entry dot color
#define MAGIC_BUY_GREEN  MagicNumber + 1  // Entered with green dot
#define MAGIC_SELL_PINK  MagicNumber + 2  // Entered with pink dot

//+------------------------------------------------------------------+
//| 💰 DAILY PROFIT/LOSS LIMIT TRACKING                              |
//+------------------------------------------------------------------+

// Current trading day tracking
datetime currentTradingDay = 0;           // Date of current trading day
datetime lastDailyResetTime = 0;          // When we last reset daily counters

// Daily P/L tracking
double todayClosedPL = 0;                 // Today's realized P/L (closed trades)
double todayFloatingPL = 0;               // Today's unrealized P/L (open positions)
double todayTotalPL = 0;                  // Total daily P/L (closed + floating)
int todayTradeCount = 0;                  // Number of trades opened today
int todayClosedCount = 0;                 // Number of trades closed today

// Limit status flags
bool dailyLossLimitHit = false;           // True if loss limit reached
bool dailyProfitTargetHit = false;        // True if profit target reached
datetime limitHitTime = 0;                // When limit was hit (for logging)

// Trade tracking for daily reset
datetime lastProcessedTradeCloseTime = 0; // Last closed trade we processed
int lastKnownHistoryTotal = 0;            // For detecting new closed trades

//+------------------------------------------------------------------+
//| 🎨 MASTERPIECE PANEL - Constants & Configuration                 |
//+------------------------------------------------------------------+

// Panel Dimensions
#define PANEL_X 15
#define PANEL_Y 25
#define PANEL_WIDTH 280
#define PANEL_PADDING 12
#define SECTION_SPACING 8
#define LINE_HEIGHT 18
#define SEPARATOR_HEIGHT 1

// Colors
#define PANEL_BG_COLOR C'20,25,35'
#define PANEL_BORDER_COLOR clrGold
#define HEADER_COLOR clrGold
#define SUBHEADER_COLOR clrWhite
#define TEXT_COLOR clrSilver
#define SUCCESS_COLOR clrLimeGreen
#define WARNING_COLOR clrOrange
#define ERROR_COLOR clrRed
#define DISABLED_COLOR clrDimGray
#define SEPARATOR_COLOR C'50,55,65'

// Section Structure
struct PanelSection
{
   string name;
   int startY;
   int height;
   bool visible;
   bool needsUpdate;
};

// Global Panel State
PanelSection sections[10];
int totalSections = 0;
int currentPanelHeight = 0;
string panelPrefix = "PTL_MP_";  // MasterPiece prefix

// Update frequency control
int panelTickCounter = 0;
datetime lastFullPanelRedraw = 0;

//+------------------------------------------------------------------+
//| 🎯 Advanced Pip Detection System - Global Variables              |
//+------------------------------------------------------------------+

// Pip override storage
struct PipOverride
{
   string symbol;
   double pipValue;  // Changed from 'multiplier' to 'pipValue'
};

PipOverride pipOverrides[];
int totalPipOverrides = 0;

// Detected pip value (cached)
double detectedPipValue = 0;
bool pipValueCached = false;

//+------------------------------------------------------------------+
//| Structure to store entry data for quick lookup                   |
//+------------------------------------------------------------------+
struct TradeEntryData
{
   int positionTicket;
   datetime entryTime;
   double entryPrice;
   int orderType;
   int magic;
   bool wasOutOfBounds;
   int entryZone;  
};

// Array to store active positions
TradeEntryData activePositions[];

// Unique prefix for drawing objects
string objPrefix = "PTL_ATR_EA_";

//+------------------------------------------------------------------+
//| Check if ticket is the first trade AND sequence is valid         |
//+------------------------------------------------------------------+
bool IsFirstTradeOfSequence(int ticket, int orderType)
{
   int firstTicket = 0;
   bool sequenceActive = false;
   
   if(orderType == OP_BUY)
   {
      firstTicket = greenFirstTradeTicket;
      sequenceActive = greenSequenceActive;
   }
   else if(orderType == OP_SELL)
   {
      firstTicket = pinkFirstTradeTicket;
      sequenceActive = pinkSequenceActive;
   }
   
   // Validation checks
   if(firstTicket == 0) return false;           // No first ticket set
   if(!sequenceActive) return false;            // Sequence not active
   if(ticket != firstTicket) return false;      // Not the first ticket
   
   return true;
}

//+------------------------------------------------------------------+
//| Get count of active same-color trades                            |
//+------------------------------------------------------------------+
int GetSameColorTradesCount(int orderType)
{
   int count = 0;
   
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      if(OrderType() == orderType)
         count++;
   }
   
   return count;
}

//+------------------------------------------------------------------+
//| Close all trades of a specific color                             |
//+------------------------------------------------------------------+
void CloseAllSameColorTrades(int orderType)
{
   Print("═══════════════════════════════════════════════");
   Print("🔒 CLOSING ALL ", (orderType == OP_BUY ? "GREEN" : "PINK"), " DOT TRADES");
   
   int closedCount = 0;
   
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      if(OrderType() == orderType)
      {
         Print("   Closing #", OrderTicket());
         CloseTrade(OrderTicket());
         closedCount++;
      }
   }
   
   Print("   Total Closed: ", closedCount);
   Print("═══════════════════════════════════════════════");
}

//+------------------------------------------------------------------+
//| Activate Same Color Lockout (SL-Based Mode)                      |
//+------------------------------------------------------------------+
void ActivateSLBasedLockout(int orderType)
{
   if(orderType == OP_BUY)
   {
      greenDotLockoutActive = true;
      greenLockoutStartTime = TimeCurrent();
      greenSequenceActive = false;
      greenFirstTradeTicket = 0;
      
      Print("═══════════════════════════════════════════════");
      Print("🔒 GREEN DOT LOCKOUT ACTIVATED (SL Hit)");
      Print("   Activation Mode: STOP LOSS");
      Print("   Lockout Start: ", TimeToString(greenLockoutStartTime));
      Print("═══════════════════════════════════════════════");
      
      DrawSameColorLockoutZone(true);
   }
   else if(orderType == OP_SELL)
   {
      pinkDotLockoutActive = true;
      pinkLockoutStartTime = TimeCurrent();
      pinkSequenceActive = false;
      pinkFirstTradeTicket = 0;
      
      Print("═══════════════════════════════════════════════");
      Print("🔒 PINK DOT LOCKOUT ACTIVATED (SL Hit)");
      Print("   Activation Mode: STOP LOSS");
      Print("   Lockout Start: ", TimeToString(pinkLockoutStartTime));
      Print("═══════════════════════════════════════════════");
      
      DrawSameColorLockoutZone(false);
   }
   
   panelNeedsFullRedraw = true;
   SaveStateToGlobalVariables();
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Set arrays as series (MQ4 style indexing)
   ArraySetAsSeries(atrMA, true);
   ArraySetAsSeries(atrUpperBand, true);
   ArraySetAsSeries(atrLowerBand, true);
   ArraySetAsSeries(atrUpper1, true);
   ArraySetAsSeries(atrLower1, true);
   ArraySetAsSeries(atrUpper2, true);
   ArraySetAsSeries(atrLower2, true);
   ArraySetAsSeries(atrUpper3, true);
   ArraySetAsSeries(atrLower3, true);
   
   ArraySetAsSeries(ptlLine1, true);
   ArraySetAsSeries(ptlLine2, true);
   ArraySetAsSeries(ptlTrend, true);
   ArraySetAsSeries(ptlTrena, true);
   ArraySetAsSeries(ptlArrowUp, true);
   ArraySetAsSeries(ptlArrowDown, true);
   
   ArraySetAsSeries(aroonUp, true);
   ArraySetAsSeries(aroonDown, true);
   
   // Set HTF arrays as series
   if(UseConsecutiveLossFilter && (LockoutType == LOCKOUT_HTF_DOT || LockoutType == LOCKOUT_HYBRID))
   {
      ArraySetAsSeries(htfAtrMA, true);
      ArraySetAsSeries(htfAtrUpperBand, true);
      ArraySetAsSeries(htfAtrLowerBand, true);
      ArraySetAsSeries(htfPtlLine1, true);
      ArraySetAsSeries(htfPtlLine2, true);
      ArraySetAsSeries(htfPtlTrend, true);
      ArraySetAsSeries(htfPtlTrena, true);
      ArraySetAsSeries(htfPtlArrowUp, true);
      ArraySetAsSeries(htfPtlArrowDown, true);
   }
   
   Print("PTL ATR Strategy EA (MT4 MASTERPIECE) initialized successfully");
   Print("ATR Periods: ", ATR_Periods, " | MA Periods: ", ATR_MA_Periods);
   Print("PTL Slow: ", PTL_SlowLength, " | PTL Fast: ", PTL_FastLength);
   Print("StopLoss: ", StopLossPips, " pips");
   if(UseLocalSwingSL)
   {
      Print("Local Swing SL: ENABLED");
      Print("  Lookback: ", SwingLookbackBars, " bars");
      Print("  Buffer: ", SwingBufferPips, " pips");
      Print("  Minimum: ", MinimumSLPips, " pips");
   }
   else
   {
      Print("Local Swing SL: DISABLED (using fixed SL)");
   }
   Print("Money Management: ", EnumToString(MoneyManagementType));
   
   // Initialize Pip Detection System
   Print("═══════════════════════════════════════════════");
   Print("🎯 INITIALIZING PIP DETECTION SYSTEM");
   
   ParsePipOverrides();
   
   double pipVal = GetPipValue();
   // Detailed info already printed in GetPipValue() if ShowPipDetectionInfo = true
   
   Print("═══════════════════════════════════════════════");
   
   // Initialize entry data storage
   ArrayResize(activePositions, 0);
   Print("Entry data storage initialized");
   
   //═══════════════════════════════════════════════════════════════
   // 🔥 NEW: RESTART RECOVERY SYSTEM
   //═══════════════════════════════════════════════════════════════
   Print("═══════════════════════════════════════════════");
   Print("🔄 RESTART RECOVERY: Scanning for existing positions...");
   
   int recoveredPositions = RecoverExistingPositions();
   
   if(recoveredPositions > 0)
   {
      Print("✅ RECOVERED ", recoveredPositions, " existing position(s)");
      Print("   Entry data restored from open orders");
   }
   else
   {
      Print("ℹ️ No existing positions to recover (clean start)");
   }
   
   // Restore consecutive loss state from global variables
   if(GlobalVariableCheck("PTL_ConsecutiveLosses"))
   {
      consecutiveLosses = (int)GlobalVariableGet("PTL_ConsecutiveLosses");
      Print("📊 RESTORED Consecutive Losses: ", consecutiveLosses);
   }
   
   if(GlobalVariableCheck("PTL_InLockout"))
   {
      inLockout = (GlobalVariableGet("PTL_InLockout") > 0);
      if(inLockout)
      {
         lockoutStartTime = (datetime)GlobalVariableGet("PTL_LockoutStartTime");
         lockoutDirection = (int)GlobalVariableGet("PTL_LockoutDirection");
         Print("🔒 RESTORED Lockout State:");
         Print("   Start Time: ", TimeToString(lockoutStartTime));
         Print("   Direction: ", (lockoutDirection == OP_BUY ? "BUY" : "SELL"));
      }
   }
   
   // Restore same color lockout states
   if(GlobalVariableCheck("PTL_GreenLockout"))
   {
      greenDotLockoutActive = (GlobalVariableGet("PTL_GreenLockout") > 0);
      if(greenDotLockoutActive)
      {
         greenLockoutStartTime = (datetime)GlobalVariableGet("PTL_GreenLockoutTime");
         Print("🟢 RESTORED Green Dot Lockout: ", TimeToString(greenLockoutStartTime));
      }
   }
   
   if(GlobalVariableCheck("PTL_PinkLockout"))
   {
      pinkDotLockoutActive = (GlobalVariableGet("PTL_PinkLockout") > 0);
      if(pinkDotLockoutActive)
      {
         pinkLockoutStartTime = (datetime)GlobalVariableGet("PTL_PinkLockoutTime");
         Print("🔴 RESTORED Pink Dot Lockout: ", TimeToString(pinkLockoutStartTime));
      }
   }
   if(GlobalVariableCheck("PTL_GreenZoneLockout"))
      greenZoneLockout = (int)GlobalVariableGet("PTL_GreenZoneLockout");
   if(GlobalVariableCheck("PTL_PinkZoneLockout"))
      pinkZoneLockout = (int)GlobalVariableGet("PTL_PinkZoneLockout");
   if(greenZoneLockout != 0) Print("🟢 RESTORED Green Zone Lockout: Zone ", greenZoneLockout);
   if(pinkZoneLockout  != 0) Print("🔴 RESTORED Pink Zone Lockout: Zone ", pinkZoneLockout);
   // Restore SL-based lockout sequence tracking
   if(GlobalVariableCheck("PTL_GreenSequenceActive"))
   {
      greenSequenceActive = (GlobalVariableGet("PTL_GreenSequenceActive") > 0);
      if(greenSequenceActive)
      {
         greenFirstTradeTicket = (int)GlobalVariableGet("PTL_GreenFirstTicket");
         Print("🟢 RESTORED Green Sequence: Active | First Ticket: ", greenFirstTradeTicket);
      }
   }
   
   if(GlobalVariableCheck("PTL_PinkSequenceActive"))
   {
      pinkSequenceActive = (GlobalVariableGet("PTL_PinkSequenceActive") > 0);
      if(pinkSequenceActive)
      {
         pinkFirstTradeTicket = (int)GlobalVariableGet("PTL_PinkFirstTicket");
         Print("🔴 RESTORED Pink Sequence: Active | First Ticket: ", pinkFirstTradeTicket);
      }
   }
   
    // ═══════════════════════════════════════════════════════════════
   // 💰 RESTORE DAILY PROFIT/LOSS LIMIT STATE
   // ═══════════════════════════════════════════════════════════════
   if(UseDailyLimits)
   {
      RestoreDailyLimitState();
   }
   
   Print("═══════════════════════════════════════════════");
   //═══════════════════════════════════════════════════════════════
   
   // Print drawing mode info
   Print("═══════════════════════════════════════════════");
   Print("Drawing Mode: ", EnumToString(DrawingMode));
   if(DrawingMode == DRAWING_ROLLING_WINDOW)
   {
      Print("  Rolling Window: ", DrawBarsBack, " bars");
   }
   else if(DrawingMode == DRAWING_ACCUMULATE_ALL)
   {
      Print("  Full History: Everything will be kept");
   }
   else if(DrawingMode == DRAWING_ACCUMULATE_LIMITED)
   {
      Print("  Max Objects: ", MaxDrawingObjects);
      Print("  Max Days: ", MaxDrawingDays);
   }
   Print("═══════════════════════════════════════════════");
   
   if(UseConsecutiveLossFilter)
   {
      Print("Consecutive Loss Filter: Enabled");
      Print("Lockout Type: ", EnumToString(LockoutType));
      Print("Max Losses: ", MaxConsecutiveLosses);
      if(LockoutType == LOCKOUT_TIME_BASED || LockoutType == LOCKOUT_HYBRID)
         Print("Lockout Hours: ", LockoutHours);
      if(LockoutType == LOCKOUT_HTF_DOT || LockoutType == LOCKOUT_HYBRID)
         Print("HTF Timeframe: ", HTF_Timeframe);
      Print("Close on Lockout: ", (ClosePositionsOnLockout ? "Yes" : "No"));
   }
   
   // Initialize position tracking
   lastKnownPositionsCount = GetOpenTradesCount();
   
   // Initialize drawing tracking
   totalDrawnObjects = 0;
   oldestDrawnBarTime = 0;
   lastDrawnBarTime = 0;
   
   // Initialize entry data storage
   ArrayResize(activePositions, 0);
   Print("Entry data storage initialized");
   
   // Aroon Filter Info
   if(UseAroonFilter)
   {
      Print("═══════════════════════════════════════════════");
      Print("Aroon Trend Filter: ENABLED");
      Print("Aroon Period: ", AroonPeriod);
      Print("═══════════════════════════════════════════════");
   }
   else
   {
      Print("Aroon Trend Filter: DISABLED");
   }
   
   // Same Color Dot Lockout Info
   greenDotLockoutActive = false;
   pinkDotLockoutActive = false;
   greenLockoutStartTime = 0;
   pinkLockoutStartTime = 0;
   greenZoneLockout = 0;
   pinkZoneLockout = 0;
   
   if(UseSameColorDotLockout)
   {
      Print("═══════════════════════════════════════════════");
      Print("Same Color Dot Lockout: ENABLED");
      
      // 🔥 NEW: Show activation mode
      Print("Activation Mode: ", EnumToString(LockoutActivationMode));
      
      if(LockoutActivationMode == ACTIVATE_IMMEDIATE)
      {
         Print("   Take Activation Trade: ", (TakeActivationTrade ? "YES" : "NO"));
      }
      else if(LockoutActivationMode == ACTIVATE_AFTER_SL_HIT)
      {
         Print("   Require First Trade SL: ", (SL_RequireFirstTrade ? "YES" : "NO"));
         Print("   Close All Trades on Lockout: ", (SL_CloseAllTrades ? "YES" : "NO"));
         
         // 🔥 NEW: Initialize sequence tracking for SL mode
         if(!greenDotLockoutActive)
         {
            greenSequenceActive = false;
            greenFirstTradeTicket = 0;
         }
         if(!pinkDotLockoutActive)
         {
            pinkSequenceActive = false;
            pinkFirstTradeTicket = 0;
         }
      }
      
      Print("Trade Unlock Signal: ", (TradeUnlockSignal ? "YES" : "NO"));
      Print("Unlock Condition: ", (WholeBarUnlock ? "WHOLE Bar Inside Bands" : "Close Inside Bands"));
      Print("Max Lockout Hours: ", (SameColorLockoutMaxHours == 0 ? "Unlimited" : IntegerToString(SameColorLockoutMaxHours)));
      Print("═══════════════════════════════════════════════");
   }
   else
   {
      Print("Same Color Dot Lockout: DISABLED");
   }
   
   // Daily Trading Hours Info
   if(UseDailyTradingHours)
   {
      Print("═══════════════════════════════════════════════");
      Print("⏰ Daily Trading Hours: ENABLED");
      Print("Trading Window: ", DailyStartTime, " - ", DailyStopTime, " (Broker Time)");
      Print("Close at Stop Time: ", (CloseTradesAtDailyStop ? "YES" : "NO"));
      Print("Allow Exits During Stop: ", (AllowExitsDuringStopTime ? "YES" : "NO"));
      Print("═══════════════════════════════════════════════");
   }
   else
   {
      Print("Daily Trading Hours: DISABLED (24/5 trading)");
   }
   
   // Daily P/L Limits Info
   if(UseDailyLimits)
   {
      Print("═══════════════════════════════════════════════");
      Print("💰 Daily Profit/Loss Limits: ENABLED");
      if(DailyLossLimit > 0)
         Print("   Loss Limit: -", DoubleToString(DailyLossLimit, 2), " ", AccountCurrency());
      if(DailyProfitTarget > 0)
         Print("   Profit Target: +", DoubleToString(DailyProfitTarget, 2), " ", AccountCurrency());
      Print("   Action on Limit: ", (LimitAction == LIMIT_CLOSE_ALL ? "Close All Positions" : "Stop New Trades Only"));
      Print("   Reset Mode: ", (ResetMode == RESET_BROKER_MIDNIGHT ? "Broker Midnight" : "Custom Time (" + CustomResetTime + ")"));
      Print("   Count Floating P/L: ", (CountFloatingPL ? "YES" : "NO"));
      Print("   Count Swap/Commission: ", (CountSwapAndCommission ? "YES" : "NO"));
      Print("   Alerts: ", (AlertOnLimitHit ? "ON" : "OFF"));
      Print("═══════════════════════════════════════════════");
   }
   else
   {
      Print("Daily Profit/Loss Limits: DISABLED");
   }
   
   // Initialize tracking - set lastBarTime to current bar so first tick 
   // doesn't falsely trigger CheckForEntry on a historical bar[1] signal
   lastBarTime = Time[0];
   wasInTradingHours = CanTradeNow();
   
   // Initial calculation and drawing
   Print("Performing initial calculation and drawing...");
   if(CalculateATRChannels() && CalculatePTL())
   {
      DrawInitialWindow();
      ChartRedraw();
      Print("Initial drawing complete!");
   }
   else
   {
      Print("Warning: Initial calculation failed - will retry on first tick");
   }
   
   // 🔥 NEW: Scan for missed trades after restart
   Print("🔍 Scanning history for missed trades...");
   ScanHistoryForMissedTrades();
   
   // Force initial panel draw
   panelNeedsFullRedraw = true;
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up all panel objects
   int totalObjects = ObjectsTotal();
   
   for(int i = totalObjects - 1; i >= 0; i--)
   {
      string objName = ObjectName(i);
      
      if(StringFind(objName, panelPrefix) == 0)
      {
         ObjectDelete(objName);
      }
   }
   
   // Clean up all drawn objects
   CleanupDrawings();
   
   // Clear entry data storage
   ArrayFree(activePositions);
   
   Print("PTL ATR Strategy EA (MT4 MASTERPIECE) deinitialized");
}

//+------------------------------------------------------------------+
//| 💰 Check if we need to reset daily counters                      |
//+------------------------------------------------------------------+
void CheckDailyReset()
{
   datetime currentTime = TimeCurrent();
   datetime resetTime = 0;
   
   // Determine reset time based on mode
   if(ResetMode == RESET_BROKER_MIDNIGHT)
   {
      // Reset at broker midnight (00:00)
      MqlDateTime dt;
      TimeToStruct(currentTime, dt);
      dt.hour = 0;
      dt.min = 0;
      dt.sec = 0;
      resetTime = StructToTime(dt);
   }
   else
   {
      // Reset at custom time
      int resetHour, resetMin;
      if(!ParseTimeString(CustomResetTime, resetHour, resetMin))
      {
         // Fallback to midnight if parse fails
         resetHour = 0;
         resetMin = 0;
      }
      
      MqlDateTime dt;
      TimeToStruct(currentTime, dt);
      dt.hour = resetHour;
      dt.min = resetMin;
      dt.sec = 0;
      resetTime = StructToTime(dt);
      
      // If custom time already passed today, use tomorrow's reset time
      if(currentTime < resetTime)
         resetTime -= 86400; // Yesterday's reset
   }
   
   // Check if we've crossed a reset boundary
   if(currentTradingDay == 0 || currentTime >= resetTime + 86400)
   {
      // Calculate which trading day we're in
      datetime newTradingDay = resetTime;
      if(currentTime >= resetTime + 86400)
         newTradingDay = resetTime + 86400;
      
      if(currentTradingDay != newTradingDay)
      {
         // NEW TRADING DAY!
         Print("═══════════════════════════════════════════════");
         Print("📅 NEW TRADING DAY STARTED");
         Print("   Previous Day: ", TimeToString(currentTradingDay, TIME_DATE));
         Print("   New Day: ", TimeToString(newTradingDay, TIME_DATE));
         if(currentTradingDay > 0)
         {
            Print("   Previous Day Final P/L: ", FormatMoney(todayTotalPL, true));
            Print("   Previous Day Trades: ", todayClosedCount);
         }
         Print("═══════════════════════════════════════════════");
         
         // Reset counters
         currentTradingDay = newTradingDay;
         lastDailyResetTime = currentTime;
         todayClosedPL = 0;
         todayFloatingPL = 0;
         todayTotalPL = 0;
         todayTradeCount = 0;
         todayClosedCount = 0;
         dailyLossLimitHit = false;
         dailyProfitTargetHit = false;
         limitHitTime = 0;
         
         // Save state
         SaveDailyLimitState();
         
         // Force panel redraw
         panelNeedsFullRedraw = true;
      }
   }
}

//+------------------------------------------------------------------+
//| 💰 Calculate today's closed trades P/L                           |
//+------------------------------------------------------------------+
double CalculateTodayClosedPL()
{
   double totalPL = 0;
   int tradesCount = 0;
   int historyTotal = OrdersHistoryTotal();
   
   // Update tracking
   lastKnownHistoryTotal = historyTotal;
   
   for(int i = historyTotal - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      datetime closeTime = OrderCloseTime();
      
      // Only count trades closed during current trading day
      if(closeTime < currentTradingDay) continue;
      if(closeTime >= currentTradingDay + 86400) continue;
      
      // Calculate P/L
      double tradePL = OrderProfit();
      
      if(CountSwapAndCommission)
      {
         tradePL += OrderSwap();
         tradePL += OrderCommission();
      }
      
      totalPL += tradePL;
      tradesCount++;
      
      // Track latest close time
      if(closeTime > lastProcessedTradeCloseTime)
         lastProcessedTradeCloseTime = closeTime;
   }
   
   todayClosedCount = tradesCount;
   
   return totalPL;
}

//+------------------------------------------------------------------+
//| 💰 Calculate current floating P/L from open positions            |
//+------------------------------------------------------------------+
double CalculateCurrentFloatingPL()
{
   double totalFloating = 0;
   
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      // Only count positions opened during current trading day
      datetime openTime = OrderOpenTime();
      if(openTime < currentTradingDay) continue;
      if(openTime >= currentTradingDay + 86400) continue;
      
      double positionPL = OrderProfit();
      
      if(CountSwapAndCommission)
      {
         positionPL += OrderSwap();
         positionPL += OrderCommission();
      }
      
      totalFloating += positionPL;
   }
   
   return totalFloating;
}

//+------------------------------------------------------------------+
//| 💰 Update daily P/L totals                                       |
//+------------------------------------------------------------------+
void UpdateDailyPL()
{
   if(!UseDailyLimits) return;
   
   // Check if new day
   CheckDailyReset();
   
   // Calculate closed P/L
   todayClosedPL = CalculateTodayClosedPL();
   
   // Calculate floating P/L if enabled
   if(CountFloatingPL)
      todayFloatingPL = CalculateCurrentFloatingPL();
   else
      todayFloatingPL = 0;
   
   // Total P/L
   todayTotalPL = todayClosedPL + todayFloatingPL;
}

//+------------------------------------------------------------------+
//| 💰 Check if daily limits have been hit                           |
//+------------------------------------------------------------------+
void CheckDailyLimits()
{
   if(!UseDailyLimits) return;
   if(dailyLossLimitHit || dailyProfitTargetHit) return; // Already hit
   
   bool limitJustHit = false;
   string limitType = "";
   
   // Check LOSS limit
   if(DailyLossLimit > 0 && todayTotalPL <= -DailyLossLimit)
   {
      dailyLossLimitHit = true;
      limitJustHit = true;
      limitType = "LOSS LIMIT";
      limitHitTime = TimeCurrent();
      
      Print("═══════════════════════════════════════════════");
      Print("🛑 DAILY LOSS LIMIT HIT!");
      Print("   Limit: -", DoubleToString(DailyLossLimit, 2));
      Print("   Today's P/L: ", DoubleToString(todayTotalPL, 2));
      Print("   Closed Trades: ", DoubleToString(todayClosedPL, 2));
      if(CountFloatingPL)
         Print("   Floating P/L: ", DoubleToString(todayFloatingPL, 2));
      Print("   Time: ", TimeToString(limitHitTime, TIME_DATE|TIME_MINUTES));
      Print("═══════════════════════════════════════════════");
   }
   
   // Check PROFIT target
   if(DailyProfitTarget > 0 && todayTotalPL >= DailyProfitTarget)
   {
      dailyProfitTargetHit = true;
      limitJustHit = true;
      limitType = "PROFIT TARGET";
      limitHitTime = TimeCurrent();
      
      Print("═══════════════════════════════════════════════");
      Print("🎯 DAILY PROFIT TARGET HIT!");
      Print("   Target: +", DoubleToString(DailyProfitTarget, 2));
      Print("   Today's P/L: ", DoubleToString(todayTotalPL, 2));
      Print("   Closed Trades: ", DoubleToString(todayClosedPL, 2));
      if(CountFloatingPL)
         Print("   Floating P/L: ", DoubleToString(todayFloatingPL, 2));
      Print("   Time: ", TimeToString(limitHitTime, TIME_DATE|TIME_MINUTES));
      Print("═══════════════════════════════════════════════");
   }
   
   // Handle limit hit
   if(limitJustHit)
   {
      // Close positions if configured
      if(LimitAction == LIMIT_CLOSE_ALL)
      {
         Print("💰 Closing all positions due to daily limit...");
         CloseAllTrades();
      }
      else
      {
         Print("💰 Stopping new trades (existing positions allowed to run)");
      }
      
      // Alerts
      if(AlertOnLimitHit)
      {
         string alertMsg = "PTL ATR EA: Daily " + limitType + " Hit!\n" +
                          "P/L: " + DoubleToString(todayTotalPL, 2) + " " + AccountCurrency();
         Alert(alertMsg);
      }
      
      // Sound
      if(PlaySoundOnLimit)
      {
         PlaySound(LimitHitSoundFile);
      }
      
      // Email
      if(SendEmailOnLimit)
      {
         string subject = "PTL ATR EA - Daily " + limitType;
         string body = "Daily " + limitType + " has been reached.\n\n" +
                      "Symbol: " + Symbol() + "\n" +
                      "Today's P/L: " + DoubleToString(todayTotalPL, 2) + " " + AccountCurrency() + "\n" +
                      "Closed Trades: " + DoubleToString(todayClosedPL, 2) + "\n" +
                      "Floating P/L: " + DoubleToString(todayFloatingPL, 2) + "\n" +
                      "Time: " + TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES);
         SendMail(subject, body);
      }
      
      // Push notification
      if(SendPushOnLimit)
      {
         string pushMsg = "PTL ATR: Daily " + limitType + " Hit! P/L: " + 
                         DoubleToString(todayTotalPL, 2) + " " + AccountCurrency();
         SendNotification(pushMsg);
      }
      
      // Save state
      SaveDailyLimitState();
      
      // Force panel redraw
      panelNeedsFullRedraw = true;
   }
}

//+------------------------------------------------------------------+
//| 💰 Check if currently blocked by daily limit                     |
//+------------------------------------------------------------------+
bool IsDailyLimitActive()
{
   if(!UseDailyLimits) return false;
   
   return (dailyLossLimitHit || dailyProfitTargetHit);
}

//+------------------------------------------------------------------+
//| 💰 Get daily limit status string                                 |
//+------------------------------------------------------------------+
string GetDailyLimitStatus()
{
   if(dailyLossLimitHit)
      return "LOSS LIMIT HIT";
   if(dailyProfitTargetHit)
      return "PROFIT TARGET HIT";
   
   return "Active";
}

//+------------------------------------------------------------------+
//| 💰 Save daily limit state to global variables                    |
//+------------------------------------------------------------------+
void SaveDailyLimitState()
{
   GlobalVariableSet("PTL_CurrentTradingDay", currentTradingDay);
   GlobalVariableSet("PTL_TodayClosedPL", todayClosedPL);
   GlobalVariableSet("PTL_TodayTradeCount", todayTradeCount);
   GlobalVariableSet("PTL_TodayClosedCount", todayClosedCount);
   GlobalVariableSet("PTL_DailyLossLimitHit", dailyLossLimitHit ? 1 : 0);
   GlobalVariableSet("PTL_DailyProfitTargetHit", dailyProfitTargetHit ? 1 : 0);
   GlobalVariableSet("PTL_LimitHitTime", limitHitTime);
   GlobalVariableSet("PTL_LastDailyResetTime", lastDailyResetTime);
}

//+------------------------------------------------------------------+
//| 💰 Restore daily limit state from global variables               |
//+------------------------------------------------------------------+
void RestoreDailyLimitState()
{
   if(!UseDailyLimits) return;
   
   if(GlobalVariableCheck("PTL_CurrentTradingDay"))
   {
      datetime savedTradingDay = (datetime)GlobalVariableGet("PTL_CurrentTradingDay");
      
      // Only restore if it's the same trading day
      CheckDailyReset(); // This sets currentTradingDay
      
      if(savedTradingDay == currentTradingDay)
      {
         Print("═══════════════════════════════════════════════");
         Print("💾 RESTORING DAILY LIMIT STATE");
         Print("   Trading Day: ", TimeToString(currentTradingDay, TIME_DATE));
         
         if(GlobalVariableCheck("PTL_TodayClosedPL"))
            todayClosedPL = GlobalVariableGet("PTL_TodayClosedPL");
         
         if(GlobalVariableCheck("PTL_TodayTradeCount"))
            todayTradeCount = (int)GlobalVariableGet("PTL_TodayTradeCount");
         
         if(GlobalVariableCheck("PTL_TodayClosedCount"))
            todayClosedCount = (int)GlobalVariableGet("PTL_TodayClosedCount");
         
         if(GlobalVariableCheck("PTL_DailyLossLimitHit"))
            dailyLossLimitHit = (GlobalVariableGet("PTL_DailyLossLimitHit") > 0);
         
         if(GlobalVariableCheck("PTL_DailyProfitTargetHit"))
            dailyProfitTargetHit = (GlobalVariableGet("PTL_DailyProfitTargetHit") > 0);
         
         if(GlobalVariableCheck("PTL_LimitHitTime"))
            limitHitTime = (datetime)GlobalVariableGet("PTL_LimitHitTime");
         
         if(GlobalVariableCheck("PTL_LastDailyResetTime"))
            lastDailyResetTime = (datetime)GlobalVariableGet("PTL_LastDailyResetTime");
         
         Print("   Restored Closed P/L: ", DoubleToString(todayClosedPL, 2));
         Print("   Restored Trade Count: ", todayClosedCount);
         Print("   Loss Limit Hit: ", (dailyLossLimitHit ? "YES" : "NO"));
         Print("   Profit Target Hit: ", (dailyProfitTargetHit ? "YES" : "NO"));
         Print("═══════════════════════════════════════════════");
         
         // Recalculate current totals
         UpdateDailyPL();
      }
      else
      {
         Print("ℹ️ Saved trading day differs from current - starting fresh");
         Print("   Saved: ", TimeToString(savedTradingDay, TIME_DATE));
         Print("   Current: ", TimeToString(currentTradingDay, TIME_DATE));
      }
   }
   else
   {
      Print("ℹ️ No saved daily limit state found - starting fresh");
      CheckDailyReset(); // Initialize current trading day
   }
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Check for new bar
   CheckNewBar();
   
   // Check for closed trades and update consecutive loss counter
   CheckClosedTrades();
   
   // Time restriction checks
   if(ShouldCloseAllTradesNow())
   {
      CloseAllTrades();
      wasInTradingHours = false;
      return;
   }
   
   // Update trading hours state
   wasInTradingHours = CanTradeNow();
   
   // Friday close check
   if(CloseFriday && IsFridayCloseTime())
   {
      CloseAllTrades();
      return;
   }
   
   // Calculate indicators on every tick for real-time updates
   if(!CalculateATRChannels()) return;
   if(!CalculatePTL()) return;
   if(!CalculateAroon()) return;
   
   // ═══════════════════════════════════════════════════════════════
   // 💰 UPDATE DAILY P/L AND CHECK LIMITS
   // ═══════════════════════════════════════════════════════════════
   if(UseDailyLimits)
   {
      UpdateDailyPL();
      CheckDailyLimits();
   }
   
   // Calculate HTF indicators if using HTF lockout
   if(UseConsecutiveLossFilter && (LockoutType == LOCKOUT_HTF_DOT || LockoutType == LOCKOUT_HYBRID))
   {
      if(!CalculateHTFIndicators()) return;
   }
   
   // Update drawings on new bar
   if(newBarFlag)
   {
      // Draw new indicators incrementally
      DrawNewBars();
      
      // Check for exits first (existing trades)
      if(CanManageExitsNow())
      {
         CheckForExits();
      }
      
      // Check if we're in lockout period
      if(UseConsecutiveLossFilter && IsInLockout())
      {
         // Check for HTF confirmation if applicable
         if(LockoutType == LOCKOUT_HTF_DOT || LockoutType == LOCKOUT_HYBRID)
         {
            CheckHTFConfirmation();
         }
         
         if(IsInLockout()) // Still in lockout after HTF check
         {
            string lockoutMsg = "In lockout period";
            if(LockoutType == LOCKOUT_TIME_BASED || LockoutType == LOCKOUT_HYBRID)
               lockoutMsg += " - " + DoubleToString(GetLockoutTimeRemaining(), 1) + " hours remaining";
            if(LockoutType == LOCKOUT_HTF_DOT || LockoutType == LOCKOUT_HYBRID)
               lockoutMsg += " - Waiting for " + IntegerToString(HTF_Timeframe) + " " + 
                            (lockoutDirection == OP_BUY ? "GREEN" : "PINK") + " dot confirmation";
            Print(lockoutMsg);
            return;
         }
      }
      
      // Check if we can trade now (time restrictions)
      if(!CanTradeNow())
      {
         return;
      }
      
      // 💰 Check daily limit before allowing new trades
      if(IsDailyLimitActive())
      {
         // Daily limit hit - no new trades allowed
         return;
      }
      
      // Check for new entries
      if(OneTradeAtATime && GetOpenTradesCount() > 0) return;
      
      CheckForEntry();
   }
   
   // Update trade info panel on every tick
   if(ShowTradeInfo)
   {
      UpdateTradeInfoPanel();
   }
   
   // 🔥 NEW: Periodic state saving (every 5 minutes)
   static datetime lastStateSave = 0;
   if(TimeCurrent() - lastStateSave > 300)  // 300 seconds = 5 minutes
   {
      SaveStateToGlobalVariables();
      lastStateSave = TimeCurrent();
   }
}

//+------------------------------------------------------------------+
//| Check for new bar                                                |
//+------------------------------------------------------------------+
void CheckNewBar()
{
   datetime currentBarTime = Time[0];
   
   if(currentBarTime != lastBarTime)
   {
      lastBarTime = currentBarTime;
      newBarFlag = true;
   }
   else
   {
      newBarFlag = false;
   }
}

//+------------------------------------------------------------------+
//| Calculate ATR Channels (Embedded Logic) - MT4 VERSION            |
//+------------------------------------------------------------------+
bool CalculateATRChannels()
{
   int bars = MathMax(ATR_Periods, ATR_MA_Periods) + 10;
   int available = Bars;
   
   if(available < bars) bars = available;
   if(bars < MathMax(ATR_Periods, ATR_MA_Periods)) return false;
   
   ArrayResize(atrMA, bars);        ArraySetAsSeries(atrMA, true);
   ArrayResize(atrUpper1, bars);    ArraySetAsSeries(atrUpper1, true);
   ArrayResize(atrLower1, bars);    ArraySetAsSeries(atrLower1, true);
   ArrayResize(atrUpper2, bars);    ArraySetAsSeries(atrUpper2, true);
   ArrayResize(atrLower2, bars);    ArraySetAsSeries(atrLower2, true);
   ArrayResize(atrUpper3, bars);    ArraySetAsSeries(atrUpper3, true);
   ArrayResize(atrLower3, bars);    ArraySetAsSeries(atrLower3, true);
   ArrayResize(atrUpperBand, bars); ArraySetAsSeries(atrUpperBand, true);
   ArrayResize(atrLowerBand, bars); ArraySetAsSeries(atrLowerBand, true);

   for(int i = 0; i < bars; i++)
   {
      double atr = iATR(Symbol(), Period(), ATR_Periods, i);
      double ma = iMA(Symbol(), Period(), ATR_MA_Periods, 0, ATR_MA_Type, PRICE_TYPICAL, i);
      
      atrMA[i] = ma;
      atrUpper1[i] = ma + atr * ATR_Mult1;
      atrLower1[i] = ma - atr * ATR_Mult1;
      atrUpper2[i] = ma + atr * ATR_Mult2;
      atrLower2[i] = ma - atr * ATR_Mult2;
      atrUpper3[i] = ma + atr * ATR_Mult3;
      atrLower3[i] = ma - atr * ATR_Mult3;
      // atrUpperBand/atrLowerBand reference the outer (6.5x) band for out-of-bounds detection
      atrUpperBand[i] = atrUpper3[i];
      atrLowerBand[i] = atrLower3[i];
   }
   return true;
}

//+------------------------------------------------------------------+
//| Calculate PTL Indicator (Embedded Logic) - MT4 VERSION           |
//+------------------------------------------------------------------+
bool CalculatePTL()
{
   int bars = MathMax(PTL_SlowLength, PTL_FastLength) + 100;
   int rates_total = Bars;
   
   if(rates_total < bars) bars = rates_total;
   if(bars < MathMax(PTL_SlowLength, PTL_FastLength)) return false;
   
   ArrayResize(ptlLine1, bars);     ArraySetAsSeries(ptlLine1, true);
   ArrayResize(ptlLine2, bars);     ArraySetAsSeries(ptlLine2, true);
   ArrayResize(ptlTrend, bars);     ArraySetAsSeries(ptlTrend, true);
   ArrayResize(ptlTrena, bars);     ArraySetAsSeries(ptlTrena, true);
   ArrayResize(ptlArrowUp, bars);   ArraySetAsSeries(ptlArrowUp, true);
   ArrayResize(ptlArrowDown, bars); ArraySetAsSeries(ptlArrowDown, true);
   
   double pipMultiplier = Point * MathPow(10, Digits % 2);
   double SlowPipDisplace = 0.0;
   double FastPipDisplace = 0.0;
   
   for(int i = bars - 1; i >= 0; i--)
   {
      int highestIdx1 = iHighest(Symbol(), Period(), MODE_HIGH, PTL_SlowLength, i);
      int lowestIdx1 = iLowest(Symbol(), Period(), MODE_LOW, PTL_SlowLength, i);
      int highestIdx2 = iHighest(Symbol(), Period(), MODE_HIGH, PTL_FastLength, i);
      int lowestIdx2 = iLowest(Symbol(), Period(), MODE_LOW, PTL_FastLength, i);
      
      double thigh1 = High[highestIdx1] + SlowPipDisplace * pipMultiplier;
      double tlow1  = Low[lowestIdx1] - SlowPipDisplace * pipMultiplier;
      double thigh2 = High[highestIdx2] + FastPipDisplace * pipMultiplier;
      double tlow2  = Low[lowestIdx2] - FastPipDisplace * pipMultiplier;
      
      if(i < bars - 1 && Close[i] > ptlLine1[i + 1])
         ptlLine1[i] = tlow1;
      else
         ptlLine1[i] = thigh1;
      
      if(i < bars - 1 && Close[i] > ptlLine2[i + 1])
         ptlLine2[i] = tlow2;
      else
         ptlLine2[i] = thigh2;
      
      ptlArrowUp[i] = EMPTY_VALUE;
      ptlArrowDown[i] = EMPTY_VALUE;
      ptlTrena[i] = i < bars - 1 ? ptlTrena[i + 1] : 0;
      ptlTrend[i] = 0;
      
      if(Close[i] < ptlLine1[i] && Close[i] < ptlLine2[i]) 
         ptlTrend[i] = 1;
      if(Close[i] > ptlLine1[i] && Close[i] > ptlLine2[i]) 
         ptlTrend[i] = -1;
      
      if(ptlLine1[i] > ptlLine2[i] || ptlTrend[i] == 1) 
         ptlTrena[i] = 1;
      if(ptlLine1[i] < ptlLine2[i] || ptlTrend[i] == -1) 
         ptlTrena[i] = -1;
      
      if(i < bars - 1 && ptlTrena[i] != ptlTrena[i + 1])
      {
         if(ptlTrena[i] == 1)
            ptlArrowDown[i] = MathMax(ptlLine1[i], ptlLine2[i]);
         else
            ptlArrowUp[i] = MathMin(ptlLine1[i], ptlLine2[i]);
      }
   }
   
   return true;
}


//+------------------------------------------------------------------+
//| Calculate HTF ATR Channels - MT4 VERSION                         |
//+------------------------------------------------------------------+
bool CalculateHTFATRChannels()
{
   int bars = MathMax(ATR_Periods, ATR_MA_Periods) + 10;
   int available = iBars(Symbol(), HTF_Timeframe);
   
   if(available < bars) bars = available;
   if(bars < MathMax(ATR_Periods, ATR_MA_Periods)) return false;
   
   ArrayResize(htfAtrMA, bars);
   ArrayResize(htfAtrUpperBand, bars);
   ArrayResize(htfAtrLowerBand, bars);
   
   for(int i = 0; i < bars; i++)
   {
      double atr = iATR(Symbol(), HTF_Timeframe, ATR_Periods, i);
      double ma = iMA(Symbol(), HTF_Timeframe, ATR_MA_Periods, 0, ATR_MA_Type, PRICE_TYPICAL, i);
      
      htfAtrMA[i] = ma;
      htfAtrUpperBand[i] = ma + atr * ATR_Mult1; // Replaced ATR_MultFactor
      htfAtrLowerBand[i] = ma - atr * ATR_Mult1; // Replaced ATR_MultFactor
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Calculate HTF PTL Indicator - MT4 VERSION                        |
//+------------------------------------------------------------------+
bool CalculateHTFPTL()
{
   int bars = MathMax(PTL_SlowLength, PTL_FastLength) + 100;
   int rates_total = iBars(Symbol(), HTF_Timeframe);
   
   if(rates_total < bars) bars = rates_total;
   if(bars < MathMax(PTL_SlowLength, PTL_FastLength)) return false;
   
   ArrayResize(htfPtlLine1, bars);
   ArrayResize(htfPtlLine2, bars);
   ArrayResize(htfPtlTrend, bars);
   ArrayResize(htfPtlTrena, bars);
   ArrayResize(htfPtlArrowUp, bars);
   ArrayResize(htfPtlArrowDown, bars);
   
   double pipMultiplier = Point * MathPow(10, Digits % 2);
   double SlowPipDisplace = 0.0;
   double FastPipDisplace = 0.0;
   
   for(int i = bars - 1; i >= 0; i--)
   {
      int highestIdx1 = iHighest(Symbol(), HTF_Timeframe, MODE_HIGH, PTL_SlowLength, i);
      int lowestIdx1 = iLowest(Symbol(), HTF_Timeframe, MODE_LOW, PTL_SlowLength, i);
      int highestIdx2 = iHighest(Symbol(), HTF_Timeframe, MODE_HIGH, PTL_FastLength, i);
      int lowestIdx2 = iLowest(Symbol(), HTF_Timeframe, MODE_LOW, PTL_FastLength, i);
      
      double thigh1 = iHigh(Symbol(), HTF_Timeframe, highestIdx1) + SlowPipDisplace * pipMultiplier;
      double tlow1  = iLow(Symbol(), HTF_Timeframe, lowestIdx1) - SlowPipDisplace * pipMultiplier;
      double thigh2 = iHigh(Symbol(), HTF_Timeframe, highestIdx2) + FastPipDisplace * pipMultiplier;
      double tlow2  = iLow(Symbol(), HTF_Timeframe, lowestIdx2) - FastPipDisplace * pipMultiplier;
      
      double htfClose = iClose(Symbol(), HTF_Timeframe, i);
      
      if(i < bars - 1 && htfClose > htfPtlLine1[i + 1])
         htfPtlLine1[i] = tlow1;
      else
         htfPtlLine1[i] = thigh1;
      
      if(i < bars - 1 && htfClose > htfPtlLine2[i + 1])
         htfPtlLine2[i] = tlow2;
      else
         htfPtlLine2[i] = thigh2;
      
      htfPtlArrowUp[i] = EMPTY_VALUE;
      htfPtlArrowDown[i] = EMPTY_VALUE;
      htfPtlTrena[i] = i < bars - 1 ? htfPtlTrena[i + 1] : 0;
      htfPtlTrend[i] = 0;
      
      if(htfClose < htfPtlLine1[i] && htfClose < htfPtlLine2[i]) 
         htfPtlTrend[i] = 1;
      if(htfClose > htfPtlLine1[i] && htfClose > htfPtlLine2[i]) 
         htfPtlTrend[i] = -1;
      
      if(htfPtlLine1[i] > htfPtlLine2[i] || htfPtlTrend[i] == 1) 
         htfPtlTrena[i] = 1;
      if(htfPtlLine1[i] < htfPtlLine2[i] || htfPtlTrend[i] == -1) 
         htfPtlTrena[i] = -1;
      
      if(i < bars - 1 && htfPtlTrena[i] != htfPtlTrena[i + 1])
      {
         if(htfPtlTrena[i] == 1)
            htfPtlArrowDown[i] = MathMax(htfPtlLine1[i], htfPtlLine2[i]);
         else
            htfPtlArrowUp[i] = MathMin(htfPtlLine1[i], htfPtlLine2[i]);
      }
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Calculate all HTF indicators                                     |
//+------------------------------------------------------------------+
bool CalculateHTFIndicators()
{
   if(!CalculateHTFATRChannels()) return false;
   if(!CalculateHTFPTL()) return false;
   return true;
}

//+------------------------------------------------------------------+
//| Check for entry signals - COMPLETE WITH PANEL TRIGGERS           |
//+------------------------------------------------------------------+
void CheckForEntry()
{
   if(ArraySize(atrMA) < 2 || ArraySize(ptlArrowUp) < 2) return;
   
   double close1 = Close[1];
   double high1 = High[1];
   double low1 = Low[1];
   
   double midline1 = atrMA[1];
   double upperBand1 = atrUpperBand[1];
   double lowerBand1 = atrLowerBand[1];
   double greenDot1 = ptlArrowUp[1];
   double pinkDot1 = ptlArrowDown[1];
   
   // ═══════════════════════════════════════════════════════════════
   // CHECK TIME-BASED LOCKOUT EXPIRY (for both colors)
   // ═══════════════════════════════════════════════════════════════
   if(UseSameColorDotLockout && SameColorLockoutMaxHours > 0)
   {
      if(greenDotLockoutActive && IsSameColorLockoutExpired(greenLockoutStartTime))
      {
         Print("═══════════════════════════════════════════════");
         Print("⏰ GREEN DOT LOCKOUT EXPIRED (Time-based)");
         Print("   Max lockout period reached: ", SameColorLockoutMaxHours, " hours");
         Print("═══════════════════════════════════════════════");
         greenDotLockoutActive = false;
         greenLockoutStartTime = 0;
         panelNeedsFullRedraw = true;  // 🔥 STATE CHANGE #1
         SaveStateToGlobalVariables();
      }
      
      if(pinkDotLockoutActive && IsSameColorLockoutExpired(pinkLockoutStartTime))
      {
         Print("═══════════════════════════════════════════════");
         Print("⏰ PINK DOT LOCKOUT EXPIRED (Time-based)");
         Print("   Max lockout period reached: ", SameColorLockoutMaxHours, " hours");
         Print("═══════════════════════════════════════════════");
         pinkDotLockoutActive = false;
         pinkLockoutStartTime = 0;
         panelNeedsFullRedraw = true;  // 🔥 STATE CHANGE #2
         SaveStateToGlobalVariables();
      }
   }
   
   // ═══════════════════════════════════════════════════════════════
   // BUY SIGNAL (GREEN DOT)
   // ═══════════════════════════════════════════════════════════════
   if(TradeLong && greenDot1 != EMPTY_VALUE)
   {
      if(close1 < midline1 && high1 < midline1)
      {
         // ──────────────────────────────────────────────────────────
         // CHECK GREEN DOT LOCKOUT STATUS
         // ──────────────────────────────────────────────────────────
         if(UseSameColorDotLockout && greenDotLockoutActive)
         {
            bool unlockConditionMet = false;
            
            if(WholeBarUnlock)
               unlockConditionMet = IsEntireBarInsideBands(1);
            else
               unlockConditionMet = IsCloseInsideBands(1);
            
            if(unlockConditionMet)
            {
               Print("═══════════════════════════════════════════════");
               Print("🔓 GREEN DOT LOCKOUT ENDED");
               Print("   Unlock condition met: ", WholeBarUnlock ? "Entire bar inside bands" : "Close inside bands");
               Print("   Close: ", close1);
               Print("   Bands: [", lowerBand1, " - ", upperBand1, "]");
               
               if(TradeUnlockSignal)
               {
                  Print("   ✅ TRADING this unlock signal (TradeUnlockSignal=true)");
                  Print("═══════════════════════════════════════════════");
                  
                  greenDotLockoutActive = false;
                  greenLockoutStartTime = 0;
                  greenSequenceActive = false;      // 🔥 NEW: Reset sequence
                  greenFirstTradeTicket = 0;        // 🔥 NEW: Reset first trade
                  panelNeedsFullRedraw = true;
                  SaveStateToGlobalVariables();
                  
                  // Continue to trade this signal (don't return)
               }
               else
               {
                  Print("   ⚠️ NOT trading this unlock signal (TradeUnlockSignal=false)");
                  Print("   ✅ Next GREEN dot will be tradeable");
                  Print("═══════════════════════════════════════════════");
                  
                  greenDotLockoutActive = false;
                  greenLockoutStartTime = 0;
                  greenSequenceActive = false;      // 🔥 NEW: Reset sequence
                  greenFirstTradeTicket = 0;        // 🔥 NEW: Reset first trade
                  panelNeedsFullRedraw = true;
                  SaveStateToGlobalVariables();
                  
                  // Don't trade - this is just the unlock trigger
                  return;
               }
            }
            else
            {
               // Still locked out
               Print("═══════════════════════════════════════════════");
               Print("🔒 GREEN DOT LOCKOUT ACTIVE - Trade BLOCKED");
               Print("   Signal: GREEN dot at ", greenDot1);
               Print("   Reason: Same-color lockout in effect");
               Print("   Close: ", close1, " (unlock condition not met)");
               if(WholeBarUnlock)
                  Print("   Waiting for: GREEN dot with ENTIRE bar inside bands");
               else
                  Print("   Waiting for: GREEN dot with close inside bands");
               Print("═══════════════════════════════════════════════");
               return;
            }
         }
         
         // ──────────────────────────────────────────────────────────
         // ZONE SL LOCKOUT CHECK (BUY side)
         // Blocks entry in the locked zone only.
         // Any green dot in ANY other zone unlocks and trades.
         // ──────────────────────────────────────────────────────────
         if(UseZoneLockout && greenZoneLockout != 0)
         {
            int currentBarZone = GetPriceZone(close1, 1);
            
            // Block only if attempting to enter the exact locked zone
            if(currentBarZone == greenZoneLockout)
            {
               Print("🔒 ZONE LOCKOUT ACTIVE (BUY): Zone ", greenZoneLockout, 
                     " (", GetZoneName(greenZoneLockout), ") locked. ",
                     "Green dot in any other zone will unlock.");
               return;
            }
            
            // Any other zone: unlock and allow the trade
            Print("═══════════════════════════════════════════════");
            Print("🔓 ZONE LOCKOUT CLEARED (BUY): Green dot in zone ", currentBarZone, 
                  " (", GetZoneName(currentBarZone), ")");
            Print("   Was locked at zone: ", greenZoneLockout, " (", GetZoneName(greenZoneLockout), ")");
            Print("═══════════════════════════════════════════════");
            greenZoneLockout = 0;
            panelNeedsFullRedraw = true;
            SaveStateToGlobalVariables();
            // Continue - this signal is tradeable
         }
         
         // ──────────────────────────────────────────────────────────
         // AROON FILTER CHECK
         // ──────────────────────────────────────────────────────────
         if(UseAroonFilter)
         {
            if(ArraySize(aroonUp) < 2 || ArraySize(aroonDown) < 2)
            {
               Print("⚠️ Aroon not ready - skipping trade");
               return;
            }
            
            double aroonUpValue = aroonUp[1];
            double aroonDownValue = aroonDown[1];
            
            if(aroonUpValue <= aroonDownValue)
            {
               Print("═══════════════════════════════════════════════");
               Print("🚫 BUY SIGNAL FILTERED by Aroon");
               Print("   Green Dot: ", greenDot1);
               Print("   Close: ", close1, " | Midline: ", midline1);
               Print("   Aroon Up: ", DoubleToString(aroonUpValue, 1), "%");
               Print("   Aroon Down: ", DoubleToString(aroonDownValue, 1), "%");
               Print("   ❌ Aroon shows DOWNTREND - trade rejected");
               Print("═══════════════════════════════════════════════");
               return;
            }
            else
            {
               Print("✅ Aroon confirms UPTREND (Up:", DoubleToString(aroonUpValue, 1), "% > Down:", DoubleToString(aroonDownValue, 1), "%)");
            }
         }
         
         // ──────────────────────────────────────────────────────────
         // CHECK IF THIS TRADE TRIGGERS GREEN LOCKOUT (IMMEDIATE MODE)
         // ──────────────────────────────────────────────────────────
         bool triggersLockout = false;
         if(UseSameColorDotLockout && LockoutActivationMode == ACTIVATE_IMMEDIATE && 
            !greenDotLockoutActive && IsEntireBarBelowBand(1))
         {
            triggersLockout = true;
            
            Print("═══════════════════════════════════════════════");
            Print("🔒 TRIGGERING GREEN DOT LOCKOUT (IMMEDIATE MODE)");
            Print("   Condition: Entire OHLC bar below lower band");
            Print("   Lower Band: ", lowerBand1);
            
            if(TakeActivationTrade)
               Print("   → Taking THIS activation trade");
            else
               Print("   → SKIPPING activation trade (TakeActivationTrade=false)");
            
            Print("   → Blocking future GREEN dots until unlock");
            Print("═══════════════════════════════════════════════");
         }
         
         // ──────────────────────────────────────────────────────────
         // TAKE THE TRADE (only if not a skipped activation trade)
         // ──────────────────────────────────────────────────────────
         if(!triggersLockout || TakeActivationTrade)
         {
            Print("BUY Signal detected at bar 1 - Green Dot: ", greenDot1, " | Close: ", close1, " | Midline: ", midline1);
            
            bool isOutOfBounds = IsEntireBarBelowBand(1);
            
            OpenTrade(OP_BUY, MAGIC_BUY_GREEN, isOutOfBounds);
            DrawEntryMarker(1, OP_BUY, greenDot1);
         }
         
         // Activate lockout AFTER trade decision
         if(triggersLockout)
         {
            greenDotLockoutActive = true;
            greenLockoutStartTime = Time[1];
            DrawSameColorLockoutZone(true);
            panelNeedsFullRedraw = true;  // 🔥 STATE CHANGE #5
            SaveStateToGlobalVariables();
         }
         
         return;
      }
      else
      {
         // GREEN dot fired but price not below midline - signal not taken
         Print("GREEN dot seen at ", greenDot1, " but price not below midline (", 
               "Close:", close1, " High:", high1, " Midline:", midline1, ") - no trade");
      }
   }
   
   // ═══════════════════════════════════════════════════════════════
   // SELL SIGNAL (PINK DOT)
   // ═══════════════════════════════════════════════════════════════
   if(TradeShort && pinkDot1 != EMPTY_VALUE)
   {
      if(close1 > midline1 && low1 > midline1)
      {
         // ──────────────────────────────────────────────────────────
         // CHECK PINK DOT LOCKOUT STATUS
         // ──────────────────────────────────────────────────────────
         if(UseSameColorDotLockout && pinkDotLockoutActive)
         {
            bool unlockConditionMet = false;
            
            if(WholeBarUnlock)
               unlockConditionMet = IsEntireBarInsideBands(1);
            else
               unlockConditionMet = IsCloseInsideBands(1);
            
            if(unlockConditionMet)
            {
               Print("═══════════════════════════════════════════════");
               Print("🔓 PINK DOT LOCKOUT ENDED");
               Print("   Unlock condition met: ", WholeBarUnlock ? "Entire bar inside bands" : "Close inside bands");
               Print("   Close: ", close1);
               Print("   Bands: [", lowerBand1, " - ", upperBand1, "]");
               
               if(TradeUnlockSignal)
               {
                  Print("   ✅ TRADING this unlock signal (TradeUnlockSignal=true)");
                  Print("═══════════════════════════════════════════════");
                  
                  pinkDotLockoutActive = false;
                  pinkLockoutStartTime = 0;
                  pinkSequenceActive = false;       // 🔥 NEW: Reset sequence
                  pinkFirstTradeTicket = 0;         // 🔥 NEW: Reset first trade
                  panelNeedsFullRedraw = true;
                  SaveStateToGlobalVariables();
                  
                  // Continue to trade this signal (don't return)
               }
               else
               {
                  Print("   ⚠️ NOT trading this unlock signal (TradeUnlockSignal=false)");
                  Print("   ✅ Next PINK dot will be tradeable");
                  Print("═══════════════════════════════════════════════");
                  
                  pinkDotLockoutActive = false;
                  pinkLockoutStartTime = 0;
                  pinkSequenceActive = false;       // 🔥 NEW: Reset sequence
                  pinkFirstTradeTicket = 0;         // 🔥 NEW: Reset first trade
                  panelNeedsFullRedraw = true;
                  SaveStateToGlobalVariables();
                  
                  // Don't trade - this is just the unlock trigger
                  return;
               }
            }
            else
            {
               // Still locked out
               Print("═══════════════════════════════════════════════");
               Print("🔒 PINK DOT LOCKOUT ACTIVE - Trade BLOCKED");
               Print("   Signal: PINK dot at ", pinkDot1);
               Print("   Reason: Same-color lockout in effect");
               Print("   Close: ", close1, " (unlock condition not met)");
               if(WholeBarUnlock)
                  Print("   Waiting for: PINK dot with ENTIRE bar inside bands");
               else
                  Print("   Waiting for: PINK dot with close inside bands");
               Print("═══════════════════════════════════════════════");
               return;
            }
         }
         
         // ──────────────────────────────────────────────────────────
         // ZONE SL LOCKOUT CHECK (BUY side)
         // Blocks entry in the locked zone only.
         // Any green dot in ANY other zone unlocks and trades.
         // ──────────────────────────────────────────────────────────
         if(UseZoneLockout && greenZoneLockout != 0)
         {
            int currentBarZone = GetPriceZone(close1, 1);
            
            // Block only if attempting to enter the exact locked zone
            if(currentBarZone == greenZoneLockout)
            {
               Print("🔒 ZONE LOCKOUT ACTIVE (BUY): Zone ", greenZoneLockout, 
                     " (", GetZoneName(greenZoneLockout), ") locked. ",
                     "Green dot in any other zone will unlock.");
               return;
            }
            
            // Any other zone: unlock and allow the trade
            Print("═══════════════════════════════════════════════");
            Print("🔓 ZONE LOCKOUT CLEARED (BUY): Green dot in zone ", currentBarZone, 
                  " (", GetZoneName(currentBarZone), ")");
            Print("   Was locked at zone: ", greenZoneLockout, " (", GetZoneName(greenZoneLockout), ")");
            Print("═══════════════════════════════════════════════");
            greenZoneLockout = 0;
            panelNeedsFullRedraw = true;
            SaveStateToGlobalVariables();
            // Continue - this signal is tradeable
         }
         
         // ──────────────────────────────────────────────────────────
         // ZONE SL LOCKOUT CHECK (SELL side)
         // Blocks entry in the locked zone only.
         // Any pink dot in ANY other zone unlocks and trades.
         // ──────────────────────────────────────────────────────────
         if(UseZoneLockout && pinkZoneLockout != 0)
         {
            int currentBarZone = GetPriceZone(close1, 1);
            
            // Block only if attempting to enter the exact locked zone
            if(currentBarZone == pinkZoneLockout)
            {
               Print("🔒 ZONE LOCKOUT ACTIVE (SELL): Zone ", pinkZoneLockout, 
                     " (", GetZoneName(pinkZoneLockout), ") locked. ",
                     "Pink dot in any other zone will unlock.");
               return;
            }
            
            // Any other zone: unlock and allow the trade
            Print("═══════════════════════════════════════════════");
            Print("🔓 ZONE LOCKOUT CLEARED (SELL): Pink dot in zone ", currentBarZone,
                  " (", GetZoneName(currentBarZone), ")");
            Print("   Was locked at zone: ", pinkZoneLockout, " (", GetZoneName(pinkZoneLockout), ")");
            Print("═══════════════════════════════════════════════");
            pinkZoneLockout = 0;
            panelNeedsFullRedraw = true;
            SaveStateToGlobalVariables();
            // Continue - this signal is tradeable
         }
         
         // ──────────────────────────────────────────────────────────
         // AROON FILTER CHECK
         // ──────────────────────────────────────────────────────────
         if(UseAroonFilter)
         {
            if(ArraySize(aroonUp) < 2 || ArraySize(aroonDown) < 2)
            {
               Print("⚠️ Aroon not ready - skipping trade");
               return;
            }
            
            double aroonUpValue = aroonUp[1];
            double aroonDownValue = aroonDown[1];
            
            if(aroonDownValue <= aroonUpValue)
            {
               Print("═══════════════════════════════════════════════");
               Print("🚫 SELL SIGNAL FILTERED by Aroon");
               Print("   Pink Dot: ", pinkDot1);
               Print("   Close: ", close1, " | Midline: ", midline1);
               Print("   Aroon Up: ", DoubleToString(aroonUpValue, 1), "%");
               Print("   Aroon Down: ", DoubleToString(aroonDownValue, 1), "%");
               Print("   ❌ Aroon shows UPTREND - trade rejected");
               Print("═══════════════════════════════════════════════");
               return;
            }
            else
            {
               Print("✅ Aroon confirms DOWNTREND (Down:", DoubleToString(aroonDownValue, 1), "% > Up:", DoubleToString(aroonUpValue, 1), "%)");
            }
         }
         
         // ──────────────────────────────────────────────────────────
         // CHECK IF THIS TRADE TRIGGERS PINK LOCKOUT (IMMEDIATE MODE)
         // ──────────────────────────────────────────────────────────
         bool triggersLockout = false;
         if(UseSameColorDotLockout && LockoutActivationMode == ACTIVATE_IMMEDIATE && 
            !pinkDotLockoutActive && IsEntireBarAboveBand(1))
         {
            triggersLockout = true;
            
            Print("═══════════════════════════════════════════════");
            Print("🔒 TRIGGERING PINK DOT LOCKOUT (IMMEDIATE MODE)");
            Print("   Condition: Entire OHLC bar above upper band");
            Print("   Upper Band: ", upperBand1);
            
            if(TakeActivationTrade)
               Print("   → Taking THIS activation trade");
            else
               Print("   → SKIPPING activation trade (TakeActivationTrade=false)");
            
            Print("   → Blocking future PINK dots until unlock");
            Print("═══════════════════════════════════════════════");
         }
         
         // ──────────────────────────────────────────────────────────
         // TAKE THE TRADE (only if not a skipped activation trade)
         // ──────────────────────────────────────────────────────────
         if(!triggersLockout || TakeActivationTrade)
         {
            Print("SELL Signal detected at bar 1 - Pink Dot: ", pinkDot1, " | Close: ", close1, " | Midline: ", midline1);
            
            bool isOutOfBounds = IsEntireBarAboveBand(1);
            
            OpenTrade(OP_SELL, MAGIC_SELL_PINK, isOutOfBounds);
            DrawEntryMarker(1, OP_SELL, pinkDot1);
         }
         
         // Activate lockout AFTER trade decision
         if(triggersLockout)
         {
            pinkDotLockoutActive = true;
            pinkLockoutStartTime = Time[1];
            DrawSameColorLockoutZone(false);
            panelNeedsFullRedraw = true;  // 🔥 STATE CHANGE #8
            SaveStateToGlobalVariables();
         }
         
         return;
      }
      else
      {
         // PINK dot fired but price not above midline - signal not taken
         Print("PINK dot seen at ", pinkDot1, " but price not above midline (", 
               "Close:", close1, " Low:", low1, " Midline:", midline1, ") - no trade");
      }
   }
}

//+------------------------------------------------------------------+
//| Check for exit signals - MT4 VERSION                             |
//+------------------------------------------------------------------+
void CheckForExits()
{
   if(ArraySize(atrMA) < 2 || ArraySize(ptlArrowUp) < 2) return;
   
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      TradeEntryData stored;
      if(!FindStoredEntryData(OrderTicket(), stored)) continue;

      // Use bar 1 close for exit checks (confirmed closed bar)
      int currentZone = GetPriceZone(Close[1], 1);
      bool sameDot = (OrderType() == OP_BUY) ? (ptlArrowUp[1] != EMPTY_VALUE) : (ptlArrowDown[1] != EMPTY_VALUE);

      // RULE 1: TRAVERSE 1 FULL BAND
      // Exit threshold accounts for the midline gap (no zone 0 exists):
      //   BUY  zone -4 -> exit >= -2  |  SELL zone +4 -> exit <= +2
      //   BUY  zone -3 -> exit >= -1  |  SELL zone +3 -> exit <= +1
      //   BUY  zone -2 -> exit >= +1  |  SELL zone +2 -> exit <= -1
      //   BUY  zone -1 -> exit >= +2  |  SELL zone +1 -> exit <= -2
      //   (inner-zone entries must fully cross midline AND first opposite band)
      int buyExitThreshold  = (stored.entryZone == -1) ? 2 : stored.entryZone + 2;
      int sellExitThreshold = (stored.entryZone ==  1) ? -2 : stored.entryZone - 2;
      
      bool traversed = false;
      if(OrderType() == OP_BUY  && currentZone >= buyExitThreshold)  traversed = true;
      if(OrderType() == OP_SELL && currentZone <= sellExitThreshold) traversed = true;

      if(traversed)
      {
         Print("Exiting: Full band traversal. Entry Zone: ", stored.entryZone, 
               " Threshold: ", (OrderType()==OP_BUY ? buyExitThreshold : sellExitThreshold),
               " Current: ", currentZone);
         CloseTrade(OrderTicket());
         continue;
      }

      // RULE 2: SAME COLOR DOT IN NEXT ADJACENT ZONE (ONE ZONE CLOSER TO MIDLINE)
      // Also accounts for midline gap: zone -1 same-dot exit is zone +1, not zone 0
      int buySameDotZone  = (stored.entryZone == -1) ? 1 : stored.entryZone + 1;
      int sellSameDotZone = (stored.entryZone ==  1) ? -1 : stored.entryZone - 1;
      
      bool inwardDot = false;
      if(OrderType() == OP_BUY  && sameDot && currentZone == buySameDotZone)  inwardDot = true;
      if(OrderType() == OP_SELL && sameDot && currentZone == sellSameDotZone) inwardDot = true;

      if(inwardDot)
      {
         Print("Exiting: Same color dot in next adjacent zone. Entry: ", stored.entryZone, " Current: ", currentZone);
         CloseTrade(OrderTicket());
         continue;
      }
   }
}

//+------------------------------------------------------------------+
//| Find LOWEST LOW within lookback period for BUY trades            |
//+------------------------------------------------------------------+
double FindLocalSwingLow(int triggerBar)
{
   double lowestLow = Low[triggerBar];
   int lowestBar = triggerBar;
   
   for(int i = triggerBar; i <= triggerBar + SwingLookbackBars; i++)
   {
      if(i >= Bars) break;
      
      double barLow = Low[i];
      
      if(barLow < lowestLow)
      {
         lowestLow = barLow;
         lowestBar = i;
      }
   }
   
   Print("   Found lowest low at bar ", lowestBar, " (", lowestBar - triggerBar, " bars back) | Price: ", lowestLow);
   return lowestLow;
}

//+------------------------------------------------------------------+
//| Find HIGHEST HIGH within lookback period for SELL trades         |
//+------------------------------------------------------------------+
double FindLocalSwingHigh(int triggerBar)
{
   double highestHigh = High[triggerBar];
   int highestBar = triggerBar;
   
   for(int i = triggerBar; i <= triggerBar + SwingLookbackBars; i++)
   {
      if(i >= Bars) break;
      
      double barHigh = High[i];
      
      if(barHigh > highestHigh)
      {
         highestHigh = barHigh;
         highestBar = i;
      }
   }
   
   Print("   Found highest high at bar ", highestBar, " (", highestBar - triggerBar, " bars back) | Price: ", highestHigh);
   return highestHigh;
}

//+------------------------------------------------------------------+
//| Open trade - MT4 VERSION WITH LOCAL SWING SL                     |
//+------------------------------------------------------------------+
void OpenTrade(int orderType, int magic, bool isOutOfBounds = false)
{
   double lotSize = CalculateLotSize();
   if(lotSize <= 0)
   {
      Print("Invalid lot size calculated: ", lotSize);
      return;
   }
   
   double price = (orderType == OP_BUY) ? Ask : Bid;
   double sl = 0, tp = 0;
   
   double pipValue = GetPipValue();
   
   // Local Swing SL calculation
   if(UseLocalSwingSL)
   {
      Print("═══ Calculating Local Swing SL ═══");
      
      if(orderType == OP_BUY)
      {
         double swingLow = FindLocalSwingLow(1);
         sl = swingLow - (SwingBufferPips * pipValue);
         
         double slDistance = (price - sl) / pipValue;
         if(slDistance < MinimumSLPips)
         {
            Print("   ⚠️ Calculated SL too close (", slDistance, " pips) - adjusting to minimum: ", MinimumSLPips);
            sl = price - (MinimumSLPips * pipValue);
         }
         
         Print("   ✅ BUY SL set at: ", sl, " | Distance: ", (price - sl) / pipValue, " pips");
         
         if(UseTakeProfit) tp = price + TakeProfitPips * pipValue;
      }
      else
      {
         double swingHigh = FindLocalSwingHigh(1);
         sl = swingHigh + (SwingBufferPips * pipValue);
         
         double slDistance = (sl - price) / pipValue;
         if(slDistance < MinimumSLPips)
         {
            Print("   ⚠️ Calculated SL too close (", slDistance, " pips) - adjusting to minimum: ", MinimumSLPips);
            sl = price + (MinimumSLPips * pipValue);
         }
         
         Print("   ✅ SELL SL set at: ", sl, " | Distance: ", (sl - price) / pipValue, " pips");
         
         if(UseTakeProfit) tp = price - TakeProfitPips * pipValue;
      }
   }
   else
   {
      // Fixed pip SL
      if(orderType == OP_BUY)
      {
         sl = price - StopLossPips * pipValue;
         if(UseTakeProfit) tp = price + TakeProfitPips * pipValue;
      }
      else
      {
         sl = price + StopLossPips * pipValue;
         if(UseTakeProfit) tp = price - TakeProfitPips * pipValue;
      }
      
      Print("   Using fixed SL: ", StopLossPips, " pips");
   }
   
   sl = NormalizeDouble(sl, Digits);
   tp = NormalizeDouble(tp, Digits);
   price = NormalizeDouble(price, Digits);
   
   color arrowColor = (orderType == OP_BUY) ? clrBlue : clrRed;
   
   int ticket = OrderSend(Symbol(), orderType, lotSize, price, 10, sl, tp, TradeComment, magic, 0, arrowColor);
   
   if(ticket > 0)
   {
      Print("Trade opened successfully: ", (orderType == OP_BUY ? "BUY" : "SELL"), " at ", price, 
            " | SL: ", sl, " | TP: ", tp, " | Lot: ", lotSize, " | Ticket: ", ticket,
            " | Out of Bounds: ", (isOutOfBounds ? "YES" : "NO"));
      
      // Capture the zone at bar 1 (where the signal occurred)
      int currentEntryZone = GetPriceZone(price, 1); 
      
      // Send that zone data to storage
      StoreEntryData(ticket, TimeCurrent(), price, orderType, magic, isOutOfBounds, currentEntryZone);
      
      // ═══════════════════════════════════════════════════════════
      // Smart sequence tracking for SL-based lockout
      // ═══════════════════════════════════════════════════════════
      if(UseSameColorDotLockout && LockoutActivationMode == ACTIVATE_AFTER_SL_HIT)
      {
         if(orderType == OP_BUY)
         {
            // Check if we need to start a NEW sequence
            bool needNewSequence = false;
            
            if(!greenSequenceActive)
            {
               needNewSequence = true;
            }
            else
            {
               // Sequence active, but is first trade still open?
               bool firstTradeStillOpen = false;
               for(int i = 0; i < OrdersTotal(); i++)
               {
                  if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
                  if(OrderTicket() == greenFirstTradeTicket)
                  {
                     firstTradeStillOpen = true;
                     break;
                  }
               }
               
               if(!firstTradeStillOpen)
               {
                  // First trade closed - start new sequence
                  needNewSequence = true;
                  Print("   🔄 Previous GREEN sequence ended - starting new one");
               }
            }
            
            if(needNewSequence)
            {
               greenSequenceActive = true;
               greenFirstTradeTicket = ticket;
               Print("   📌 This is the FIRST GREEN trade in NEW sequence (SL mode)");
               Print("      First Ticket: #", ticket);
            }
            else
            {
               Print("   📌 Additional GREEN trade in active sequence");
               Print("      First Ticket: #", greenFirstTradeTicket, " | This Ticket: #", ticket);
            }
         }
         else if(orderType == OP_SELL)
         {
            // Check if we need to start a NEW sequence
            bool needNewSequence = false;
            
            if(!pinkSequenceActive)
            {
               needNewSequence = true;
            }
            else
            {
               // Sequence active, but is first trade still open?
               bool firstTradeStillOpen = false;
               for(int i = 0; i < OrdersTotal(); i++)
               {
                  if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
                  if(OrderTicket() == pinkFirstTradeTicket)
                  {
                     firstTradeStillOpen = true;
                     break;
                  }
               }
               
               if(!firstTradeStillOpen)
               {
                  // First trade closed - start new sequence
                  needNewSequence = true;
                  Print("   🔄 Previous PINK sequence ended - starting new one");
               }
            }
            
            if(needNewSequence)
            {
               pinkSequenceActive = true;
               pinkFirstTradeTicket = ticket;
               Print("   📌 This is the FIRST PINK trade in NEW sequence (SL mode)");
               Print("      First Ticket: #", ticket);
            }
            else
            {
               Print("   📌 Additional PINK trade in active sequence");
               Print("      First Ticket: #", pinkFirstTradeTicket, " | This Ticket: #", ticket);
            }
         }
      }
   }
   else
   {
      Print("Trade failed! Error: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Calculate Aroon Indicator                                        |
//+------------------------------------------------------------------+
bool CalculateAroon()
{
   if(!UseAroonFilter) return true; // Skip if not enabled
   
   int bars = Bars;
   if(bars < AroonPeriod + 2) return true; // Not enough bars yet, skip silently
   ArrayResize(aroonUp, bars);
   ArraySetAsSeries(aroonUp, true);
   ArrayResize(aroonDown, bars);
   ArraySetAsSeries(aroonDown, true);
   
   for(int i = 0; i < bars - AroonPeriod - 1; i++)
   {
      // Find highest high and lowest low over AroonPeriod bars
      int highestBar = iHighest(Symbol(), Period(), MODE_HIGH, AroonPeriod + 1, i);
      int lowestBar  = iLowest (Symbol(), Period(), MODE_LOW,  AroonPeriod + 1, i);
      
      // Aroon Up = bars since highest high, expressed as % of period
      // Aroon Down = bars since lowest low, expressed as % of period
      aroonUp[i]   = (double)(AroonPeriod - (highestBar - i)) / AroonPeriod * 100.0;
      aroonDown[i] = (double)(AroonPeriod - (lowestBar  - i)) / AroonPeriod * 100.0;
   }
   return true;
}

//+------------------------------------------------------------------+
//| Close trade - MT4 VERSION                                        |
//+------------------------------------------------------------------+
void CloseTrade(int ticket)
{
   if(!OrderSelect(ticket, SELECT_BY_TICKET)) return;
   
   int orderType = OrderType();
   double lots = OrderLots();
   double closePrice = (orderType == OP_BUY) ? Bid : Ask;
   
   bool result = OrderClose(ticket, lots, closePrice, 10, clrWhite);
   
   if(result)
   {
      Print("Position closed successfully: #", ticket);
   }
   else
   {
      Print("Failed to close position #", ticket, " Error: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Calculate lot size based on money management                     |
//+------------------------------------------------------------------+
double CalculateLotSize()
{
   double lotSize = FixedLotSize;
   
   if(MoneyManagementType == MM_RISK_PERCENT)
   {
      double balance = AccountBalance();
      double riskAmount = balance * RiskPercent / 100.0;
      
      double pipValue = GetPipValue();
      
      double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
      double tickSize = MarketInfo(Symbol(), MODE_TICKSIZE);
      
      double moneyPerPip = (tickValue / tickSize) * pipValue;
      lotSize = riskAmount / (StopLossPips * moneyPerPip);
   }
   else if(MoneyManagementType == MM_FIXED_AMOUNT)
   {
      double pipValue = GetPipValue();
      
      double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
      double tickSize = MarketInfo(Symbol(), MODE_TICKSIZE);
      
      double moneyPerPip = (tickValue / tickSize) * pipValue;
      lotSize = FixedRiskAmount / (StopLossPips * moneyPerPip);
   }
   
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);
   double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   
   lotSize = MathFloor(lotSize / lotStep) * lotStep;
   lotSize = MathMax(minLot, MathMin(maxLot, lotSize));
   
   return NormalizeDouble(lotSize, 2);
}

//+------------------------------------------------------------------+
//| 🎯 INTELLIGENT PIP VALUE DETECTION - Enhanced                    |
//+------------------------------------------------------------------+
double GetPipValue()
{
   // Return cached value if available
   if(pipValueCached && detectedPipValue > 0)
      return detectedPipValue;
   
   double pipValue = 0;
   
   // ═══════════════════════════════════════════════════════════════
   // TIER 1: CHECK FOR MANUAL OVERRIDE (HIGHEST PRIORITY)
   // ═══════════════════════════════════════════════════════════════
   
   double manualOverride = GetSymbolPipOverride(Symbol());
   if(manualOverride > 0)
   {
      if(ShowPipDetectionInfo)
      {
         Print("═══════════════════════════════════════════════");
         Print("📊 MANUAL OVERRIDE ACTIVE");
         Print("   Symbol: ", Symbol());
         Print("   Override Pip Value: ", manualOverride);
         Print("   (Auto-detection SKIPPED)");
         Print("═══════════════════════════════════════════════");
      }
      
      pipValue = manualOverride;
   }
   else
   {
      // ════════════════════════════════════════════════════════════
      // TIER 2: INTELLIGENT AUTO-DETECTION
      // ════════════════════════════════════════════════════════════
      
      if(UseAutoPipDetection)
      {
         pipValue = DetectPipValueIntelligent();
      }
      else
      {
         // Fallback to basic digit-based detection
         pipValue = DetectPipValueBasic();
      }
      
      if(ShowPipDetectionInfo)
      {
         Print("📊 Using AUTO-DETECTED pip value: ", pipValue);
      }
   }
   
   // ═══════════════════════════════════════════════════════════════
   // TIER 3: SAFETY VALIDATION
   // ═══════════════════════════════════════════════════════════════
   
   if(pipValue <= 0 || pipValue > 1000)
   {
      Print("⚠️ WARNING: Pip value seems incorrect: ", pipValue);
      Print("   Falling back to basic Point-based calculation");
      pipValue = DetectPipValueBasic();
   }
   
   // Cache the result
   detectedPipValue = pipValue;
   pipValueCached = true;
   
   if(ShowPipDetectionInfo)
   {
      Print("═══════════════════════════════════════════════");
      Print("🎯 FINAL PIP VALUE");
      Print("   Symbol: ", Symbol());
      Print("   Digits: ", Digits);
      Print("   Point: ", Point);
      Print("   Final Pip Value: ", pipValue);
      
      // Show practical examples
      double exampleSL = 15.0;  // 15 pips
      double exampleDistance = exampleSL * pipValue;
      Print("   ──────────────────────────────");
      Print("   Example: ", exampleSL, " pips SL = $", DoubleToString(exampleDistance, 2), " distance");
      Print("═══════════════════════════════════════════════");
   }
   
   return pipValue;
}

//+------------------------------------------------------------------+
//| 🎯 Intelligent Pip Detection - Symbol Classification             |
//+------------------------------------------------------------------+
double DetectPipValueIntelligent()
{
   string symbol = Symbol();
   int digits = Digits;
   double point = Point;
   
   // ═══════════════════════════════════════════════════════════════
   // FOREX PAIRS - Most common
   // ═══════════════════════════════════════════════════════════════
   
   // Standard forex pairs (6 characters, no special prefixes)
   if(StringLen(symbol) == 6)
   {
      // Check if it's a currency pair (3-letter codes on each side)
      string base = StringSubstr(symbol, 0, 3);
      string quote = StringSubstr(symbol, 3, 3);
      
      if(IsCurrencyCode(base) && IsCurrencyCode(quote))
      {
         // JPY pairs use 2 decimal places (0.01 pip)
         if(quote == "JPY")
         {
            if(digits == 3) return 0.01;   // 3-digit broker
            if(digits == 2) return 0.01;   // 2-digit broker
            return point * 100;             // Fallback
         }
         else
         {
            // Standard pairs use 4/5 decimal places (0.0001 pip)
            if(digits == 5) return 0.0001;  // 5-digit broker
            if(digits == 4) return 0.0001;  // 4-digit broker
            if(digits == 3) return 0.001;   // 3-digit broker
            return point * 10;              // Fallback
         }
      }
   }
   
   // Forex pairs with prefixes/suffixes (e.g. EURUSDm, EURUSD.pro, #EURUSD)
   if(StringFind(symbol, "EUR") >= 0 || StringFind(symbol, "GBP") >= 0 || 
      StringFind(symbol, "USD") >= 0 || StringFind(symbol, "AUD") >= 0 ||
      StringFind(symbol, "NZD") >= 0 || StringFind(symbol, "CAD") >= 0 ||
      StringFind(symbol, "CHF") >= 0)
   {
      // Check for JPY
      if(StringFind(symbol, "JPY") >= 0)
      {
         if(digits == 3 || digits == 2) return 0.01;
         return point * 100;
      }
      else
      {
         if(digits == 5 || digits == 4) return 0.0001;
         if(digits == 3) return 0.001;
         return point * 10;
      }
   }
   
   // ═══════════════════════════════════════════════════════════════
   // PRECIOUS METALS
   // ═══════════════════════════════════════════════════════════════
   
   // Gold (XAUUSD, GOLD, etc.)
   if(StringFind(symbol, "XAU") >= 0 || StringFind(symbol, "GOLD") >= 0)
   {
      if(digits == 2) return 0.1;    // Most brokers
      if(digits == 3) return 0.1;    // Some brokers
      if(digits == 1) return 1.0;    // Rare
      return 0.1;                    // Default for gold
   }
   
   // Silver (XAGUSD, SILVER, etc.)
   if(StringFind(symbol, "XAG") >= 0 || StringFind(symbol, "SILVER") >= 0)
   {
      if(digits == 3) return 0.01;   // Most brokers
      if(digits == 4) return 0.01;   // Some brokers
      if(digits == 2) return 0.1;    // Rare
      return 0.01;                   // Default for silver
   }
   
   // Platinum
   if(StringFind(symbol, "XPT") >= 0 || StringFind(symbol, "PLATINUM") >= 0)
   {
      return 0.1;
   }
   
   // Palladium
   if(StringFind(symbol, "XPD") >= 0 || StringFind(symbol, "PALLADIUM") >= 0)
   {
      return 0.1;
   }
   
   // ═══════════════════════════════════════════════════════════════
   // INDICES
   // ═══════════════════════════════════════════════════════════════
   
   // US Indices
   if(StringFind(symbol, "US30") >= 0 || StringFind(symbol, "DOW") >= 0 || StringFind(symbol, "YM") >= 0)
      return 1.0;  // Dow Jones
   
   if(StringFind(symbol, "NAS100") >= 0 || StringFind(symbol, "NASDAQ") >= 0 || StringFind(symbol, "NQ") >= 0)
      return 1.0;  // Nasdaq
   
   if(StringFind(symbol, "SPX500") >= 0 || StringFind(symbol, "SP500") >= 0 || StringFind(symbol, "ES") >= 0)
      return 1.0;  // S&P 500
   
   if(StringFind(symbol, "US2000") >= 0 || StringFind(symbol, "RUSSELL") >= 0)
      return 1.0;  // Russell 2000
   
   // European Indices
   if(StringFind(symbol, "GER") >= 0 || StringFind(symbol, "DAX") >= 0)
      return 1.0;  // DAX
   
   if(StringFind(symbol, "UK100") >= 0 || StringFind(symbol, "FTSE") >= 0)
      return 1.0;  // FTSE
   
   if(StringFind(symbol, "FRA40") >= 0 || StringFind(symbol, "CAC") >= 0)
      return 1.0;  // CAC 40
   
   if(StringFind(symbol, "ESP35") >= 0 || StringFind(symbol, "IBEX") >= 0)
      return 1.0;  // IBEX 35
   
   // Asian Indices
   if(StringFind(symbol, "JPN225") >= 0 || StringFind(symbol, "NIKKEI") >= 0)
      return 1.0;  // Nikkei
   
   if(StringFind(symbol, "HK50") >= 0 || StringFind(symbol, "HSI") >= 0)
      return 1.0;  // Hang Seng
   
   // ═══════════════════════════════════════════════════════════════
   // CRYPTOCURRENCIES
   // ═══════════════════════════════════════════════════════════════
   
   // Bitcoin
   if(StringFind(symbol, "BTC") >= 0 || StringFind(symbol, "BITCOIN") >= 0)
   {
      if(digits == 2) return 1.0;    // Common
      if(digits == 1) return 10.0;   // Some brokers
      if(digits == 0) return 100.0;  // Rare
      return 1.0;                    // Default
   }
   
   // Ethereum
   if(StringFind(symbol, "ETH") >= 0 || StringFind(symbol, "ETHEREUM") >= 0)
   {
      if(digits == 2) return 0.1;    // Common
      if(digits == 3) return 0.1;    // Some brokers
      return 0.1;                    // Default
   }
   
   // Litecoin
   if(StringFind(symbol, "LTC") >= 0 || StringFind(symbol, "LITECOIN") >= 0)
   {
      if(digits == 2) return 0.1;
      return 0.1;
   }
   
   // Ripple
   if(StringFind(symbol, "XRP") >= 0 || StringFind(symbol, "RIPPLE") >= 0)
   {
      if(digits == 5) return 0.0001;
      if(digits == 4) return 0.001;
      return 0.0001;
   }
   
   // ═══════════════════════════════════════════════════════════════
   // OIL & COMMODITIES
   // ═══════════════════════════════════════════════════════════════
   
   if(StringFind(symbol, "OIL") >= 0 || StringFind(symbol, "WTI") >= 0 || StringFind(symbol, "BRENT") >= 0)
   {
      if(digits == 2) return 0.01;
      if(digits == 3) return 0.01;
      return 0.01;
   }
   
   // ═══════════════════════════════════════════════════════════════
   // FALLBACK - Use basic detection
   // ═══════════════════════════════════════════════════════════════
   
   return DetectPipValueBasic();
}

//+------------------------------------------------------------------+
//| 🎯 Basic Pip Detection - Digit-based (Original method)           |
//+------------------------------------------------------------------+
double DetectPipValueBasic()
{
   double pipValue = Point;
   
   // Standard forex digit adjustments
   if(Digits == 3 || Digits == 5) 
      pipValue *= 10;
   else if(Digits == 2)
      pipValue *= 10;
   else if(Digits == 1)
      pipValue *= 1;
   
   return pipValue;
}

//+------------------------------------------------------------------+
//| 🎯 Check if string is a valid currency code                      |
//+------------------------------------------------------------------+
bool IsCurrencyCode(string code)
{
   // Major currencies
   if(code == "EUR" || code == "USD" || code == "GBP" || code == "JPY" ||
      code == "AUD" || code == "NZD" || code == "CAD" || code == "CHF")
      return true;
   
   // Other common currencies
   if(code == "SEK" || code == "NOK" || code == "DKK" || code == "PLN" ||
      code == "HUF" || code == "CZK" || code == "SGD" || code == "HKD" ||
      code == "ZAR" || code == "MXN" || code == "TRY" || code == "CNH" ||
      code == "RUB" || code == "INR" || code == "BRL" || code == "KRW")
      return true;
   
   return false;
}

//+------------------------------------------------------------------+
//| 🎯 Parse Pip Value Overrides from input string                   |
//+------------------------------------------------------------------+
void ParsePipOverrides()
{
   totalPipOverrides = 0;
   ArrayResize(pipOverrides, 0);
   
   if(StringLen(PipValueOverrides) == 0)
   {
      if(ShowPipDetectionInfo)
         Print("ℹ️ No manual pip value overrides specified - using auto-detection");
      return;
   }
   
   if(ShowPipDetectionInfo)
   {
      Print("═══════════════════════════════════════════════");
      Print("📝 PARSING PIP VALUE OVERRIDES (ABSOLUTE MODE)");
      Print("   Input: ", PipValueOverrides);
   }
   
   // Split by comma
   string pairs[];
   int pairCount = StringSplit(PipValueOverrides, StringGetCharacter(",", 0), pairs);
   
   for(int i = 0; i < pairCount; i++)
   {
      string pair = pairs[i];
      
      // Trim whitespace
      StringTrimLeft(pair);
      StringTrimRight(pair);
      
      // Split by colon
      string parts[];
      int partCount = StringSplit(pair, StringGetCharacter(":", 0), parts);
      
      if(partCount != 2)
      {
         Print("⚠️ Invalid override format: '", pair, "' (expected SYMBOL:PIPVALUE)");
         Print("   Example: 'XAUUSD:0.1' or 'BTCUSD:1.0'");
         continue;
      }
      
      string symbolName = parts[0];
      StringTrimLeft(symbolName);
      StringTrimRight(symbolName);
      
      double pipValue = StringToDouble(parts[1]);
      
      if(pipValue <= 0)
      {
         Print("⚠️ Invalid pip value for ", symbolName, ": ", parts[1], " (must be > 0)");
         continue;
      }
      
      // Add to array
      ArrayResize(pipOverrides, totalPipOverrides + 1);
      pipOverrides[totalPipOverrides].symbol = symbolName;
      pipOverrides[totalPipOverrides].pipValue = pipValue;
      
      if(ShowPipDetectionInfo)
         Print("   ✅ Loaded: ", symbolName, " → ", pipValue, " (ABSOLUTE pip value)");
      
      totalPipOverrides++;
   }
   
   if(ShowPipDetectionInfo)
   {
      Print("   Total overrides: ", totalPipOverrides);
      Print("═══════════════════════════════════════════════");
   }
}

//+------------------------------------------------------------------+
//| 🎯 Get Pip Value Override for specific symbol (0 if not found)   |
//+------------------------------------------------------------------+
double GetSymbolPipOverride(string symbol)
{
   for(int i = 0; i < totalPipOverrides; i++)
   {
      if(pipOverrides[i].symbol == symbol)
      {
         return pipOverrides[i].pipValue;
      }
   }
   
   return 0;  // No override found
}

//+------------------------------------------------------------------+
//| Check if it's Friday close time                                  |
//+------------------------------------------------------------------+
bool IsFridayCloseTime()
{
   if(DayOfWeek() != 5) return false;
   
   string timeStr[];
   StringSplit(FridayCloseTime, StringGetCharacter(":", 0), timeStr);
   if(ArraySize(timeStr) != 2) return false;
   
   int closeHour = (int)StringToInteger(timeStr[0]);
   int closeMinute = (int)StringToInteger(timeStr[1]);
   
   if(Hour() > closeHour) return true;
   if(Hour() == closeHour && Minute() >= closeMinute) return true;
   
   return false;
}

//+------------------------------------------------------------------+
//| Close all trades - MT4 VERSION                                   |
//+------------------------------------------------------------------+
void CloseAllTrades()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      Print("Closing order #", OrderTicket());
      CloseTrade(OrderTicket());
   }
}

//+------------------------------------------------------------------+
//| Get open trades count - MT4 VERSION                              |
//+------------------------------------------------------------------+
int GetOpenTradesCount()
{
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic == MAGIC_BUY_GREEN || posMagic == MAGIC_SELL_PINK) count++;
   }
   return count;
}

//+------------------------------------------------------------------+
//| Store entry data when position opens                             |
//+------------------------------------------------------------------+
void StoreEntryData(int positionTicket, datetime entryTime, double entryPrice, 
                    int orderType, int magic, bool wasOutOfBounds, int entryZone)
{
   int size = ArraySize(activePositions); 
   ArrayResize(activePositions, size + 1); 
   
   activePositions[size].positionTicket = positionTicket; 
   activePositions[size].entryTime = entryTime;
   activePositions[size].entryPrice = entryPrice;
   activePositions[size].orderType = orderType;
   activePositions[size].magic = magic;
   activePositions[size].wasOutOfBounds = wasOutOfBounds;
   activePositions[size].entryZone = entryZone; // Correctly stores -4 to 4
}

//+------------------------------------------------------------------+
//| Find entry data from stored array                                |
//+------------------------------------------------------------------+
bool FindStoredEntryData(int positionTicket, TradeEntryData &entryData)
{
   for(int i = 0; i < ArraySize(activePositions); i++)
   {
      if(activePositions[i].positionTicket == positionTicket)
      {
         entryData = activePositions[i];
         return true;
      }
   }
   return false;
}

//+------------------------------------------------------------------+
//| Remove entry data after position closes                          |
//+------------------------------------------------------------------+
void RemoveEntryData(int positionTicket)
{
   for(int i = 0; i < ArraySize(activePositions); i++)
   {
      if(activePositions[i].positionTicket == positionTicket)
      {
         for(int j = i; j < ArraySize(activePositions) - 1; j++)
         {
            activePositions[j] = activePositions[j + 1];
         }
         ArrayResize(activePositions, ArraySize(activePositions) - 1);
         Print("🗑️ Removed entry data for position #", positionTicket);
         return;
      }
   }
}

//+------------------------------------------------------------------+
//| Get entry data from history (fallback method)                    |
//+------------------------------------------------------------------+
bool GetEntryDataFromHistory(int positionTicket, datetime &entryTime, double &entryPrice)
{
   if(!OrderSelect(positionTicket, SELECT_BY_TICKET, MODE_HISTORY))
   {
      Print("❌ ERROR: Cannot select order #", positionTicket, " from history!");
      return false;
   }
   
   entryTime = OrderOpenTime();
   entryPrice = OrderOpenPrice();
   
   Print("   ✅ Entry found from history: Price=", entryPrice, " Time=", entryTime);
   return true;
}

//+------------------------------------------------------------------+
//| Check for closed trades - ROBUST MT4 VERSION                     |
//+------------------------------------------------------------------+
void CheckClosedTrades()
{
   int currentPositionsCount = GetOpenTradesCount();
   
   if(currentPositionsCount >= lastKnownPositionsCount)
   {
      lastKnownPositionsCount = currentPositionsCount;
      return;
   }
   
   Print("═══════════════════════════════════════════════");
   Print("📉 Position count decreased: ", lastKnownPositionsCount, " → ", currentPositionsCount);
   Print("Analyzing closed positions...");
   
   // Check stored positions
   int processedPositions[];
   int processedCount = 0;
   
   for(int i = ArraySize(activePositions) - 1; i >= 0; i--)
   {
      int ticket = activePositions[i].positionTicket;
      
      // Check if this position still exists in open orders
      bool stillOpen = false;
      for(int j = 0; j < OrdersTotal(); j++)
      {
         if(!OrderSelect(j, SELECT_BY_POS, MODE_TRADES)) continue;
         if(OrderTicket() == ticket)
         {
            stillOpen = true;
            break;
         }
      }
      
      if(!stillOpen)
      {
         // Position closed - check if already processed
         bool alreadyProcessed = false;
         for(int k = 0; k < processedCount; k++)
         {
            if(processedPositions[k] == ticket)
            {
               alreadyProcessed = true;
               break;
            }
         }
         
         if(alreadyProcessed) continue;
         
         // Check if line already exists
         string lineName = objPrefix + "TRADELINE_" + IntegerToString(ticket);
         if(ObjectFind(lineName) >= 0)
         {
            Print("⚠️ Line already exists for #", ticket, " - skipping");
            continue;
         }
         
         // Mark as processed
         ArrayResize(processedPositions, processedCount + 1);
         processedPositions[processedCount] = ticket;
         processedCount++;
         
         Print("─────────────────────────────────────────────");
         Print("Processing closed position #", ticket);
         
         // Get entry data from storage
         TradeEntryData storedEntry;
         datetime entryTime = 0;
         double entryPrice = 0;
         bool wasOutOfBounds = false;
         int closedTradeEntryZone = 0; // Zone at time of entry (for zone lockout)

         if(FindStoredEntryData(ticket, storedEntry))
         {
            entryTime = storedEntry.entryTime;
            entryPrice = storedEntry.entryPrice;
            wasOutOfBounds = storedEntry.wasOutOfBounds;
            closedTradeEntryZone = storedEntry.entryZone; // Capture zone BEFORE removal
            Print("Entry data from STORED: ", entryPrice, " @ ", entryTime, 
                  " | Out of Bounds: ", (wasOutOfBounds ? "YES" : "NO"),
                  " | Zone: ", closedTradeEntryZone);
            
            RemoveEntryData(ticket);
         }
         else
         {
            Print("Entry not in stored data, checking history...");
            if(!GetEntryDataFromHistory(ticket, entryTime, entryPrice))
            {
               Print("ERROR: Could not find entry data for position #", ticket);
               continue;
            }
            wasOutOfBounds = false;
         }
         
         // Get exit data from history
         if(!OrderSelect(ticket, SELECT_BY_TICKET, MODE_HISTORY))
         {
            Print("❌ ERROR: Cannot select order #", ticket, " from history!");
            continue;
         }
         
         datetime exitTime = OrderCloseTime();
         double exitPrice = OrderClosePrice();
         int orderType = OrderType();
         double profit = OrderProfit();
         double swap = OrderSwap();
         double commission = OrderCommission();
         double totalProfit = profit + swap + commission;
         double orderSL = OrderStopLoss();
         
         // Accurate SL detection
         double slTolerance = 20 * Point;
         bool isSLHit = false;
         
         // Method 1: Price proximity check with directional validation
         if(orderType == OP_BUY && orderSL > 0)
         {
            if(exitPrice <= orderSL && MathAbs(exitPrice - orderSL) < slTolerance)
               isSLHit = true;
         }
         else if(orderType == OP_SELL && orderSL > 0)
         {
            if(exitPrice >= orderSL && MathAbs(exitPrice - orderSL) < slTolerance)
               isSLHit = true;
         }
         
         // Method 2: Check order comment for SL indicators
         if(!isSLHit)
         {
            string comment = OrderComment();
            if(StringFind(comment, "[sl]") >= 0 || 
               StringFind(comment, "sl") >= 0 ||
               StringFind(comment, "stop") >= 0)
            {
               isSLHit = true;
            }
         }
         
         string exitReason = "";
         if(isSLHit) exitReason = "Stop Loss";
         else if(totalProfit > 0) exitReason = "EA/Manual (Win)";
         else exitReason = "EA/Manual (Loss)";
         
         Print("Entry: ", entryPrice, " @ ", entryTime);
         Print("Exit: ", exitPrice, " @ ", exitTime);
         Print("P/L: ", totalProfit, " | Reason: ", exitReason);
         
         // Draw trade line
         DrawTradeLineRefactored(ticket, entryTime, entryPrice, 
                                 exitTime, exitPrice, orderType, 
                                 totalProfit, isSLHit, exitReason);
         
         // Draw exit marker
         string markerName = objPrefix + "EXIT_" + IntegerToString(ticket);
         
         if(ObjectFind(markerName) < 0)
         {
            if(isSLHit)
            {
               ObjectCreate(markerName, OBJ_ARROW, 0, exitTime, exitPrice);
               ObjectSet(markerName, OBJPROP_ARROWCODE, 251);
               ObjectSet(markerName, OBJPROP_COLOR, ExitLossColor);
               ObjectSet(markerName, OBJPROP_ANCHOR, ANCHOR_TOP);
               ObjectSet(markerName, OBJPROP_WIDTH, 4);
               ObjectSetText(markerName, "STOP LOSS | " + DoubleToString(totalProfit, 2), 8, "Arial", ExitLossColor);
            }
            else if(totalProfit > 0)
            {
               ObjectCreate(markerName, OBJ_ARROW, 0, exitTime, exitPrice);
               ObjectSet(markerName, OBJPROP_ARROWCODE, 252);
               ObjectSet(markerName, OBJPROP_COLOR, ExitWinColor);
               ObjectSet(markerName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
               ObjectSet(markerName, OBJPROP_WIDTH, 4);
               ObjectSetText(markerName, "WIN | " + DoubleToString(totalProfit, 2), 8, "Arial", ExitWinColor);
            }
         }
         
         // ═══════════════════════════════════════════════════════════
         // 🔒 ZONE-BASED SL LOCKOUT - trigger on SL hit
         // Locks the specific zone where the SL-hit trade was entered
         // ═══════════════════════════════════════════════════════════
         if(UseZoneLockout && isSLHit)
         {
            // Get the zone of the trade at entry time using stored entry data
            int lostZone = 0;
            TradeEntryData tmpStored;
            // storedEntry was already loaded above - use its entryZone
            // (note: storedEntry is in scope as 'storedEntry' from FindStoredEntryData above)
            // We need to recalculate since storedEntry was removed; use price at entry bar
            // Best we have is the entryPrice and the bar ATR at that time
            // Use GetPriceZone with bar 0 as fallback - but entryZone was stored!
            // Actually storedEntry.entryZone was set at trade open time - but RemoveEntryData
            // was called already. We need to save entryZone BEFORE removal.
            // FIX: we'll capture entryZone before RemoveEntryData. See patch below.
            lostZone = closedTradeEntryZone; // captured before removal (see patch)
            
            if(orderType == OP_BUY && lostZone < 0)
            {
               greenZoneLockout = lostZone;
               Print("═══════════════════════════════════════════════");
               Print("🔒 ZONE LOCKOUT ACTIVATED (BUY side)");
               Print("   SL hit in: ", GetZoneName(lostZone), " (zone ", lostZone, ")");
               Print("   Blocked: green dots in zone ", lostZone, " only");
               Print("   Unlock: green dot in any other zone");
               Print("═══════════════════════════════════════════════");
               panelNeedsFullRedraw = true;
               SaveStateToGlobalVariables();
            }
            else if(orderType == OP_SELL && lostZone > 0)
            {
               pinkZoneLockout = lostZone;
               Print("═══════════════════════════════════════════════");
               Print("🔒 ZONE LOCKOUT ACTIVATED (SELL side)");
               Print("   SL hit in: ", GetZoneName(lostZone), " (zone ", lostZone, ")");
               Print("   Blocked: pink dots in zone ", lostZone, " only");
               Print("   Unlock: pink dot in any other zone");
               Print("═══════════════════════════════════════════════");
               panelNeedsFullRedraw = true;
               SaveStateToGlobalVariables();
            }
         }
         
         // ═══════════════════════════════════════════════════════════
         // 🔥 DIAGNOSTIC: Show sequence state when SL detected
         // ═══════════════════════════════════════════════════════════
         if(UseSameColorDotLockout && LockoutActivationMode == ACTIVATE_AFTER_SL_HIT && isSLHit)
         {
            Print("┌─────────────────────────────────────────────────┐");
            Print("│ 🔍 SL-BASED LOCKOUT DIAGNOSTIC                  │");
            Print("├─────────────────────────────────────────────────┤");
            Print("│ Trade Ticket: #", ticket);
            Print("│ Order Type: ", (orderType == OP_BUY ? "BUY (GREEN)" : "SELL (PINK)"));
            Print("│ Exit Price: ", exitPrice, " | SL: ", orderSL);
            Print("│ Total Profit: ", totalProfit);
            
            if(orderType == OP_BUY)
            {
               Print("├─────────────────────────────────────────────────┤");
               Print("│ GREEN SEQUENCE STATUS:                          │");
               Print("│ • Sequence Active: ", (greenSequenceActive ? "YES ✅" : "NO ❌"));
               Print("│ • First Ticket: #", greenFirstTradeTicket);
               Print("│ • This Ticket: #", ticket);
               Print("│ • Is First Trade?: ", (IsFirstTradeOfSequence(ticket, orderType) ? "YES ✅" : "NO ❌"));
               Print("│ • Require First?: ", (SL_RequireFirstTrade ? "YES" : "NO (any SL)"));
               Print("│ • Current Lockout: ", (greenDotLockoutActive ? "ACTIVE 🔒" : "INACTIVE"));
            }
            else
            {
               Print("├─────────────────────────────────────────────────┤");
               Print("│ PINK SEQUENCE STATUS:                           │");
               Print("│ • Sequence Active: ", (pinkSequenceActive ? "YES ✅" : "NO ❌"));
               Print("│ • First Ticket: #", pinkFirstTradeTicket);
               Print("│ • This Ticket: #", ticket);
               Print("│ • Is First Trade?: ", (IsFirstTradeOfSequence(ticket, orderType) ? "YES ✅" : "NO ❌"));
               Print("│ • Require First?: ", (SL_RequireFirstTrade ? "YES" : "NO (any SL)"));
               Print("│ • Current Lockout: ", (pinkDotLockoutActive ? "ACTIVE 🔒" : "INACTIVE"));
            }
            
            Print("└─────────────────────────────────────────────────┘");
         }
         
         // ═══════════════════════════════════════════════════════════
         // NEW: Check for SL-based Same Color Lockout activation
         // ═══════════════════════════════════════════════════════════
         if(UseSameColorDotLockout && LockoutActivationMode == ACTIVATE_AFTER_SL_HIT)
         {
            if(isSLHit)
            {
               Print("   📊 Trade was ", (wasOutOfBounds ? "OUT OF BOUNDS" : "INSIDE BOUNDS"), " at entry");
               
               bool shouldActivateLockout = false;
               
               // Only activate lockout if trade was OUT OF BOUNDS
               if(wasOutOfBounds)
               {
                  if(SL_RequireFirstTrade)
                  {
                     if(IsFirstTradeOfSequence(ticket, orderType))
                     {
                        shouldActivateLockout = true;
                        Print("   SL Hit on FIRST out-of-bounds trade - activating lockout");
                     }
                     else
                     {
                        Print("   SL Hit on out-of-bounds trade, but NOT first trade - lockout not triggered");
                     }
                  }
                  else
                  {
                     shouldActivateLockout = true;
                     Print("   SL Hit on out-of-bounds trade - activating lockout");
                  }
               }
               else
               {
                  Print("   SL Hit on INSIDE-BOUNDS trade - lockout NOT triggered");
               }
               
               if(shouldActivateLockout)
               {
                  if(SL_CloseAllTrades)
                  {
                     CloseAllSameColorTrades(orderType);
                  }
                  ActivateSLBasedLockout(orderType);
               }
            }
         }
         
         // Update consecutive loss tracking
         if(totalProfit < 0)
         {
            consecutiveLosses++;
            lockoutDirection = orderType;
            Print("📊 Loss registered | Consecutive: ", consecutiveLosses);
            
            if(UseConsecutiveLossFilter && consecutiveLosses >= MaxConsecutiveLosses)
            {
               TriggerLockout();
            }
         }
         else if(totalProfit > 0)
         {
            if(consecutiveLosses > 0)
            {
               Print("📊 Win registered | Resetting consecutive losses from ", consecutiveLosses, " to 0");
               consecutiveLosses = 0;
               inLockout = false;
               lockoutDirection = -1;
            }
         }
         // 🔥 NEW: Save state after each trade closes
         SaveStateToGlobalVariables();
         
         Print("─────────────────────────────────────────────");
      }
   }
   
   lastKnownPositionsCount = currentPositionsCount;
   
   ChartRedraw();
   Print("═══════════════════════════════════════════════");
}

//+------------------------------------------------------------------+
//| Trigger lockout after consecutive losses                         |
//+------------------------------------------------------------------+
void TriggerLockout()
{
   if(inLockout) return;
   
   inLockout = true;
   lockoutStartTime = TimeCurrent();
   
   Print("═══════════════════════════════════════════════");
   Print("⚠️ LOCKOUT TRIGGERED! ", consecutiveLosses, " consecutive ", 
         (lockoutDirection == OP_BUY ? "BUY" : "SELL"), " losses");
   Print("Lockout Type: ", EnumToString(LockoutType));
   
   if(LockoutType == LOCKOUT_TIME_BASED || LockoutType == LOCKOUT_HYBRID)
   {
      Print("⏰ Max Lockout Period: ", LockoutHours, " hours");
      Print("🔒 Time unlock: ", TimeToString(lockoutStartTime + LockoutHours * 3600));
   }
   
   if(LockoutType == LOCKOUT_HTF_DOT || LockoutType == LOCKOUT_HYBRID)
   {
      string dotColor = (lockoutDirection == OP_BUY) ? "GREEN" : "PINK";
      Print("🔍 Waiting for ", IntegerToString(HTF_Timeframe), " ", dotColor, " dot confirmation");
      Print("   (All entry rules must be met on HTF)");
   }
   
   Print("═══════════════════════════════════════════════");
   
   DrawLockoutZone();
   
   if(ClosePositionsOnLockout)
   {
      Print("Closing all existing positions due to lockout...");
      CloseAllTrades();
   }
   
   // 🔥 NEW: Force panel redraw on lockout
   panelNeedsFullRedraw = true;
   
   // 🔥 NEW: Save lockout state
   SaveStateToGlobalVariables();
}

//+------------------------------------------------------------------+
//| Check if currently in lockout period                             |
//+------------------------------------------------------------------+
bool IsInLockout()
{
   if(!inLockout) return false;
   
   datetime currentTime = TimeCurrent();
   datetime lockoutEndTime = lockoutStartTime + (LockoutHours * 3600);
   
   if(LockoutType == LOCKOUT_TIME_BASED || LockoutType == LOCKOUT_HYBRID)
   {
      if(currentTime >= lockoutEndTime)
      {
         Print("═══════════════════════════════════════════════");
         Print("✅ TIME-BASED LOCKOUT EXPIRED - Resuming normal operations");
         Print("Consecutive losses reset to 0");
         Print("═══════════════════════════════════════════════");
         inLockout = false;
         consecutiveLosses = 0;
         lockoutDirection = -1;
         return false;
      }
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Get remaining lockout time in hours                              |
//+------------------------------------------------------------------+
double GetLockoutTimeRemaining()
{
   if(!inLockout) return 0;
   
   datetime currentTime = TimeCurrent();
   datetime lockoutEndTime = lockoutStartTime + (LockoutHours * 3600);
   
   int remainingSeconds = (int)(lockoutEndTime - currentTime);
   return (double)remainingSeconds / 3600.0;
}

//+------------------------------------------------------------------+
//| Check for HTF confirmation to unlock                             |
//+------------------------------------------------------------------+
void CheckHTFConfirmation()
{
   if(!inLockout) return;
   if(ArraySize(htfAtrMA) < 2 || ArraySize(htfPtlArrowUp) < 2) return;
   
   double htfClose1 = iClose(Symbol(), HTF_Timeframe, 1);
   double htfHigh1 = iHigh(Symbol(), HTF_Timeframe, 1);
   double htfLow1 = iLow(Symbol(), HTF_Timeframe, 1);
   
   double htfMidline1 = htfAtrMA[1];
   double htfGreenDot1 = htfPtlArrowUp[1];
   double htfPinkDot1 = htfPtlArrowDown[1];
   
   bool confirmationFound = false;
   string confirmationType = "";
   
   if(lockoutDirection == OP_BUY && htfGreenDot1 != EMPTY_VALUE)
   {
      if(htfClose1 < htfMidline1 && htfHigh1 < htfMidline1)
      {
         confirmationFound = true;
         confirmationType = IntegerToString(HTF_Timeframe) + " GREEN dot (valid BUY setup)";
      }
   }
   
   if(lockoutDirection == OP_SELL && htfPinkDot1 != EMPTY_VALUE)
   {
      if(htfClose1 > htfMidline1 && htfLow1 > htfMidline1)
      {
         confirmationFound = true;
         confirmationType = IntegerToString(HTF_Timeframe) + " PINK dot (valid SELL setup)";
      }
   }
   
   if(confirmationFound)
   {
      Print("═══════════════════════════════════════════════");
      Print("✅ HTF CONFIRMATION RECEIVED!");
      Print("Signal: ", confirmationType);
      Print("LOCKOUT RELEASED - Resuming normal operations");
      Print("Consecutive losses reset to 0");
      Print("═══════════════════════════════════════════════");
      
      inLockout = false;
      consecutiveLosses = 0;
      lockoutDirection = -1;
      panelNeedsFullRedraw = true;
   }
}

//+------------------------------------------------------------------+
//| Check if entire bar is below lower band                          |
//+------------------------------------------------------------------+
bool IsEntireBarBelowBand(int barIndex)
{
   if(ArraySize(atrLowerBand) <= barIndex) return false;
   
   double open = Open[barIndex];
   double high = High[barIndex];
   double low = Low[barIndex];
   double close = Close[barIndex];
   double lowerBand = atrLowerBand[barIndex];
   
   bool allBelow = (open < lowerBand && 
                    high < lowerBand && 
                    low < lowerBand && 
                    close < lowerBand);
   
   if(allBelow)
   {
      Print("   📊 Entire OHLC bar BELOW lower band");
      Print("      O:", open, " H:", high, " L:", low, " C:", close);
      Print("      Lower Band: ", lowerBand);
   }
   
   return allBelow;
}

//+------------------------------------------------------------------+
//| Check if entire bar is above upper band                          |
//+------------------------------------------------------------------+
bool IsEntireBarAboveBand(int barIndex)
{
   if(ArraySize(atrUpperBand) <= barIndex) return false;
   
   double open = Open[barIndex];
   double high = High[barIndex];
   double low = Low[barIndex];
   double close = Close[barIndex];
   double upperBand = atrUpperBand[barIndex];
   
   bool allAbove = (open > upperBand && 
                    high > upperBand && 
                    low > upperBand && 
                    close > upperBand);
   
   if(allAbove)
   {
      Print("   📊 Entire OHLC bar ABOVE upper band");
      Print("      O:", open, " H:", high, " L:", low, " C:", close);
      Print("      Upper Band: ", upperBand);
   }
   
   return allAbove;
}

//+------------------------------------------------------------------+
//| Check if close is inside ATR bands                               |
//+------------------------------------------------------------------+
bool IsCloseInsideBands(int barIndex)
{
   if(ArraySize(atrUpperBand) <= barIndex || ArraySize(atrLowerBand) <= barIndex) 
      return false;
   
   double close = Close[barIndex];
   double upperBand = atrUpperBand[barIndex];
   double lowerBand = atrLowerBand[barIndex];
   
   bool inside = (close > lowerBand && close < upperBand);
   
   if(inside)
   {
      Print("   ✅ Close INSIDE bands");
      Print("      Close: ", close);
      Print("      Bands: [", lowerBand, " - ", upperBand, "]");
   }
   
   return inside;
}

//+------------------------------------------------------------------+
//| Check if ENTIRE OHLC bar is inside ATR bands                     |
//+------------------------------------------------------------------+
bool IsEntireBarInsideBands(int barIndex)
{
   if(ArraySize(atrUpperBand) <= barIndex || ArraySize(atrLowerBand) <= barIndex) 
      return false;
   
   double open = Open[barIndex];
   double high = High[barIndex];
   double low = Low[barIndex];
   double close = Close[barIndex];
   double upperBand = atrUpperBand[barIndex];
   double lowerBand = atrLowerBand[barIndex];
   
   bool allInside = (open > lowerBand && open < upperBand &&
                     high > lowerBand && high < upperBand &&
                     low > lowerBand && low < upperBand &&
                     close > lowerBand && close < upperBand);
   
   if(allInside)
   {
      Print("   ✅ ENTIRE OHLC bar INSIDE bands");
      Print("      O:", open, " H:", high, " L:", low, " C:", close);
      Print("      Bands: [", lowerBand, " - ", upperBand, "]");
   }
   else
   {
      Print("   ⚠️ Bar NOT entirely inside bands");
      Print("      O:", open, " H:", high, " L:", low, " C:", close);
      Print("      Bands: [", lowerBand, " - ", upperBand, "]");
   }
   
   return allInside;
}

//+------------------------------------------------------------------+
//| Check if same color lockout expired by time                      |
//+------------------------------------------------------------------+
bool IsSameColorLockoutExpired(datetime startTime)
{
   if(SameColorLockoutMaxHours == 0) return false;
   
   datetime currentTime = TimeCurrent();
   datetime expiryTime = startTime + (SameColorLockoutMaxHours * 3600);
   
   return (currentTime >= expiryTime);
}

//+------------------------------------------------------------------+
//| Draw same color lockout zone on chart                            |
//+------------------------------------------------------------------+
void DrawSameColorLockoutZone(bool isGreen)
{
   if(!ShowSameColorLockoutZones) return;
   
   string lockoutName = objPrefix + "SameColorLockout_" + 
                       (isGreen ? "GREEN_" : "PINK_") + 
                       TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES);
   
   datetime startTime = isGreen ? greenLockoutStartTime : pinkLockoutStartTime;
   datetime endTime = TimeCurrent() + (24 * 3600);
   
   double highPrice = WindowPriceMax();
   double lowPrice = WindowPriceMin();
   
   ObjectCreate(lockoutName, OBJ_RECTANGLE, 0, startTime, highPrice, endTime, lowPrice);
   ObjectSet(lockoutName, OBJPROP_COLOR, isGreen ? GreenLockoutColor : PinkLockoutColor);
   ObjectSet(lockoutName, OBJPROP_BACK, true);
   ObjectSet(lockoutName, OBJPROP_SELECTABLE, false);
   ObjectSet(lockoutName, OBJPROP_WIDTH, 0);
   
   string labelName = objPrefix + "SameColorLockoutText_" + 
                     (isGreen ? "GREEN_" : "PINK_") + 
                     TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES);
   
   datetime labelTime = startTime + ((endTime - startTime) / 4);
   double labelPrice = (highPrice + lowPrice) / 2;
   
   string labelText = isGreen ? "🔒 GREEN DOT LOCKOUT" : "🔒 PINK DOT LOCKOUT";
   if(WholeBarUnlock)
      labelText += "\nWaiting for WHOLE bar inside bands";
   else
      labelText += "\nWaiting for close inside bands";
   
   if(SameColorLockoutMaxHours > 0)
   {
      labelText += "\nMax: " + IntegerToString(SameColorLockoutMaxHours) + "h";
   }
   
   ObjectCreate(labelName, OBJ_TEXT, 0, labelTime, labelPrice);
   ObjectSetText(labelName, labelText, 10, "Arial Bold", clrYellow);
   
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| Parse time string "HH:MM" to hour and minute integers            |
//+------------------------------------------------------------------+
bool ParseTimeString(string timeStr, int &hour, int &minute)
{
   string parts[];
   int count = StringSplit(timeStr, StringGetCharacter(":", 0), parts);
   
   if(count != 2)
   {
      Print("ERROR: Invalid time format '", timeStr, "' - use HH:MM");
      return false;
   }
   
   hour = (int)StringToInteger(parts[0]);
   minute = (int)StringToInteger(parts[1]);
   
   if(hour < 0 || hour > 23 || minute < 0 || minute > 59)
   {
      Print("ERROR: Time out of range '", timeStr, "' - hour must be 0-23, minute 0-59");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Check if current time is within a time range (handles overnight) |
//+------------------------------------------------------------------+
bool IsTimeInRange(string startTimeStr, string endTimeStr)
{
   int startHour, startMin, endHour, endMin;
   
   if(!ParseTimeString(startTimeStr, startHour, startMin)) return false;
   if(!ParseTimeString(endTimeStr, endHour, endMin)) return false;
   
   int currentMinutes = Hour() * 60 + Minute();
   int startMinutes = startHour * 60 + startMin;
   int endMinutes = endHour * 60 + endMin;
   
   if(endMinutes < startMinutes)
   {
      return (currentMinutes >= startMinutes || currentMinutes < endMinutes);
   }
   else
   {
      return (currentMinutes >= startMinutes && currentMinutes < endMinutes);
   }
}

//+------------------------------------------------------------------+
//| Check if within daily trading hours                              |
//+------------------------------------------------------------------+
bool IsWithinDailyTradingHours()
{
   if(!UseDailyTradingHours) return true;
   
   return IsTimeInRange(DailyStartTime, DailyStopTime);
}

//+------------------------------------------------------------------+
//| Master check: Can we enter new trades right now?                 |
//+------------------------------------------------------------------+
bool CanTradeNow()
{
   if(!IsWithinDailyTradingHours()) return false;
   
   return true;
}

//+------------------------------------------------------------------+
//| Check if we should close all trades due to time restrictions     |
//+------------------------------------------------------------------+
bool ShouldCloseAllTradesNow()
{
   bool closeNow = false;
   string reason = "";
   
   if(UseDailyTradingHours && CloseTradesAtDailyStop)
   {
      if(!IsWithinDailyTradingHours() && wasInTradingHours)
      {
         closeNow = true;
         reason = "Daily stop time reached (" + DailyStopTime + ")";
      }
   }
   
   if(closeNow)
   {
      Print("═══════════════════════════════════════════════");
      Print("⏰ TIME RESTRICTION TRIGGERED");
      Print("Reason: ", reason);
      Print("Closing all open positions...");
      Print("═══════════════════════════════════════════════");
   }
   
   return closeNow;
}

//+------------------------------------------------------------------+
//| Check if we can manage exits during off-hours                    |
//+------------------------------------------------------------------+
bool CanManageExitsNow()
{
   if(CanTradeNow()) return true;
   
   if(UseDailyTradingHours && !IsWithinDailyTradingHours())
   {
      if(!AllowExitsDuringStopTime) return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| INCREMENTAL DRAWING - Draw only new bars                         |
//+------------------------------------------------------------------+
void DrawNewBars()
{
   datetime currentBarTime = Time[1];
   
   if(currentBarTime <= lastDrawnBarTime && lastDrawnBarTime != 0)
      return;
   
   if(lastDrawnBarTime == 0)
   {
      DrawInitialWindow();
      lastDrawnBarTime = currentBarTime;
      return;
   }
   
   int newBars = 0;
   for(int i = 0; i < 100; i++)
   {
      datetime barTime = Time[i];
      if(barTime <= lastDrawnBarTime) break;
      newBars++;
   }
   
   if(newBars == 0) return;
   
   for(int i = newBars - 1; i >= 1; i--)
   {
      if(ShowATRBands) DrawSingleBarATR(i);
      if(ShowPTLLines) DrawSingleBarPTL(i);
      if(ShowPTLArrows) DrawSingleBarArrows(i);
      totalDrawnObjects += 7;
   }
   
   lastDrawnBarTime = currentBarTime;
   if(oldestDrawnBarTime == 0)
      oldestDrawnBarTime = Time[newBars - 1];
   
   if(DrawingMode == DRAWING_ACCUMULATE_LIMITED)
   {
      CheckAndCleanupLimits();
   }
   else if(DrawingMode == DRAWING_ROLLING_WINDOW)
   {
      CleanupRollingWindow();
   }
   
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| Draw initial window on startup                                   |
//+------------------------------------------------------------------+
void DrawInitialWindow()
{
   int barsToShow = DrawBarsBack;
   int totalBars = Bars;
   
   if(DrawingMode == DRAWING_ROLLING_WINDOW)
   {
      barsToShow = MathMin(DrawBarsBack, totalBars - 1);
   }
   else
   {
      barsToShow = MathMin(5000, totalBars - 1);
   }
   
   Print("Drawing initial window: ", barsToShow, " bars");
   
   for(int i = barsToShow; i >= 1; i--)
   {
      if(ShowATRBands) DrawSingleBarATR(i);
      if(ShowPTLLines) DrawSingleBarPTL(i);
      if(ShowPTLArrows) DrawSingleBarArrows(i);
   }
   
   totalDrawnObjects = barsToShow * 7;
   oldestDrawnBarTime = Time[barsToShow];
   
   Print("Initial drawing complete - ", totalDrawnObjects, " objects drawn");
}

//+------------------------------------------------------------------+
//| Draw single bar ATR channels - MT4 VERSION                       |
//+------------------------------------------------------------------+
void DrawSingleBarATR(int barIndex)
{
   int arraySize = ArraySize(atrMA);
   if(barIndex >= arraySize - 1) return;
   
   datetime time1 = Time[barIndex];
   datetime time2 = Time[barIndex - 1];
   string ts = TimeToString(time1, TIME_DATE|TIME_MINUTES);
   
   // Midline
   string nameMid = objPrefix + "ATR_Mid_" + ts;
   if(ObjectFind(nameMid) < 0)
   {
      ObjectCreate(nameMid, OBJ_TREND, 0, time2, atrMA[barIndex-1], time1, atrMA[barIndex]);
      ObjectSet(nameMid, OBJPROP_COLOR, ATR_MidlineColor);
      ObjectSet(nameMid, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(nameMid, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(nameMid, OBJPROP_RAY, false);
      ObjectSet(nameMid, OBJPROP_SELECTABLE, false);
      ObjectSet(nameMid, OBJPROP_BACK, true);
   }
   
   // Band 1 upper (2.5x)
   string nameU1 = objPrefix + "ATR_U1_" + ts;
   if(ObjectFind(nameU1) < 0)
   {
      ObjectCreate(nameU1, OBJ_TREND, 0, time2, atrUpper1[barIndex-1], time1, atrUpper1[barIndex]);
      ObjectSet(nameU1, OBJPROP_COLOR, ATR_BandColor);
      ObjectSet(nameU1, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(nameU1, OBJPROP_STYLE, STYLE_DOT);
      ObjectSet(nameU1, OBJPROP_RAY, false);
      ObjectSet(nameU1, OBJPROP_SELECTABLE, false);
      ObjectSet(nameU1, OBJPROP_BACK, true);
   }
   
   // Band 1 lower (2.5x)
   string nameL1 = objPrefix + "ATR_L1_" + ts;
   if(ObjectFind(nameL1) < 0)
   {
      ObjectCreate(nameL1, OBJ_TREND, 0, time2, atrLower1[barIndex-1], time1, atrLower1[barIndex]);
      ObjectSet(nameL1, OBJPROP_COLOR, ATR_BandColor);
      ObjectSet(nameL1, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(nameL1, OBJPROP_STYLE, STYLE_DOT);
      ObjectSet(nameL1, OBJPROP_RAY, false);
      ObjectSet(nameL1, OBJPROP_SELECTABLE, false);
      ObjectSet(nameL1, OBJPROP_BACK, true);
   }
   
   // Band 2 upper (4.5x)
   string nameU2 = objPrefix + "ATR_U2_" + ts;
   if(ObjectFind(nameU2) < 0)
   {
      ObjectCreate(nameU2, OBJ_TREND, 0, time2, atrUpper2[barIndex-1], time1, atrUpper2[barIndex]);
      ObjectSet(nameU2, OBJPROP_COLOR, ATR_BandColor);
      ObjectSet(nameU2, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(nameU2, OBJPROP_STYLE, STYLE_DOT);
      ObjectSet(nameU2, OBJPROP_RAY, false);
      ObjectSet(nameU2, OBJPROP_SELECTABLE, false);
      ObjectSet(nameU2, OBJPROP_BACK, true);
   }
   
   // Band 2 lower (4.5x)
   string nameL2 = objPrefix + "ATR_L2_" + ts;
   if(ObjectFind(nameL2) < 0)
   {
      ObjectCreate(nameL2, OBJ_TREND, 0, time2, atrLower2[barIndex-1], time1, atrLower2[barIndex]);
      ObjectSet(nameL2, OBJPROP_COLOR, ATR_BandColor);
      ObjectSet(nameL2, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(nameL2, OBJPROP_STYLE, STYLE_DOT);
      ObjectSet(nameL2, OBJPROP_RAY, false);
      ObjectSet(nameL2, OBJPROP_SELECTABLE, false);
      ObjectSet(nameL2, OBJPROP_BACK, true);
   }
   
   // Band 3 upper (6.5x) - solid outer
   string nameU3 = objPrefix + "ATR_U3_" + ts;
   if(ObjectFind(nameU3) < 0)
   {
      ObjectCreate(nameU3, OBJ_TREND, 0, time2, atrUpper3[barIndex-1], time1, atrUpper3[barIndex]);
      ObjectSet(nameU3, OBJPROP_COLOR, ATR_BandColor);
      ObjectSet(nameU3, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(nameU3, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(nameU3, OBJPROP_RAY, false);
      ObjectSet(nameU3, OBJPROP_SELECTABLE, false);
      ObjectSet(nameU3, OBJPROP_BACK, true);
   }
   
   // Band 3 lower (6.5x) - solid outer
   string nameL3 = objPrefix + "ATR_L3_" + ts;
   if(ObjectFind(nameL3) < 0)
   {
      ObjectCreate(nameL3, OBJ_TREND, 0, time2, atrLower3[barIndex-1], time1, atrLower3[barIndex]);
      ObjectSet(nameL3, OBJPROP_COLOR, ATR_BandColor);
      ObjectSet(nameL3, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(nameL3, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(nameL3, OBJPROP_RAY, false);
      ObjectSet(nameL3, OBJPROP_SELECTABLE, false);
      ObjectSet(nameL3, OBJPROP_BACK, true);
   }
}

//+------------------------------------------------------------------+
//| Draw single bar PTL lines - MT4 VERSION                          |
//+------------------------------------------------------------------+
void DrawSingleBarPTL(int barIndex)
{
   int arraySize = ArraySize(ptlLine1);
   if(barIndex >= arraySize - 1) return;
   
   datetime time1 = Time[barIndex];
   datetime time2 = Time[barIndex - 1];
   
   string nameSlow = objPrefix + "PTL_Slow_" + TimeToString(time1, TIME_DATE|TIME_MINUTES);
   if(ObjectFind(nameSlow) < 0)
   {
      ObjectCreate(nameSlow, OBJ_TREND, 0, time2, ptlLine1[barIndex-1], time1, ptlLine1[barIndex]);
      ObjectSet(nameSlow, OBJPROP_COLOR, PTL_SlowColor);
      ObjectSet(nameSlow, OBJPROP_WIDTH, PTL_LineWidth);
      ObjectSet(nameSlow, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(nameSlow, OBJPROP_RAY, false);
      ObjectSet(nameSlow, OBJPROP_SELECTABLE, false);
      ObjectSet(nameSlow, OBJPROP_BACK, true);
   }
   
   string nameFast = objPrefix + "PTL_Fast_" + TimeToString(time1, TIME_DATE|TIME_MINUTES);
   if(ObjectFind(nameFast) < 0)
   {
      ObjectCreate(nameFast, OBJ_TREND, 0, time2, ptlLine2[barIndex-1], time1, ptlLine2[barIndex]);
      ObjectSet(nameFast, OBJPROP_COLOR, PTL_FastColor);
      ObjectSet(nameFast, OBJPROP_WIDTH, PTL_LineWidth);
      ObjectSet(nameFast, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(nameFast, OBJPROP_RAY, false);
      ObjectSet(nameFast, OBJPROP_SELECTABLE, false);
      ObjectSet(nameFast, OBJPROP_BACK, true);
   }
}

//+------------------------------------------------------------------+
//| Draw single bar arrows - MT4 VERSION                             |
//+------------------------------------------------------------------+
void DrawSingleBarArrows(int barIndex)
{
   int arraySize = ArraySize(ptlArrowUp);
   if(barIndex >= arraySize) return;
   
   datetime time1 = Time[barIndex];
   
   if(ptlArrowUp[barIndex] != EMPTY_VALUE)
   {
      string nameUp = objPrefix + "Arrow_Up_" + TimeToString(time1, TIME_DATE|TIME_MINUTES);
      if(ObjectFind(nameUp) < 0)
      {
         ObjectCreate(nameUp, OBJ_ARROW, 0, time1, ptlArrowUp[barIndex]);
         ObjectSet(nameUp, OBJPROP_COLOR, ArrowUpColor);
         ObjectSet(nameUp, OBJPROP_ARROWCODE, ArrowCodeUp);
         ObjectSet(nameUp, OBJPROP_WIDTH, ArrowSize);
         ObjectSet(nameUp, OBJPROP_ANCHOR, ANCHOR_TOP);
         ObjectSet(nameUp, OBJPROP_SELECTABLE, false);
         ObjectSet(nameUp, OBJPROP_BACK, false);
      }
   }
   
   if(ptlArrowDown[barIndex] != EMPTY_VALUE)
   {
      string nameDn = objPrefix + "Arrow_Dn_" + TimeToString(time1, TIME_DATE|TIME_MINUTES);
      if(ObjectFind(nameDn) < 0)
      {
         ObjectCreate(nameDn, OBJ_ARROW, 0, time1, ptlArrowDown[barIndex]);
         ObjectSet(nameDn, OBJPROP_COLOR, ArrowDownColor);
         ObjectSet(nameDn, OBJPROP_ARROWCODE, ArrowCodeDown);
         ObjectSet(nameDn, OBJPROP_WIDTH, ArrowSize);
         ObjectSet(nameDn, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
         ObjectSet(nameDn, OBJPROP_SELECTABLE, false);
         ObjectSet(nameDn, OBJPROP_BACK, false);
      }
   }
}

//+------------------------------------------------------------------+
//| Check and cleanup if limits exceeded (LIMITED mode)              |
//+------------------------------------------------------------------+
void CheckAndCleanupLimits()
{
   int currentObjectCount = CountOurObjects();
   datetime currentTime = TimeCurrent();
   datetime oldestAllowedTime = currentTime - (MaxDrawingDays * 86400);
   
   bool needsCleanup = false;
   string cleanupReason = "";
   
   if(currentObjectCount > MaxDrawingObjects)
   {
      needsCleanup = true;
      cleanupReason = "Object limit exceeded (" + IntegerToString(currentObjectCount) + "/" + IntegerToString(MaxDrawingObjects) + ")";
   }
   
   if(oldestDrawnBarTime < oldestAllowedTime)
   {
      needsCleanup = true;
      cleanupReason += (cleanupReason != "" ? " | " : "") + "Time limit exceeded (" + IntegerToString(MaxDrawingDays) + " days)";
   }
   
   if(needsCleanup)
   {
      Print("Cleanup triggered: ", cleanupReason);
      CleanupOldestObjects();
   }
}

//+------------------------------------------------------------------+
//| Cleanup oldest objects to maintain limits                        |
//+------------------------------------------------------------------+
void CleanupOldestObjects()
{
   datetime cutoffTime = TimeCurrent() - ((MaxDrawingDays - 2) * 86400);
   int deletedCount = 0;
   
   int totalObjects = ObjectsTotal();
   
   for(int i = totalObjects - 1; i >= 0; i--)
   {
      string objName = ObjectName(i);
      
      if(StringFind(objName, objPrefix) == 0)
      {
         datetime objTime = (datetime)ObjectGet(objName, OBJPROP_TIME1);
         
         if(objTime < cutoffTime)
         {
            ObjectDelete(objName);
            deletedCount++;
         }
      }
   }
   
   oldestDrawnBarTime = cutoffTime;
   totalDrawnObjects -= deletedCount;
   
   Print("Cleaned up ", deletedCount, " old objects. Remaining: ", totalDrawnObjects);
}

//+------------------------------------------------------------------+
//| Cleanup for rolling window mode                                  |
//+------------------------------------------------------------------+
void CleanupRollingWindow()
{
   datetime cutoffTime = Time[DrawBarsBack];
   int deletedCount = 0;
   
   int totalObjects = ObjectsTotal();
   
   for(int i = totalObjects - 1; i >= 0; i--)
   {
      string objName = ObjectName(i);
      
      if(StringFind(objName, objPrefix) == 0)
      {
         if(StringFind(objName, "ENTRY_") >= 0 || 
            StringFind(objName, "EXIT_") >= 0 ||
            StringFind(objName, "TradeInfoPanel") >= 0 ||
            StringFind(objName, "Lockout") >= 0)
            continue;
         
         datetime objTime = (datetime)ObjectGet(objName, OBJPROP_TIME1);
         
         if(objTime < cutoffTime)
         {
            ObjectDelete(objName);
            deletedCount++;
         }
      }
   }
   
   if(deletedCount > 0)
   {
      oldestDrawnBarTime = cutoffTime;
      totalDrawnObjects -= deletedCount;
   }
}

//+------------------------------------------------------------------+
//| Count our drawing objects                                        |
//+------------------------------------------------------------------+
int CountOurObjects()
{
   int count = 0;
   int totalObjects = ObjectsTotal();
   
   for(int i = 0; i < totalObjects; i++)
   {
      string objName = ObjectName(i);
      if(StringFind(objName, objPrefix) == 0)
         count++;
   }
   
   return count;
}

//+------------------------------------------------------------------+
//| Draw entry marker - MT4 VERSION                                  |
//+------------------------------------------------------------------+
void DrawEntryMarker(int bar, int orderType, double price)
{
   datetime time1 = Time[bar];
   string name = objPrefix + "ENTRY_" + TimeToString(time1, TIME_DATE|TIME_MINUTES);
   
   double pipValue = GetPipValue();
   
   double offsetDistance = EntryArrowOffset * pipValue;
   double arrowPrice;
   
   ObjectDelete(name);
   
   if(orderType == OP_BUY)
   {
      arrowPrice = price - offsetDistance;
      
      ObjectCreate(name, OBJ_ARROW, 0, time1, arrowPrice);
      ObjectSet(name, OBJPROP_ARROWCODE, 233);
      ObjectSet(name, OBJPROP_COLOR, clrDodgerBlue);
      ObjectSet(name, OBJPROP_WIDTH, 4);
      ObjectSet(name, OBJPROP_ANCHOR, ANCHOR_TOP);
      ObjectSetText(name, "BUY Entry - Green Dot Signal", 8, "Arial", clrDodgerBlue);
   }
   else
   {
      arrowPrice = price + offsetDistance;
      
      ObjectCreate(name, OBJ_ARROW, 0, time1, arrowPrice);
      ObjectSet(name, OBJPROP_ARROWCODE, 234);
      ObjectSet(name, OBJPROP_COLOR, clrOrangeRed);
      ObjectSet(name, OBJPROP_WIDTH, 4);
      ObjectSet(name, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
      ObjectSetText(name, "SELL Entry - Pink Dot Signal", 8, "Arial", clrOrangeRed);
   }
   
   ObjectSet(name, OBJPROP_SELECTABLE, true);
   ObjectSet(name, OBJPROP_BACK, false);
   
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| Draw trade line - MT4 VERSION                                    |
//+------------------------------------------------------------------+
void DrawTradeLineRefactored(int positionTicket, 
                             datetime entryTime, double entryPrice,
                             datetime exitTime, double exitPrice,
                             int posType,
                             double profit, bool isSLHit, string exitReason)
{
   if(!ShowTradeLines) return;
   
   string lineName = objPrefix + "TRADELINE_" + IntegerToString(positionTicket);
   
   if(ObjectFind(lineName) >= 0)
   {
      Print("⚠️ Line already exists for position #", positionTicket);
      return;
   }
   
   if(!ObjectCreate(lineName, OBJ_TREND, 0, entryTime, entryPrice, exitTime, exitPrice))
   {
      Print("❌ ERROR: Failed to create trade line! Error: ", GetLastError());
      return;
   }
   
   color lineColor;
   bool isWin = (profit > 0);
   
   if(LineColorMode == COLOR_BY_OUTCOME)
   {
      if(isSLHit)
         lineColor = SLLossLineColor;
      else if(isWin)
         lineColor = WinLineColor;
      else
         lineColor = SmallLossLineColor;
   }
   else
   {
      lineColor = (posType == OP_BUY) ? BuyLineColor : SellLineColor;
   }
   
   ObjectSet(lineName, OBJPROP_COLOR, lineColor);
   ObjectSet(lineName, OBJPROP_WIDTH, TradeLineWidth);
   ObjectSet(lineName, OBJPROP_STYLE, TradeLineStyle);
   ObjectSet(lineName, OBJPROP_RAY, false);
   ObjectSet(lineName, OBJPROP_SELECTABLE, true);
   ObjectSet(lineName, OBJPROP_BACK, true);
   
   string tooltip = StringConcatenate(
      (posType == OP_BUY ? "BUY" : "SELL"), " Trade #", positionTicket,
      "\nEntry: ", DoubleToString(entryPrice, Digits), " @ ", TimeToString(entryTime, TIME_DATE|TIME_MINUTES),
      "\nExit: ", DoubleToString(exitPrice, Digits), " @ ", TimeToString(exitTime, TIME_DATE|TIME_MINUTES),
      "\nP/L: ", DoubleToString(profit, 2),
      "\nReason: ", exitReason
   );
   
   ObjectSetText(lineName, tooltip, 8, "Arial", lineColor);
   
   Print("✅ Trade line drawn: #", positionTicket, " | ", 
         entryPrice, "→", exitPrice, " | Color: ", lineColor);
}

//+------------------------------------------------------------------+
//| 🎨 MASTERPIECE PANEL - Complete Rebuild                          |
//+------------------------------------------------------------------+
void UpdateTradeInfoPanel()
{
   // ═══════════════════════════════════════════════════════════════
   // SMART UPDATE LOGIC - Decide if we need full redraw
   // ═══════════════════════════════════════════════════════════════
   
   panelTickCounter++;
   
   bool hasOpenPosition = (GetOpenTradesCount() > 0);
   bool isNewBar = (Time[0] != lastPanelUpdate);
   bool forceFullRedraw = panelNeedsFullRedraw;
   
   // Full redraw conditions
   bool needsFullRedraw = (forceFullRedraw || 
                           isNewBar || 
                           lastFullPanelRedraw == 0);
   
   // Real-time update (P/L only) - every 5 ticks if position open
   bool needsQuickUpdate = (hasOpenPosition && panelTickCounter >= 5);
   
   if(!needsFullRedraw && !needsQuickUpdate)
      return;  // Skip this tick
   
   if(needsQuickUpdate && !needsFullRedraw)
   {
      // Quick update - only P/L section
      UpdatePositionProfitOnly();
      panelTickCounter = 0;
      return;
   }
   
   // ═══════════════════════════════════════════════════════════════
   // FULL PANEL REBUILD
   // ═══════════════════════════════════════════════════════════════
   
   panelTickCounter = 0;
   totalSections = 0;
   int yPos = PANEL_Y + PANEL_PADDING;
   
   // ═══════════════════════════════════════════════════════════════
   // BACKGROUND - Create or update
   // ═══════════════════════════════════════════════════════════════
   
   string bgName = panelPrefix + "Background";
   
   if(ObjectFind(bgName) < 0)
   {
      ObjectCreate(bgName, OBJ_RECTANGLE_LABEL, 0, 0, 0);
      ObjectSet(bgName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSet(bgName, OBJPROP_BORDER_TYPE, BORDER_FLAT);
      ObjectSet(bgName, OBJPROP_COLOR, PANEL_BORDER_COLOR);
      ObjectSet(bgName, OBJPROP_WIDTH, 2);
      ObjectSet(bgName, OBJPROP_BACK, false);
      ObjectSet(bgName, OBJPROP_SELECTABLE, false);
   }
   
   ObjectSet(bgName, OBJPROP_XDISTANCE, PANEL_X);
   ObjectSet(bgName, OBJPROP_YDISTANCE, PANEL_Y);
   ObjectSet(bgName, OBJPROP_XSIZE, PANEL_WIDTH);
   ObjectSet(bgName, OBJPROP_BGCOLOR, PANEL_BG_COLOR);
   
   // ═══════════════════════════════════════════════════════════════
   // TITLE SECTION
   // ═══════════════════════════════════════════════════════════════
   
   CreateLabel(panelPrefix + "Title", "PTL ATR STRATEGY", 
               PANEL_X + (PANEL_WIDTH / 2), yPos, 11, "Arial Black", HEADER_COLOR, ANCHOR_CENTER);
   yPos += LINE_HEIGHT + 2;
   
   // Subtitle with symbol and timeframe
   string subtitle = StringConcatenate(Symbol(), " • ", PeriodToString(Period()));
   CreateLabel(panelPrefix + "Subtitle", subtitle, 
               PANEL_X + (PANEL_WIDTH / 2), yPos, 8, "Arial", TEXT_COLOR, ANCHOR_CENTER);
   yPos += LINE_HEIGHT + SECTION_SPACING;
   
   DrawSeparator(panelPrefix + "TitleSep", PANEL_X + PANEL_PADDING, yPos, PANEL_WIDTH - (PANEL_PADDING * 2));
   yPos += SEPARATOR_HEIGHT + SECTION_SPACING;
   
   // ═══════════════════════════════════════════════════════════════
   // SECTION 1: TRADING STATUS
   // ═══════════════════════════════════════════════════════════════
   
   CleanPanelSection("TradingStatus");
   
   int sectionIndex = 0;
   InitPanelSection("TradingStatus", yPos);
   
   yPos = DrawSectionHeader("TradingStatus", "TRADING STATUS", yPos, clrDodgerBlue);
   
   // Position status
   if(hasOpenPosition)
   {
      int totalPositions = 0;
      bool firstPositionDrawn = false;
      
      // Count total positions first
      for(int i = 0; i < OrdersTotal(); i++)
      {
         if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
         if(OrderSymbol() != Symbol()) continue;
         
         int posMagic = OrderMagicNumber();
         if(posMagic == MAGIC_BUY_GREEN || posMagic == MAGIC_SELL_PINK)
            totalPositions++;
      }
      
      // Draw first position details
      for(int i = 0; i < OrdersTotal(); i++)
      {
         if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
         if(OrderSymbol() != Symbol()) continue;
         
         int posMagic = OrderMagicNumber();
         if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
         
         if(firstPositionDrawn) continue;  // Only show first one
         
         int posType = OrderType();
         double profit = OrderProfit() + OrderSwap() + OrderCommission();
         double lots = OrderLots();
         double openPrice = OrderOpenPrice();
         double currentPrice = (posType == OP_BUY) ? Bid : Ask;
         double pips = (currentPrice - openPrice) / GetPipValue();
         if(posType == OP_SELL) pips = -pips;
         
         // Position type with icon
         string typeText = "";
         color typeColor;
         string icon = "";
         
         if(posType == OP_BUY)
         {
            typeText = "BUY";
            typeColor = clrDodgerBlue;
            icon = "▲";
         }
         else
         {
            typeText = "SELL";
            typeColor = clrOrangeRed;
            icon = "▼";
         }
         
         // Add counter if multiple positions
         if(totalPositions > 1)
            typeText += " (" + IntegerToString(totalPositions) + ")";
         
         CreateLabel(panelPrefix + "TradingStatus_Icon", icon, 
                    PANEL_X + PANEL_PADDING, yPos, 12, "Arial Black", typeColor, ANCHOR_LEFT);
         
         CreateLabel(panelPrefix + "TradingStatus_Type", typeText, 
                    PANEL_X + PANEL_PADDING + 20, yPos, 10, "Arial Black", typeColor, ANCHOR_LEFT);
         
         CreateLabel(panelPrefix + "TradingStatus_Lots", DoubleToString(lots, 2) + " lots", 
                    PANEL_X + PANEL_WIDTH - PANEL_PADDING, yPos, 8, "Arial", TEXT_COLOR, ANCHOR_RIGHT);
         
         yPos += LINE_HEIGHT + 2;
         
         // P/L (this will be updated frequently)
         color plColor;
         if(profit > 0) plColor = SUCCESS_COLOR;
         else if(profit < 0) plColor = ERROR_COLOR;
         else plColor = TEXT_COLOR;
         
         CreateLabel(panelPrefix + "TradingStatus_PL", FormatMoney(profit, true), 
                    PANEL_X + PANEL_PADDING, yPos, 11, "Courier New Bold", plColor, ANCHOR_LEFT);
         
         // Pips
         string pipsText = StringConcatenate((pips >= 0 ? "+" : ""), DoubleToString(pips, 1), " pips");
         CreateLabel(panelPrefix + "TradingStatus_Pips", pipsText, 
                    PANEL_X + PANEL_WIDTH - PANEL_PADDING, yPos, 8, "Arial", plColor, ANCHOR_RIGHT);
         
         yPos += LINE_HEIGHT + 4;
         
         firstPositionDrawn = true;
      }
      
      // If multiple positions, show combined P/L
      if(totalPositions > 1)
      {
         double totalProfit = 0;
         
         for(int i = 0; i < OrdersTotal(); i++)
         {
            if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
            if(OrderSymbol() != Symbol()) continue;
            
            int posMagic = OrderMagicNumber();
            if(posMagic == MAGIC_BUY_GREEN || posMagic == MAGIC_SELL_PINK)
               totalProfit += OrderProfit() + OrderSwap() + OrderCommission();
         }
         
         color totalColor = (totalProfit >= 0) ? SUCCESS_COLOR : ERROR_COLOR;
         
         CreateLabel(panelPrefix + "TradingStatus_Total", "Total: " + FormatMoney(totalProfit, true), 
                    PANEL_X + PANEL_PADDING + 15, yPos, 9, "Arial Bold", totalColor, ANCHOR_LEFT);
         
         yPos += LINE_HEIGHT + 4;
      }
   }
   else
   {
      // No position
      CreateLabel(panelPrefix + "TradingStatus_NoPos", GetStatusIcon(true, true) + " Ready to Trade", 
                 PANEL_X + PANEL_PADDING, yPos, 9, "Arial Bold", SUCCESS_COLOR, ANCHOR_LEFT);
      yPos += LINE_HEIGHT + 4;
   }
   
   FinalizePanelSection(sectionIndex++, yPos);
   yPos += SECTION_SPACING;
   
   // ═══════════════════════════════════════════════════════════════
   // SECTION 2: MARKET POSITION (Price vs Bands)
   // ═══════════════════════════════════════════════════════════════
   
   CleanPanelSection("Market");
   
   InitPanelSection("Market", yPos);
   
   yPos = DrawSectionHeader("Market", "MARKET POSITION", yPos, clrGold);
   
   double currentClose = 0;
   double currentMidline = 0;
   double currentUpperBand = 0;
   double currentLowerBand = 0;
   
   bool marketDataValid = false;
   
   if(SafeGetArrayValue(atrMA, 0, currentMidline) &&
      SafeGetArrayValue(atrUpperBand, 0, currentUpperBand) &&
      SafeGetArrayValue(atrLowerBand, 0, currentLowerBand))
   {
      currentClose = Close[0];
      marketDataValid = true;
      
      // Price vs Midline
      string priceVsMid = "";
      color priceColor;
      
      if(currentClose > currentMidline)
      {
         priceVsMid = "Above Midline";
         priceColor = SUCCESS_COLOR;
      }
      else if(currentClose < currentMidline)
      {
         priceVsMid = "Below Midline";
         priceColor = ERROR_COLOR;
      }
      else
      {
         priceVsMid = "At Midline";
         priceColor = WARNING_COLOR;
      }
      
      CreateLabel(panelPrefix + "Market_Position", priceVsMid, 
                 PANEL_X + PANEL_PADDING, yPos, 9, "Arial Bold", priceColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
      
      // Distance from midline
      double distancePips = MathAbs(currentClose - currentMidline) / GetPipValue();
      string distText = StringConcatenate(DoubleToString(distancePips, 1), " pips");
      
      CreateLabel(panelPrefix + "Market_Distance", distText, 
                 PANEL_X + PANEL_PADDING + 15, yPos, 8, "Arial", TEXT_COLOR, ANCHOR_LEFT);
      yPos += LINE_HEIGHT + 2;
      
      // Band status
      string bandStatus = "";
      color bandColor;
      
      if(currentClose > currentUpperBand)
      {
         bandStatus = "⚠ ABOVE Upper Band";
         bandColor = WARNING_COLOR;
      }
      else if(currentClose < currentLowerBand)
      {
         bandStatus = "⚠ BELOW Lower Band";
         bandColor = WARNING_COLOR;
      }
      else
      {
         bandStatus = "✓ Inside Bands";
         bandColor = SUCCESS_COLOR;
      }
      
      CreateLabel(panelPrefix + "Market_Bands", bandStatus, 
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial", bandColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT + 4;
   }
   else
   {
      // Fallback if data not ready
      CreateLabel(panelPrefix + "Market_Loading", "⏳ Calculating...", 
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial", WARNING_COLOR, ANCHOR_LEFT);
      yPos += LINE_HEIGHT + 4;
   }
   
   FinalizePanelSection(sectionIndex++, yPos);
   yPos += SECTION_SPACING;
   
   // ═══════════════════════════════════════════════════════════════
   // SECTION 3: ACTIVE FILTERS
   // ═══════════════════════════════════════════════════════════════
   
   CleanPanelSection("Filters");
   
   InitPanelSection("Filters", yPos);
   
   yPos = DrawSectionHeader("Filters", "ACTIVE FILTERS", yPos, clrGold);
   
   int activeFilters = 0;
   
   // Aroon Filter
   if(UseAroonFilter)
   {
      activeFilters++;
      
      double aroonUpNow = 0;
      double aroonDownNow = 0;
      
      if(SafeGetArrayValue(aroonUp, 0, aroonUpNow) && 
         SafeGetArrayValue(aroonDown, 0, aroonDownNow))
      {
         string aroonText = "";
         color aroonColor;
         string aroonIcon = "";
         
         if(aroonUpNow > aroonDownNow)
         {
            aroonText = "Aroon: BULLISH";
            aroonColor = SUCCESS_COLOR;
            aroonIcon = "▲";
         }
         else if(aroonDownNow > aroonUpNow)
         {
            aroonText = "Aroon: BEARISH";
            aroonColor = ERROR_COLOR;
            aroonIcon = "▼";
         }
         else
         {
            aroonText = "Aroon: NEUTRAL";
            aroonColor = WARNING_COLOR;
            aroonIcon = "━";
         }
         
         CreateLabel(panelPrefix + "Filters_Aroon", aroonIcon + " " + aroonText, 
                    PANEL_X + PANEL_PADDING, yPos, 8, "Arial Bold", aroonColor, ANCHOR_LEFT);
         
         string aroonValues = StringConcatenate("↑", DoubleToString(aroonUpNow, 0), "% ↓", DoubleToString(aroonDownNow, 0), "%");
         CreateLabel(panelPrefix + "Filters_AroonVal", aroonValues, 
                    PANEL_X + PANEL_WIDTH - PANEL_PADDING, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_RIGHT);
         
         yPos += LINE_HEIGHT;
      }
      else
      {
         CreateLabel(panelPrefix + "Filters_Aroon", "⏳ Aroon: Calculating...", 
                    PANEL_X + PANEL_PADDING, yPos, 8, "Arial", WARNING_COLOR, ANCHOR_LEFT);
         yPos += LINE_HEIGHT;
      }
   }
   
   // Same Color Dot Lockout
   if(UseSameColorDotLockout)
   {
      activeFilters++;
      
      // Green Dots
      string greenText = "";
      color greenColor;
      
      if(greenDotLockoutActive)
      {
         greenText = "🔒 Green Dots: LOCKED";
         greenColor = WARNING_COLOR;
      }
      else
      {
         greenText = GetStatusIcon(true, true) + " Green Dots: Active";
         greenColor = SUCCESS_COLOR;
      }
      
      CreateLabel(panelPrefix + "Filters_Green", greenText, 
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial", greenColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
      
      // Pink Dots
      string pinkText = "";
      color pinkColor;
      
      if(pinkDotLockoutActive)
      {
         pinkText = "🔒 Pink Dots: LOCKED";
         pinkColor = WARNING_COLOR;
      }
      else
      {
         pinkText = GetStatusIcon(true, true) + " Pink Dots: Active";
         pinkColor = clrPaleVioletRed;
      }
      
      CreateLabel(panelPrefix + "Filters_Pink", pinkText, 
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial", pinkColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
      
      // 🔥 NEW: Show activation mode info
      string modeText = "Mode: ";
      if(LockoutActivationMode == ACTIVATE_IMMEDIATE)
         modeText += "Immediate";
      else
      {
         modeText += "SL-Based";
         if(SL_RequireFirstTrade)
            modeText += " (1st)";
         else
            modeText += " (Any)";
      }
      
      CreateLabel(panelPrefix + "Filters_LockoutMode", modeText, 
                 PANEL_X + PANEL_PADDING + 10, yPos, 7, "Arial", DISABLED_COLOR, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
   }
   
   // Zone SL Lockout
   if(UseZoneLockout)
   {
      activeFilters++;
      
      bool buyLocked  = (greenZoneLockout != 0);
      bool sellLocked = (pinkZoneLockout  != 0);
      
      string buyText  = buyLocked  ? StringConcatenate("🔒 Locked: ", GetZoneName(greenZoneLockout))
                                   : "✓ Buy Zones: Open";
      string sellText = sellLocked ? StringConcatenate("🔒 Locked: ", GetZoneName(pinkZoneLockout))
                                   : "✓ Sell Zones: Open";
      
      color buyColor  = buyLocked  ? WARNING_COLOR : SUCCESS_COLOR;
      color sellColor = sellLocked ? WARNING_COLOR : clrPaleVioletRed;
      
      CreateLabel(panelPrefix + "Filters_ZoneBuy", buyText,
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial", buyColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
      
      CreateLabel(panelPrefix + "Filters_ZoneSell", sellText,
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial", sellColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
      
      if(buyLocked)
      {
         string unlockText = StringConcatenate("  Unlock: green dot in any other zone");
         CreateLabel(panelPrefix + "Filters_ZoneBuyUnlock", unlockText,
                    PANEL_X + PANEL_PADDING + 10, yPos, 7, "Arial", DISABLED_COLOR, ANCHOR_LEFT);
         yPos += LINE_HEIGHT;
      }
      if(sellLocked)
      {
         string unlockText = StringConcatenate("  Unlock: pink dot in any other zone");
         CreateLabel(panelPrefix + "Filters_ZoneSellUnlock", unlockText,
                    PANEL_X + PANEL_PADDING + 10, yPos, 7, "Arial", DISABLED_COLOR, ANCHOR_LEFT);
         yPos += LINE_HEIGHT;
      }
   }
   
   // Daily Trading Hours
   if(UseDailyTradingHours)
   {
      activeFilters++;
      
      bool inWindow = IsWithinDailyTradingHours();
      
      string timeText = "";
      color timeColor;
      
      if(inWindow)
      {
         timeText = GetStatusIcon(true, true) + " Trading Window: OPEN";
         timeColor = SUCCESS_COLOR;
      }
      else
      {
         timeText = GetStatusIcon(false, false) + " Trading Window: CLOSED";
         timeColor = ERROR_COLOR;
      }
      
      CreateLabel(panelPrefix + "Filters_Time", timeText, 
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial Bold", timeColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
      
      string windowText = StringConcatenate(DailyStartTime, " - ", DailyStopTime);
      CreateLabel(panelPrefix + "Filters_TimeWindow", windowText, 
                 PANEL_X + PANEL_PADDING + 15, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
   }
   
   if(activeFilters == 0)
   {
      CreateLabel(panelPrefix + "Filters_None", "⚠ No Filters Active", 
                 PANEL_X + PANEL_PADDING, yPos, 8, "Arial", DISABLED_COLOR, ANCHOR_LEFT);
      yPos += LINE_HEIGHT;
   }
   
   yPos += 2;
   FinalizePanelSection(sectionIndex++, yPos);
   yPos += SECTION_SPACING;
   
   // ═══════════════════════════════════════════════════════════════
   // SECTION 4: PROTECTION STATUS (Only if enabled)
   // ═══════════════════════════════════════════════════════════════
   
   if(UseConsecutiveLossFilter)
   {
      CleanPanelSection("Protection");
      
      InitPanelSection("Protection", yPos);
      
      yPos = DrawSectionHeader("Protection", "LOSS PROTECTION", yPos, clrOrangeRed);
      
      if(inLockout)
      {
         // LOCKOUT ACTIVE
         CreateLabel(panelPrefix + "Protection_Status", "⚠️ LOCKOUT ACTIVE", 
                    PANEL_X + PANEL_PADDING, yPos, 9, "Arial Black", ERROR_COLOR, ANCHOR_LEFT);
         yPos += LINE_HEIGHT + 2;
         
         string dirText = StringConcatenate("Type: ", (lockoutDirection == OP_BUY ? "BUY Losses" : "SELL Losses"));
         CreateLabel(panelPrefix + "Protection_Dir", dirText, 
                    PANEL_X + PANEL_PADDING + 15, yPos, 8, "Arial", WARNING_COLOR, ANCHOR_LEFT);
         yPos += LINE_HEIGHT;
         
         // Lockout details based on type
         if(LockoutType == LOCKOUT_TIME_BASED || LockoutType == LOCKOUT_HYBRID)
         {
            double remaining = GetLockoutTimeRemaining();
            string timeText = StringConcatenate("⏰ Expires: ", DoubleToString(remaining, 1), " hours");
            CreateLabel(panelPrefix + "Protection_Time", timeText, 
                       PANEL_X + PANEL_PADDING + 15, yPos, 8, "Arial", TEXT_COLOR, ANCHOR_LEFT);
            yPos += LINE_HEIGHT;
         }
         
         if(LockoutType == LOCKOUT_HTF_DOT || LockoutType == LOCKOUT_HYBRID)
         {
            string dotColor = (lockoutDirection == OP_BUY ? "GREEN" : "PINK");
            string htfText = StringConcatenate("🔍 Wait: M", HTF_Timeframe, " ", dotColor, " dot");
            CreateLabel(panelPrefix + "Protection_HTF", htfText, 
                       PANEL_X + PANEL_PADDING + 15, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_LEFT);
            yPos += LINE_HEIGHT;
         }
         
         yPos += 2;
      }
      else
      {
         // Not in lockout - show loss counter
         string lossText = StringConcatenate("Losses: ", consecutiveLosses, " / ", MaxConsecutiveLosses);
         color lossColor;
         
         if(consecutiveLosses == 0)
            lossColor = SUCCESS_COLOR;
         else if(consecutiveLosses >= MaxConsecutiveLosses - 1)
            lossColor = ERROR_COLOR;
         else
            lossColor = WARNING_COLOR;
         
         CreateLabel(panelPrefix + "Protection_Count", lossText, 
                    PANEL_X + PANEL_PADDING, yPos, 9, "Arial Bold", lossColor, ANCHOR_LEFT);
         yPos += LINE_HEIGHT + 2;
         
         if(consecutiveLosses > 0)
         {
            int remaining = MaxConsecutiveLosses - consecutiveLosses;
            string warnText = StringConcatenate("⚠️ ", remaining, " more loss", (remaining == 1 ? "" : "es"), " = lockout");
            CreateLabel(panelPrefix + "Protection_Warn", warnText, 
                       PANEL_X + PANEL_PADDING + 15, yPos, 7, "Arial", WARNING_COLOR, ANCHOR_LEFT);
            yPos += LINE_HEIGHT;
         }
         else
         {
            CreateLabel(panelPrefix + "Protection_OK", GetStatusIcon(true, true) + " Protection Active", 
                       PANEL_X + PANEL_PADDING + 15, yPos, 8, "Arial", SUCCESS_COLOR, ANCHOR_LEFT);
            yPos += LINE_HEIGHT;
         }
         
         yPos += 2;
      }
      
      FinalizePanelSection(sectionIndex++, yPos);
      yPos += SECTION_SPACING;
   }
   
   // ═══════════════════════════════════════════════════════════════
   // SECTION 5: DAILY P/L LIMITS (Only if enabled)
   // ═══════════════════════════════════════════════════════════════
   
   if(UseDailyLimits && ShowDailyPLInPanel)
   {
      CleanPanelSection("DailyPL");
      
      InitPanelSection("DailyPL", yPos);
      
      yPos = DrawSectionHeader("DailyPL", "DAILY P/L LIMITS", yPos, clrGold);
      
      // Update current totals
      UpdateDailyPL();
      
      // Status indicator
      string statusText = "";
      color statusColor;
      
      if(dailyLossLimitHit)
      {
         statusText = "🛑 LOSS LIMIT HIT";
         statusColor = ERROR_COLOR;
      }
      else if(dailyProfitTargetHit)
      {
         statusText = "🎯 PROFIT TARGET HIT";
         statusColor = SUCCESS_COLOR;
      }
      else
      {
         statusText = GetStatusIcon(true, true) + " Active";
         statusColor = SUCCESS_COLOR;
      }
      
      CreateLabel(panelPrefix + "DailyPL_Status", statusText, 
                 PANEL_X + PANEL_PADDING, yPos, 9, "Arial Bold", statusColor, ANCHOR_LEFT);
      yPos += LINE_HEIGHT + 2;
      
      // Today's Total P/L (big display)
      color plColor;
      if(todayTotalPL > 0) plColor = DailyProfitColor;
      else if(todayTotalPL < 0) plColor = DailyLossColor;
      else plColor = TEXT_COLOR;
      
      CreateLabel(panelPrefix + "DailyPL_Total", FormatMoney(todayTotalPL, true), 
                 PANEL_X + PANEL_PADDING, yPos, 11, "Courier New Bold", plColor, ANCHOR_LEFT);
      
      string tradesText = IntegerToString(todayClosedCount) + " trade" + (todayClosedCount == 1 ? "" : "s");
      CreateLabel(panelPrefix + "DailyPL_Trades", tradesText, 
                 PANEL_X + PANEL_WIDTH - PANEL_PADDING, yPos, 8, "Arial", TEXT_COLOR, ANCHOR_RIGHT);
      
      yPos += LINE_HEIGHT + 2;
      
      // Breakdown (if we're counting floating)
      if(CountFloatingPL && todayFloatingPL != 0)
      {
         string closedText = "Closed: " + FormatMoney(todayClosedPL, true);
         CreateLabel(panelPrefix + "DailyPL_Closed", closedText, 
                    PANEL_X + PANEL_PADDING + 15, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_LEFT);
         yPos += LINE_HEIGHT - 2;
         
         string floatingText = "Floating: " + FormatMoney(todayFloatingPL, true);
         color floatColor = (todayFloatingPL > 0) ? DailyProfitColor : DailyLossColor;
         CreateLabel(panelPrefix + "DailyPL_Floating", floatingText, 
                    PANEL_X + PANEL_PADDING + 15, yPos, 7, "Arial", floatColor, ANCHOR_LEFT);
         yPos += LINE_HEIGHT;
      }
      
      // Limits display
      if(DailyLossLimit > 0 || DailyProfitTarget > 0)
      {
         yPos += 2;
         
         if(DailyLossLimit > 0)
         {
            // Calculate percentage to limit
            double lossPercent = 0;
            if(todayTotalPL < 0)
               lossPercent = (MathAbs(todayTotalPL) / DailyLossLimit) * 100.0;
            
            string lossText = StringConcatenate("Loss Limit: -", DoubleToString(DailyLossLimit, 2));
            
            color lossLimitColor;
            if(dailyLossLimitHit)
               lossLimitColor = ERROR_COLOR;
            else if(lossPercent >= 80)
               lossLimitColor = DailyWarningColor;
            else
               lossLimitColor = TEXT_COLOR;
            
            CreateLabel(panelPrefix + "DailyPL_LossLimit", lossText, 
                       PANEL_X + PANEL_PADDING + 10, yPos, 7, "Arial", lossLimitColor, ANCHOR_LEFT);
            
            if(lossPercent > 0 && !dailyLossLimitHit)
            {
               string percentText = StringConcatenate(DoubleToString(lossPercent, 0), "%");
               CreateLabel(panelPrefix + "DailyPL_LossPercent", percentText, 
                          PANEL_X + PANEL_WIDTH - PANEL_PADDING, yPos, 7, "Arial", lossLimitColor, ANCHOR_RIGHT);
            }
            
            yPos += LINE_HEIGHT - 2;
         }
         
         if(DailyProfitTarget > 0)
         {
            // Calculate percentage to target
            double profitPercent = 0;
            if(todayTotalPL > 0)
               profitPercent = (todayTotalPL / DailyProfitTarget) * 100.0;
            
            string profitText = StringConcatenate("Profit Target: +", DoubleToString(DailyProfitTarget, 2));
            
            color profitTargetColor;
            if(dailyProfitTargetHit)
               profitTargetColor = SUCCESS_COLOR;
            else if(profitPercent >= 80)
               profitTargetColor = DailyWarningColor;
            else
               profitTargetColor = TEXT_COLOR;
            
            CreateLabel(panelPrefix + "DailyPL_ProfitTarget", profitText, 
                       PANEL_X + PANEL_PADDING + 10, yPos, 7, "Arial", profitTargetColor, ANCHOR_LEFT);
            
            if(profitPercent > 0 && !dailyProfitTargetHit)
            {
               string percentText = StringConcatenate(DoubleToString(profitPercent, 0), "%");
               CreateLabel(panelPrefix + "DailyPL_ProfitPercent", percentText, 
                          PANEL_X + PANEL_WIDTH - PANEL_PADDING, yPos, 7, "Arial", profitTargetColor, ANCHOR_RIGHT);
            }
            
            yPos += LINE_HEIGHT - 2;
         }
      }
      
      yPos += 2;
      FinalizePanelSection(sectionIndex++, yPos);
      yPos += SECTION_SPACING;
   }
   
   // ═══════════════════════════════════════════════════════════════
   // SECTION 6: SETTINGS SUMMARY
   // ═══════════════════════════════════════════════════════════════
   
   CleanPanelSection("Settings");
   
   InitPanelSection("Settings", yPos);
   
   yPos = DrawSectionHeader("Settings", "CONFIGURATION", yPos, clrSilver);
   
   // Money Management
   string mmText = "";
   if(MoneyManagementType == MM_FIXED_LOT)
      mmText = StringConcatenate("MM: Fixed ", DoubleToString(FixedLotSize, 2), " lots");
   else if(MoneyManagementType == MM_RISK_PERCENT)
      mmText = StringConcatenate("MM: ", DoubleToString(RiskPercent, 1), "% Risk");
   else
      mmText = StringConcatenate("MM: $", DoubleToString(FixedRiskAmount, 0), " Risk");
   
   CreateLabel(panelPrefix + "Settings_MM", mmText, 
              PANEL_X + PANEL_PADDING, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_LEFT);
   yPos += LINE_HEIGHT;
   
   // Stop Loss Type
   string slText = "";
   if(UseLocalSwingSL)
      slText = StringConcatenate("SL: Local Swing (", SwingLookbackBars, " bars)");
   else
      slText = StringConcatenate("SL: Fixed ", StopLossPips, " pips");
   
   CreateLabel(panelPrefix + "Settings_SL", slText, 
              PANEL_X + PANEL_PADDING, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_LEFT);
   yPos += LINE_HEIGHT;
   
   // Exit Methods
   string exitText = "Exit: ";
   int exitCount = 0;
   if(UseBandExit) { exitText += "Bands"; exitCount++; }
   if(UseSameDotExit) { exitText += (exitCount > 0 ? " + " : "") + "Same Dot"; exitCount++; }
   if(exitCount == 0) exitText += "None";
   
   CreateLabel(panelPrefix + "Settings_Exit", exitText, 
              PANEL_X + PANEL_PADDING, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_LEFT);
   yPos += LINE_HEIGHT + 4;
   
   // Pip Value Info
   string pipInfo = StringConcatenate("Pip: ", DoubleToString(GetPipValue(), (Digits > 4 ? 5 : Digits)));
   CreateLabel(panelPrefix + "Settings_Pip", pipInfo, 
              PANEL_X + PANEL_PADDING, yPos, 7, "Arial", TEXT_COLOR, ANCHOR_LEFT);
   yPos += LINE_HEIGHT;
   
   FinalizePanelSection(sectionIndex++, yPos);
   
   // ═══════════════════════════════════════════════════════════════
   // FINALIZE PANEL - Adjust background height
   // ═══════════════════════════════════════════════════════════════
   
   int finalHeight = yPos - PANEL_Y + PANEL_PADDING;
   ObjectSet(bgName, OBJPROP_YSIZE, finalHeight);
   
   currentPanelHeight = finalHeight;
   
   // Update tracking
   lastPanelUpdate = Time[0];
   lastFullPanelRedraw = TimeCurrent();
   panelNeedsFullRedraw = false;
   
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| 🎨 Quick Update - Only P/L (Real-time performance)               |
//+------------------------------------------------------------------+
void UpdatePositionProfitOnly()
{
   bool hasPosition = false;
   
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      hasPosition = true;
      
      int posType = OrderType();
      double profit = OrderProfit() + OrderSwap() + OrderCommission();
      double openPrice = OrderOpenPrice();
      double currentPrice = (posType == OP_BUY) ? Bid : Ask;
      double pips = (currentPrice - openPrice) / GetPipValue();
      if(posType == OP_SELL) pips = -pips;
      
      // Update P/L color
      color plColor;
      if(profit > 0) plColor = SUCCESS_COLOR;
      else if(profit < 0) plColor = ERROR_COLOR;
      else plColor = TEXT_COLOR;
      
      // Update labels (they exist from full redraw)
      string plName = panelPrefix + "TradingStatus_PL";
      if(ObjectFind(plName) >= 0)
      {
         ObjectSetText(plName, FormatMoney(profit, true), 11, "Courier New Bold", plColor);
      }
      
      string pipsName = panelPrefix + "TradingStatus_Pips";
      if(ObjectFind(pipsName) >= 0)
      {
         string pipsText = StringConcatenate((pips >= 0 ? "+" : ""), DoubleToString(pips, 1), " pips");
         ObjectSetText(pipsName, pipsText, 8, "Arial", plColor);
      }
      
      break;  // Only first position
   }
   
   if(!hasPosition)
   {
      // Position was closed - trigger full redraw next tick
      panelNeedsFullRedraw = true;
   }
}

//+------------------------------------------------------------------+
//| 🎨 Period to String Helper                                       |
//+------------------------------------------------------------------+
string PeriodToString(int period)
{
   switch(period)
   {
      case PERIOD_M1:  return "M1";
      case PERIOD_M5:  return "M5";
      case PERIOD_M15: return "M15";
      case PERIOD_M30: return "M30";
      case PERIOD_H1:  return "H1";
      case PERIOD_H4:  return "H4";
      case PERIOD_D1:  return "D1";
      case PERIOD_W1:  return "W1";
      case PERIOD_MN1: return "MN1";
      default:         return "M" + IntegerToString(period);
   }
}

//+------------------------------------------------------------------+
//| 🎨 Enhanced Label Creator with Auto-Cleanup                      |
//+------------------------------------------------------------------+
void CreateLabel(string name, string text, int x, int y, int fontSize, 
                 string fontName, color textColor, int anchor = ANCHOR_LEFT)
{
   // Delete if exists (ensures clean state)
   if(ObjectFind(name) >= 0)
      ObjectDelete(name);
   
   // Create new
   ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
   ObjectSet(name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSet(name, OBJPROP_ANCHOR, anchor);
   ObjectSet(name, OBJPROP_XDISTANCE, x);
   ObjectSet(name, OBJPROP_YDISTANCE, y);
   ObjectSet(name, OBJPROP_SELECTABLE, false);
   ObjectSet(name, OBJPROP_BACK, false);
   ObjectSetText(name, text, fontSize, fontName, textColor);
}

//+------------------------------------------------------------------+
//| 🎨 Enhanced Separator with Proper Styling                        |
//+------------------------------------------------------------------+
void DrawSeparator(string name, int x, int y, int width)
{
   if(ObjectFind(name) >= 0)
      ObjectDelete(name);
   
   ObjectCreate(name, OBJ_RECTANGLE_LABEL, 0, 0, 0);
   ObjectSet(name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSet(name, OBJPROP_XDISTANCE, x);
   ObjectSet(name, OBJPROP_YDISTANCE, y);
   ObjectSet(name, OBJPROP_XSIZE, width);
   ObjectSet(name, OBJPROP_YSIZE, SEPARATOR_HEIGHT);
   ObjectSet(name, OBJPROP_BGCOLOR, SEPARATOR_COLOR);
   ObjectSet(name, OBJPROP_BORDER_TYPE, BORDER_FLAT);
   ObjectSet(name, OBJPROP_SELECTABLE, false);
   ObjectSet(name, OBJPROP_BACK, false);
}

//+------------------------------------------------------------------+
//| 🎨 Clean Panel Section - Remove all objects from a section       |
//+------------------------------------------------------------------+
void CleanPanelSection(string sectionName)
{
   int totalObjects = ObjectsTotal();
   
   for(int i = totalObjects - 1; i >= 0; i--)
   {
      string objName = ObjectName(i);
      
      // Match any object that starts with our section prefix
      if(StringFind(objName, panelPrefix + sectionName) == 0)
      {
         ObjectDelete(objName);
      }
   }
}

//+------------------------------------------------------------------+
//| 🎨 Initialize Section Tracking                                   |
//+------------------------------------------------------------------+
void InitPanelSection(string name, int &yPos, bool visible = true)
{
   if(totalSections >= 10) return;  // Safety limit
   
   sections[totalSections].name = name;
   sections[totalSections].startY = yPos;
   sections[totalSections].height = 0;
   sections[totalSections].visible = visible;
   sections[totalSections].needsUpdate = true;
   
   totalSections++;
}

//+------------------------------------------------------------------+
//| 🎨 Finalize Section - Calculate height                           |
//+------------------------------------------------------------------+
void FinalizePanelSection(int sectionIndex, int &yPos)
{
   if(sectionIndex >= totalSections) return;
   
   sections[sectionIndex].height = yPos - sections[sectionIndex].startY;
}

//+------------------------------------------------------------------+
//| 🎨 Section Header - Consistent styling                           |
//+------------------------------------------------------------------+
int DrawSectionHeader(string sectionName, string title, int yPos, color headerColor = HEADER_COLOR)
{
   string headerName = panelPrefix + sectionName + "_Header";
   CreateLabel(headerName, title, PANEL_X + PANEL_PADDING, yPos, 9, "Arial Black", headerColor, ANCHOR_LEFT);
   
   yPos += LINE_HEIGHT + 3;
   
   string sepName = panelPrefix + sectionName + "_Sep";
   DrawSeparator(sepName, PANEL_X + PANEL_PADDING - 2, yPos, PANEL_WIDTH - (PANEL_PADDING * 2) + 4);
   
   yPos += SEPARATOR_HEIGHT + 6;
   
   return yPos;
}

//+------------------------------------------------------------------+
//| 🎨 Status Indicator - Visual status with icon                    |
//+------------------------------------------------------------------+
string GetStatusIcon(bool active, bool isGood = true)
{
   if(active)
      return (isGood ? "✓" : "⚠");
   else
      return "✗";
}

//+------------------------------------------------------------------+
//| 🎨 Format Money - Consistent currency display                    |
//+------------------------------------------------------------------+
string FormatMoney(double amount, bool showSign = true)
{
   string sign = "";
   if(showSign)
   {
      if(amount > 0) sign = "+";
      else if(amount < 0) sign = "";
      else sign = " ";
   }
   
   return StringConcatenate(sign, DoubleToString(amount, 2), " ", AccountCurrency());
}

//+------------------------------------------------------------------+
//| 🎨 Safe Array Access - Prevents crashes                          |
//+------------------------------------------------------------------+
bool SafeGetArrayValue(double &array[], int index, double &value)
{
   if(ArraySize(array) <= index) return false;
   if(index < 0) return false;
   
   value = array[index];
   
   if(value == EMPTY_VALUE) return false;
   if(value > 999999 || value < -999999) return false;  // Sanity check
   
   return true;
}

//+------------------------------------------------------------------+
//| Draw lockout zone on chart - MT4 VERSION                         |
//+------------------------------------------------------------------+
void DrawLockoutZone()
{
   string lockoutRectName = objPrefix + "LockoutZone_" + TimeToString(lockoutStartTime);
   
   datetime endTime;
   if(LockoutType == LOCKOUT_TIME_BASED || LockoutType == LOCKOUT_HYBRID)
      endTime = lockoutStartTime + (LockoutHours * 3600);
   else
      endTime = lockoutStartTime + (24 * 3600);
   
   double highPrice = WindowPriceMax();
   double lowPrice = WindowPriceMin();
   
   ObjectCreate(lockoutRectName, OBJ_RECTANGLE, 0, lockoutStartTime, highPrice, endTime, lowPrice);
   ObjectSet(lockoutRectName, OBJPROP_COLOR, clrDarkRed);
   ObjectSet(lockoutRectName, OBJPROP_BACK, true);
   ObjectSet(lockoutRectName, OBJPROP_SELECTABLE, false);
   ObjectSet(lockoutRectName, OBJPROP_WIDTH, 0);
   ObjectSet(lockoutRectName, OBJPROP_STYLE, STYLE_SOLID);
   
   string lockoutTextName = objPrefix + "LockoutText_" + TimeToString(lockoutStartTime);
   datetime labelTime = lockoutStartTime + ((endTime - lockoutStartTime) / 2);
   double labelPrice = (highPrice + lowPrice) / 2;
   
   string labelText = "🔒 LOCKOUT - ";
   if(LockoutType == LOCKOUT_TIME_BASED)
      labelText += IntegerToString(LockoutHours) + "H MAX";
   else if(LockoutType == LOCKOUT_HTF_DOT)
   {
      string dotColor = (lockoutDirection == OP_BUY) ? "GREEN" : "PINK";
      labelText += IntegerToString(HTF_Timeframe) + " " + dotColor + " DOT";
   }
   else
   {
      string dotColor = (lockoutDirection == OP_BUY) ? "GREEN" : "PINK";
      labelText += IntegerToString(LockoutHours) + "H OR " + IntegerToString(HTF_Timeframe) + " " + dotColor;
   }
   
   ObjectCreate(lockoutTextName, OBJ_TEXT, 0, labelTime, labelPrice);
   ObjectSetText(lockoutTextName, labelText, 10, "Arial Bold", clrYellow);
   
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| Clean up all drawn objects                                       |
//+------------------------------------------------------------------+
void CleanupDrawings()
{
   int totalObjects = ObjectsTotal();
   
   for(int i = totalObjects - 1; i >= 0; i--)
   {
      string objName = ObjectName(i);
      
      if(StringFind(objName, objPrefix) == 0)
      {
         ObjectDelete(objName);
      }
      
      if(StringFind(objName, "SameColorLockout") >= 0)
      {
         ObjectDelete(objName);
      }
      
      // 🔥 NEW: Clean up panel objects
      if(StringFind(objName, "PTL_Panel_") >= 0)
      {
         ObjectDelete(objName);
      }
   }
}

//+------------------------------------------------------------------+
//| 🔥 NEW: Recover existing positions after restart                 |
//+------------------------------------------------------------------+
int RecoverExistingPositions()
{
   int recovered = 0;
   
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      // Check if already in storage (shouldn't be, but safety check)
      bool alreadyStored = false;
      for(int j = 0; j < ArraySize(activePositions); j++)
      {
         if(activePositions[j].positionTicket == OrderTicket())
         {
            alreadyStored = true;
            break;
         }
      }
      
      if(!alreadyStored)
{
   // We don't know if recovered positions were out of bounds, assume false
   bool wasOutOfBounds = false;
   
   StoreEntryData(OrderTicket(), OrderOpenTime(), OrderOpenPrice(), 
                  OrderType(), OrderMagicNumber(), wasOutOfBounds, 0); // 0 = unknown zone (recovered)
   recovered++;
}
   }
   
   return recovered;
}

//+------------------------------------------------------------------+
//| 🔥 NEW: Scan recent history for missed closed trades             |
//+------------------------------------------------------------------+
void ScanHistoryForMissedTrades()
{
   // Scan last 7 days of history
   datetime scanFrom = TimeCurrent() - (7 * 86400);
   int totalOrders = OrdersHistoryTotal();
   
   int foundMissed = 0;
   
   for(int i = totalOrders - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      
      // Only check recent orders
      if(OrderCloseTime() < scanFrom) break;
      
      if(OrderSymbol() != Symbol()) continue;
      
      int posMagic = OrderMagicNumber();
      if(posMagic != MAGIC_BUY_GREEN && posMagic != MAGIC_SELL_PINK) continue;
      
      int ticket = OrderTicket();
      
      // Check if trade line already exists
      string lineName = objPrefix + "TRADELINE_" + IntegerToString(ticket);
      if(ObjectFind(lineName) >= 0) continue;  // Already processed
      
      // This is a missed trade - process it now
      foundMissed++;
      
      Print("🔍 FOUND MISSED TRADE: #", ticket);
      
      datetime entryTime = OrderOpenTime();
      double entryPrice = OrderOpenPrice();
      datetime exitTime = OrderCloseTime();
      double exitPrice = OrderClosePrice();
      int orderType = OrderType();
      double profit = OrderProfit();
      double swap = OrderSwap();
      double commission = OrderCommission();
      double totalProfit = profit + swap + commission;
      double orderSL = OrderStopLoss();
      
      // Detect SL hit (improved tolerance)
      double slTolerance = 20 * Point;  // Increased from 10
      bool isSLHit = false;
      
      if(orderType == OP_BUY && orderSL > 0)
      {
         if(exitPrice <= orderSL && MathAbs(exitPrice - orderSL) < slTolerance)
            isSLHit = true;
      }
      else if(orderType == OP_SELL && orderSL > 0)
      {
         if(exitPrice >= orderSL && MathAbs(exitPrice - orderSL) < slTolerance)
            isSLHit = true;
      }
      
      // Also check comment for SL indication
      string comment = OrderComment();
      if(StringFind(comment, "[sl]") >= 0 || StringFind(comment, "sl") >= 0)
         isSLHit = true;
      
      string exitReason = "";
      if(isSLHit) exitReason = "Stop Loss";
      else if(totalProfit > 0) exitReason = "EA/Manual (Win)";
      else exitReason = "EA/Manual (Loss)";
      
      // Draw trade line
      DrawTradeLineRefactored(ticket, entryTime, entryPrice, 
                              exitTime, exitPrice, orderType, 
                              totalProfit, isSLHit, exitReason);
      
      // Draw exit marker
      string markerName = objPrefix + "EXIT_" + IntegerToString(ticket);
      
      if(ObjectFind(markerName) < 0)
      {
         if(isSLHit)
         {
            ObjectCreate(markerName, OBJ_ARROW, 0, exitTime, exitPrice);
            ObjectSet(markerName, OBJPROP_ARROWCODE, 251);
            ObjectSet(markerName, OBJPROP_COLOR, ExitLossColor);
            ObjectSet(markerName, OBJPROP_ANCHOR, ANCHOR_TOP);
            ObjectSet(markerName, OBJPROP_WIDTH, 4);
            ObjectSetText(markerName, "STOP LOSS | " + DoubleToString(totalProfit, 2), 8, "Arial", ExitLossColor);
         }
         else if(totalProfit > 0)
         {
            ObjectCreate(markerName, OBJ_ARROW, 0, exitTime, exitPrice);
            ObjectSet(markerName, OBJPROP_ARROWCODE, 252);
            ObjectSet(markerName, OBJPROP_COLOR, ExitWinColor);
            ObjectSet(markerName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
            ObjectSet(markerName, OBJPROP_WIDTH, 4);
            ObjectSetText(markerName, "WIN | " + DoubleToString(totalProfit, 2), 8, "Arial", ExitWinColor);
         }
      }
   }
   
   if(foundMissed > 0)
   {
      Print("✅ Recovered ", foundMissed, " missed trade line(s) from history");
      ChartRedraw();
   }
}

//+------------------------------------------------------------------+
//| 🔥 NEW: Save state to global variables (persistence)             |
//+------------------------------------------------------------------+
void SaveStateToGlobalVariables()
{
   GlobalVariableSet("PTL_ConsecutiveLosses", consecutiveLosses);
   GlobalVariableSet("PTL_InLockout", inLockout ? 1 : 0);
   GlobalVariableSet("PTL_LockoutStartTime", lockoutStartTime);
   GlobalVariableSet("PTL_LockoutDirection", lockoutDirection);
   
   GlobalVariableSet("PTL_GreenLockout", greenDotLockoutActive ? 1 : 0);
   GlobalVariableSet("PTL_GreenLockoutTime", greenLockoutStartTime);
   GlobalVariableSet("PTL_GreenZoneLockout", greenZoneLockout);
   
   GlobalVariableSet("PTL_PinkLockout", pinkDotLockoutActive ? 1 : 0);
   GlobalVariableSet("PTL_PinkLockoutTime", pinkLockoutStartTime);
   GlobalVariableSet("PTL_PinkZoneLockout", pinkZoneLockout);
   
   // Save SL-based lockout sequence tracking
   GlobalVariableSet("PTL_GreenSequenceActive", greenSequenceActive ? 1 : 0);
   GlobalVariableSet("PTL_GreenFirstTicket", greenFirstTradeTicket);
   
   GlobalVariableSet("PTL_PinkSequenceActive", pinkSequenceActive ? 1 : 0);
   GlobalVariableSet("PTL_PinkFirstTicket", pinkFirstTradeTicket);
   
   // 💰 Save daily limit state
   if(UseDailyLimits)
   {
      SaveDailyLimitState();
   }
   
   GlobalVariableSet("PTL_LastSaveTime", TimeCurrent());
}


//Brand new zone tracker for multiband

//+------------------------------------------------------------------+
//| Return human-readable name for a zone number                    |
//+------------------------------------------------------------------+
string GetZoneName(int zone)
{
   switch(zone)
   {
      case  5: return "Beyond Outer (+5)";  // future-proof
      case  4: return "Beyond Outer";
      case  3: return "4.5x-6.5x Sell";
      case  2: return "2.5x-4.5x Sell";
      case  1: return "Mid-2.5x Sell";
      case -1: return "Mid-2.5x Buy";
      case -2: return "2.5x-4.5x Buy";
      case -3: return "4.5x-6.5x Buy";
      case -4: return "Beyond Outer";
      case -5: return "Beyond Outer (-5)";  // future-proof
      default: return "Zone " + IntegerToString(zone);
   }
}

int GetPriceZone(double price, int barIdx) 
{
   double ma = atrMA[barIdx];
   double atr = iATR(Symbol(), Period(), ATR_Periods, barIdx);
   double diff = price - ma; // No MathAbs, we need direction

   // SELL SIDE (Above Midline)
   // Zone +4 = beyond outer band (above 6.5x ATR) — fully outside all bands
   // Zone +3 = between 4.5x and 6.5x ATR
   // Zone +2 = between 2.5x and 4.5x ATR
   // Zone +1 = between midline and 2.5x ATR
   if (diff > atr * ATR_Mult3) return 4;   // Beyond outer band (6.5x+)
   if (diff > atr * ATR_Mult2) return 3;   // 4.5x - 6.5x
   if (diff > atr * ATR_Mult1) return 2;   // 2.5x - 4.5x
   if (diff > 0)               return 1;   // mid - 2.5x

   // BUY SIDE (Below Midline)
   // Zone -4 = beyond outer band (below 6.5x ATR) — fully outside all bands
   // Zone -3 = between 4.5x and 6.5x ATR
   // Zone -2 = between 2.5x and 4.5x ATR
   // Zone -1 = between midline and 2.5x ATR
   if (diff < -atr * ATR_Mult3) return -4; // Beyond outer band (6.5x+)
   if (diff < -atr * ATR_Mult2) return -3; // 4.5x - 6.5x
   if (diff < -atr * ATR_Mult1) return -2; // 2.5x - 4.5x
   return -1;                              // mid - 2.5x
}

void DrawTrendLine(string name, datetime t1, double p1, datetime t2, double p2, color clr, int style)
{
   if(ObjectFind(name) < 0)
   {
      ObjectCreate(name, OBJ_TREND, 0, t2, p2, t1, p1);
      ObjectSet(name, OBJPROP_COLOR, clr);
      ObjectSet(name, OBJPROP_WIDTH, ATR_LineWidth);
      ObjectSet(name, OBJPROP_STYLE, style);
      ObjectSet(name, OBJPROP_RAY, false);
      ObjectSet(name, OBJPROP_SELECTABLE, false);
      ObjectSet(name, OBJPROP_BACK, true);
   }
}
//+------------------------------------------------------------------+
