فهرست منبع

Merge branch 'update/tp-sl-and-csv-changes' of huzaifa.hayat/vol_hedge_strategy_mt5 into master

Wajeeh Saqib 9 ماه پیش
والد
کامیت
6cab7a1a4a
3فایلهای تغییر یافته به همراه235 افزوده شده و 123 حذف شده
  1. 3 2
      data/vol_hedge_data.csv
  2. BIN
      vol_hedge_strategy_mt5.ex5
  3. 232 121
      vol_hedge_strategy_mt5.mq5

+ 3 - 2
data/vol_hedge_data.csv

@@ -1,2 +1,3 @@
-EURUSDm,1.08384,1000,1000,2023.03.22 02:05:25,2023.03.24 02:05:25
-EURUSDm,1.08734,400,400,2023.03.30 00:00:00,2023.04.04 02:05:25
+Symbol,Price,Buy StopLoss,Buy TakeProfit,Sell StopLoss,Sell TakeProfit,StartTime,EndTime
+EURUSDm,1.08384,1.07384,1.09384,1.09384,1.07384,2023.03.22 02:05:25,2024.03.24 02:05:25
+EURUSDm,1.08734,1.07734,1.09734,1.09734,1.07734,2023.03.30 00:00:00,2024.04.04 02:05:25

BIN
vol_hedge_strategy_mt5.ex5


+ 232 - 121
vol_hedge_strategy_mt5.mq5

@@ -5,7 +5,7 @@
 //+------------------------------------------------------------------+
 #property copyright "Copyright 2025, MQL Development"
 #property link      "https://www.mqldevelopment.com/"
-#property version   "1.00"
+#property version   "1.10"
 #define MaxOrders 100
 #include <Trade\Trade.mqh>
 CTrade  trade;
@@ -22,6 +22,11 @@ enum selectLine
    LineOnNewsBar =0,
    LineOnNewsStop=1
   };
+enum selectDay
+  {
+   prev,    // Previous Day
+   curr,    // Current Day
+  };
 
 #import "volHedgeNewsFilter.ex5"
 
@@ -61,8 +66,10 @@ struct new_trade_store
    ulong             sell_ticket;           // Sell Ticket
    string            symbol;                // Symbol
    double            price;                 // Price
-   double            stop_loss;             // StopLoss
-   double            take_profit;           // TakeProfit
+   double            stop_loss_buy;         // StopLoss Buy
+   double            take_profit_buy;       // TakeProfit Buy
+   double            stop_loss_sell;        // StopLoss Sell
+   double            take_profit_sell;      // TakeProfit Sell
    datetime          start_time;            // Start time
    datetime          end_time;              // End Time
    bool              buy_hit_virtual_sl;    // Buy Hit Virtual StopLoss
@@ -83,18 +90,21 @@ new_trade_store newTradeStore[MaxOrders];
 enum lotcalculator
   {
    fix, //Fixed Lot Size
-   rsk, //Risk Percentage
+   rsk, //Risk in Percentage
    dollar, // Risk in Dollars
   };
 
 sinput       string                  string_0                   = "<><><><><><> General SETTINGS <><><><><><>";   //__
 input        int                     magic_no                   = 333;             // Magic no
-input        bool                    bothHitsSl                 = false;           // Open after Both Hits StopLoss
-input        int                     maxTrades                  = 2;               // Max Concurrent Trades
-input        int                     maxSlippage                = 5;               // Max Slippage
+input        bool                    useTpSlPips                = false;           // Use Relative Tp/Sl in Pips
+input        double                  stopLoss                   = 100;             // Fixed Stop Loss in Pips
+input        double                  takeProfit                 = 100;             // Fixed Take Profit in Pips
+input        bool                    bothHitsSl                 = false;           // Enable Topped & Tailed Pre-Demand Level
+input        int                     maxSlippage                = 5;               // Max Slippage (Points)
 input        bool                    enableSpreadFilter         = false;           // Enable Spread Filter
-input        double                  maximumSpread              = 10;              // Maximum Spread
-input        string                  dataFileName               = "vol_hedge_data.csv"; // Data File Name
+input        double                  maximumSpread              = 10;              // Maximum Spread (Points)
+input        string                  tradeComment               = "Trade Placed";  // Trade Comment Prefix
+input        string                  dataFileName               = "vol_hedge_data.csv"; // CSV File Name
 
 input        string                  string_1                   = "<><><><><><> Lot Management<><><><><><>";   //__
 input        lotcalculator           lot_calculator             = fix;             // Lot Size Option
@@ -102,10 +112,11 @@ input        double                  lot_amount                 = 0.1;
 input        double                  risk                       = 0.5;             // Risk in Percentage %
 input        double                  dollars                    = 10;              // Risk in GBP
 
-input        string                  string_2                   = "<><><><><><> Time Filter Setting <><><><><><> ";//_
-input        bool                    enableTimeSession          = false;           // Enable Time Session
-input        string                  start_time_session         = "01:00";         // Start Session
-input        string                  end_time_session           = "23:59";         // End Session
+input        string                  time_setting               = "<><><><><> Time Filter Settings <><><><><>";             //_
+input        selectDay               newYorkSessionDay          = curr;            // Select Day for Start Time
+input        bool                    enableTimeFilter           = false;           // Enable Time Filter
+input        string                  startTime                  = "03:00";         // Start Time Session
+input        string                  endTime                    = "09:00";         // End Time Session
 
 input        string                  string_0_2                 = "<><><><><><> Trailing Setting<><><><><><>";   //__
 input        bool                    indivial_trailing          = false;           // Indiviual Trailing
@@ -125,21 +136,23 @@ input        int                     High_Stop_Time             = 15;
 input        bool                    show_high_line             = true;                 //Show verticle Line when high news comes
 input        selectLine              Select_News_Line           = 0;                    //News Line
 input        bool                    mobileAlert                = true;                 //Mobile Alert
-input        bool                    Medium_Impact_News         = false;                // Medium Impact News
+input        bool                    Medium_Impact_News         = true;                 // Medium Impact News
 input        int                     Medium_Start_Time          = 60;                   // Stop Trade before medium News (min)
 input        int                     Medium_Stop_Time           = 15;                   // Stop Trade after medium News (min)
-input        bool                    show_medium_line           = false;                // Show vertical Line when medium news comes
-input        bool                    Low_Impact_News            = false;                // Low Impact News
+input        bool                    show_medium_line           = true;                 // Show vertical Line when medium news comes
+input        bool                    Low_Impact_News            = true;                 // Low Impact News
 input        int                     Low_Start_Time             = 60;                   // Stop Trade before low News (min)
 input        int                     Low_Stop_Time              = 15;                   // Stop Trade after low News (min)
-input        bool                    show_low_line              = false;                // Show vertical Line when low news comes
+input        bool                    show_low_line              = true;                 // Show vertical Line when low news comes
 
 // Global Variables
 static double tickCurrentBid = 0;
 double tickPreviousBid = 0;
 static double tickCurrentAsk = 0;
 double tickPreviousAsk = 0;
-datetime startSessionTime, endSessionTime;
+int newYorkStartTime = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0;
+datetime newYorkStartTrading = 0, newYorkEndTrading = 0;
+int maxTrades = 2; // Max Concurrent Trades
 int GMT_Broker_Time = +2; // GMT_Broker_Time Time of your Broker
 int                     gmt                        = 0;                   // GMT_Broker_Time Time of your Broker
 string Lname="newsLabel3";
@@ -179,7 +192,7 @@ int OnInit()
             Print(" Order Data: ", orderData[i], " i: ", i);
            }
 
-         if(ArraySize(orderData) >= 6)
+         if(ArraySize(orderData) >= 8)
            {
             if(orderData[0] == Symbol())
               {
@@ -188,11 +201,13 @@ int OnInit()
                ulong  sell_ticket_local = (ulong)-1;
                string symbol_local      = orderData[0];
                double price_local       = StringToDouble(orderData[1]);
-               double sl_local          = StringToDouble(orderData[2]);
-               double tp_local          = StringToDouble(orderData[3]);
+               double sl_buy_local      = StringToDouble(orderData[2]);
+               double tp_buy_local      = StringToDouble(orderData[3]);
+               double sl_sell_local     = StringToDouble(orderData[4]);
+               double tp_sell_local     = StringToDouble(orderData[5]);
                // if your CSV has extra fields (tp2,tp3, etc.) parse here as needed
-               datetime start_local     = StringToTime(orderData[4]);
-               datetime end_local       = StringToTime(orderData[5]);
+               datetime start_local     = StringToTime(orderData[6]);
+               datetime end_local       = StringToTime(orderData[7]);
 
                ArrayResize(levelsAre,ArraySize(levelsAre)+1);
                levelsAre[ArraySize(levelsAre) - 1] = price_local;
@@ -212,7 +227,8 @@ int OnInit()
                  {
                   addToNewTradeStore(buy_ticket_local, sell_ticket_local,
                                      symbol_local, price_local,
-                                     sl_local, tp_local,
+                                     sl_buy_local, tp_buy_local,
+                                     sl_sell_local, tp_sell_local,
                                      start_local, end_local,
                                      buy_virtual_tp_hit, sell_virtual_tp_hit);
                  }
@@ -232,8 +248,19 @@ int OnInit()
 
    struct_level_check();
 
-   timeFilter(true,start_time_session, end_time_session, startSessionTime, endSessionTime);
-   Print(" Session Start  = ", startSessionTime,  " Asian  Session End = ", endSessionTime);
+   string time[];
+   StringSplit(startTime,':',time);
+   newYorkStartTime = (int)StringToInteger(time[0]);
+   newYorkStartMin  = (int)StringToInteger(time[1]);
+   Print("NewYork Start Time Hour: ",newYorkStartTime,"  Start Time Min: ",newYorkStartMin);
+   time[0] = "";
+   time[1] = "";
+   StringSplit(endTime,':',time);
+   newYorkEndHour = (int)StringToInteger(time[0]);
+   newYorkEndMin  = (int)StringToInteger(time[1]);
+   Print("NewYork End Time Hour: ",newYorkEndHour,"  End Time Min: ",newYorkEndMin);
+   timeFilter(true);
+
 
    int timeDifference = (int)TimeCurrent() - (int)TimeGMT();
    Print("Time Difference is: ", timeDifference);
@@ -394,6 +421,7 @@ void OnTick()
 void mainActivity()
   {
 //---
+   newBar();
    if(indivial_trailing)
      {
       Individual_Trailing();
@@ -427,10 +455,9 @@ void mainActivity()
       tickCurrentAsk  = Ask;
      }
 
-// Print(" Time is: ", TimeCurrent());
-   timeFilter(false,start_time_session, end_time_session, startSessionTime, endSessionTime);
-// Comment(" Session Start  = ", startSessionTime,  " Asian  Session End = ", endSessionTime);
-   if((!enableTimeSession) || (enableTimeSession && TimeCurrent() >= startSessionTime && TimeCurrent() <= endSessionTime))
+   timeFilter(false);
+//   Comment(" Session Start  = ", newYorkStartTrading,  " Asian  Session End = ", newYorkEndTrading);
+   if((enableTimeFilter && TimeCurrent() >= newYorkStartTrading && TimeCurrent() <= newYorkEndTrading) || !enableTimeFilter)
      {
       removeFromStructure();
       if(bothHitsSl)
@@ -441,6 +468,22 @@ void mainActivity()
      }
   }
 //+------------------------------------------------------------------+
+bool newBar()
+  {
+   static datetime lastbar;
+   datetime curbar = iTime(Symbol(), PERIOD_CURRENT, 0);
+   if(lastbar != curbar)
+     {
+      lastbar = curbar;
+      Print(" ---------------------- New Bar :: ---------------------- ",lastbar);
+      return (true);
+     }
+   else
+     {
+      return (false);
+     }
+  }
+
 //+------------------------------------------------------------------+
 //|                                                                  |
 //+------------------------------------------------------------------+
@@ -566,14 +609,16 @@ void struct_level_check()
                buy_virtual_tp_hit = false;
                sell_virtual_tp_hit = false;
               }
-            newTradeStore[i].buy_hit_virtual_sl = buy_virtual_tp_hit;
+            newTradeStore[i].buy_hit_virtual_sl  = buy_virtual_tp_hit;
             newTradeStore[i].sell_hit_virtual_sl = sell_virtual_tp_hit;
-            newTradeStore[i].symbol      = "";
-            newTradeStore[i].price       = 0.0;
-            newTradeStore[i].stop_loss   = 0.0;
-            newTradeStore[i].take_profit = 0.0;
-            newTradeStore[i].start_time  = 0;
-            newTradeStore[i].end_time    = 0;
+            newTradeStore[i].symbol           = "";
+            newTradeStore[i].price            = 0.0;
+            newTradeStore[i].stop_loss_buy    = 0.0;
+            newTradeStore[i].take_profit_buy  = 0.0;
+            newTradeStore[i].stop_loss_sell   = 0.0;
+            newTradeStore[i].take_profit_sell = 0.0;
+            newTradeStore[i].start_time       = 0;
+            newTradeStore[i].end_time         = 0;
             return;
            }
         }
@@ -587,7 +632,8 @@ void struct_level_check()
 //+------------------------------------------------------------------+
 void addToNewTradeStore(ulong r_buy_ticket, ulong r_sell_ticket,
                         string r_symbol, double r_price,
-                        double r_stop_loss, double r_take_profit,
+                        double r_stop_loss_buy, double r_take_profit_buy,
+                        double r_stop_loss_sell, double r_take_profit_sell,
                         datetime r_start_time, datetime r_end_time, bool r_buy_hit_sl, bool r_sell_hit_sl)
   {
    Print(" Tier 1. ");
@@ -602,8 +648,10 @@ void addToNewTradeStore(ulong r_buy_ticket, ulong r_sell_ticket,
             newTradeStore[i].sell_ticket = r_sell_ticket;
             newTradeStore[i].symbol      = r_symbol;
             newTradeStore[i].price       = r_price;
-            newTradeStore[i].stop_loss   = r_stop_loss;
-            newTradeStore[i].take_profit = r_take_profit;
+            newTradeStore[i].stop_loss_buy   = r_stop_loss_buy;
+            newTradeStore[i].take_profit_buy = r_take_profit_buy;
+            newTradeStore[i].stop_loss_sell   = r_stop_loss_sell;
+            newTradeStore[i].take_profit_sell = r_take_profit_sell;
             newTradeStore[i].start_time  = r_start_time;
             newTradeStore[i].end_time    = r_end_time;
             newTradeStore[i].buy_hit_virtual_sl = r_buy_hit_sl;
@@ -612,8 +660,10 @@ void addToNewTradeStore(ulong r_buy_ticket, ulong r_sell_ticket,
             Print("Stored -> idx: ", i,
                   " | Symbol: ", newTradeStore[i].symbol,
                   " | price: ", DoubleToString(newTradeStore[i].price, Digits()),
-                  " | sl: ", DoubleToString(newTradeStore[i].stop_loss, Digits()),
-                  " | tp: ", DoubleToString(newTradeStore[i].take_profit, Digits()),
+                  " | Sl Buy: ", DoubleToString(newTradeStore[i].stop_loss_buy, Digits()),
+                  " | Tp Buy: ", DoubleToString(newTradeStore[i].take_profit_buy, Digits()),
+                  "\n | Sl Sell: ", DoubleToString(newTradeStore[i].stop_loss_sell, Digits()),
+                  " | Tp Sell: ", DoubleToString(newTradeStore[i].take_profit_sell, Digits()),
                   " | start: ", TimeToString(newTradeStore[i].start_time, TIME_DATE|TIME_SECONDS),
                   " | end: ", TimeToString(newTradeStore[i].end_time, TIME_DATE|TIME_SECONDS),
                   " | Buy Virtal Sl Hit: ", newTradeStore[i].buy_hit_virtual_sl,
@@ -642,12 +692,12 @@ void tradePlacingCheck()
                   if((tickPreviousBid > levelPriceIs && tickCurrentBid < levelPriceIs) ||
                      (tickPreviousBid < levelPriceIs && tickCurrentBid > levelPriceIs))
                     {
-                     if(countLiveTrades() < maxTrades)
+                     if(countLiveTrades() == 0)
                        {
                         if((enableSpreadFilter && spreadFilter()) || !enableSpreadFilter)
                           {
-                           ulong buyTicket = placeBuyTrade(newTradeStore[i].stop_loss, newTradeStore[i].take_profit);
-                           ulong sellTicket = placeSellTrade(newTradeStore[i].stop_loss, newTradeStore[i].take_profit);
+                           ulong buyTicket = placeBuyTrade(newTradeStore[i].stop_loss_buy, newTradeStore[i].take_profit_buy);
+                           ulong sellTicket = placeSellTrade(newTradeStore[i].stop_loss_sell, newTradeStore[i].take_profit_sell);
 
                            newTradeStore[i].buy_ticket = buyTicket;
                            newTradeStore[i].sell_ticket = sellTicket;
@@ -671,17 +721,31 @@ ulong placeBuyTrade(double stoploss, double takeprofit)
    double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
    double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
 
-   if(stoploss != 0)
+   if(useTpSlPips)
      {
-      buySL = Ask - (stoploss * Point());
+      if(stopLoss != 0)
+        {
+         buySL = Ask - (stopLoss * 10 * Point());
+        }
+      if(takeProfit != 0)
+        {
+         buyTp = Ask + (takeProfit * 10 * Point());
+        }
      }
-   if(takeprofit != 0)
+   else
      {
-      buyTp = Ask + (takeprofit * Point());
+      if(stoploss > 0)
+        {
+         buySL = stoploss;
+        }
+      if(takeprofit > 0)
+        {
+         buyTp = takeprofit;
+        }
      }
 
    double distance = MathAbs((Ask - buySL) / Point());
-   if(trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,getLot(distance),Ask,buySL,buyTp,"Buy Trade Placed"))
+   if(trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,getLot(distance),Ask,buySL,buyTp,tradeComment+" Buy"))
      {
       Print("Buy Trade Placed: ",trade.ResultOrder());
       return trade.ResultOrder();
@@ -703,16 +767,30 @@ ulong placeSellTrade(double stoploss, double takeprofit)
    double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
    double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
 
-   if(stoploss != 0)
+   if(useTpSlPips)
      {
-      sellSL = Bid + (stoploss * Point());
+      if(stopLoss != 0)
+        {
+         sellSL = Bid + (stopLoss * 10 * Point());
+        }
+      if(takeProfit != 0)
+        {
+         sellTp = Bid - (takeProfit * 10 * Point());
+        }
      }
-   if(takeprofit != 0)
+   else
      {
-      sellTp = Bid - (takeprofit * Point());
+      if(stoploss > 0)
+        {
+         sellSL = stoploss;
+        }
+      if(takeprofit > 0)
+        {
+         sellTp = takeprofit;
+        }
      }
    double distance = MathAbs((Bid - sellSL) / Point());
-   if(trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,getLot(distance),Bid,sellSL,sellTp,"Sell Trade Placed"))
+   if(trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,getLot(distance),Bid,sellSL,sellTp,tradeComment+ " Sell"))
      {
       Print("Sell Trade PLaced: ",trade.ResultOrder());
       return trade.ResultOrder();
@@ -783,49 +861,11 @@ double getLot(double stop_loss)
 //+------------------------------------------------------------------+
 //|                                                                  |
 //+------------------------------------------------------------------+
-void timeFilter(bool onInit,string startTime,string endTime,datetime & sessionStart,datetime & sessionEnd)
+void timeFilter(bool onInit)
   {
-   int newYorkStartHour = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0;
-
-   datetime newYorkStartTrading,newYorkEndTrading;
-
-   string time[];
-   StringSplit(startTime,':',time);
-   newYorkStartHour = (int)StringToInteger(time[0]);
-   newYorkStartMin  = (int)StringToInteger(time[1]);
-
-   EventSetMillisecondTimer(500);
-   time[0] = "";
-   time[1] = "";
-   StringSplit(endTime,':',time);
-   newYorkEndHour = (int)StringToInteger(time[0]);
-   newYorkEndMin  = (int)StringToInteger(time[1]);
-
-// Print(" Start Time Hour: ",newYorkStartHour,"  Start Time Min: ",newYorkStartMin);
-// Print(" End Time Hour: ",newYorkEndHour,"  End Time Min: ",newYorkEndMin);
-
-
-   datetime startDateTime;
-   MqlDateTime st;
-   TimeCurrent(st); // get current date
-   st.hour   = newYorkStartHour;
-   st.min    = newYorkStartMin;
-   st.sec    = 0;
-   startDateTime = StructToTime(st);
-
-
-   datetime endDateTime;
-   MqlDateTime et;
-   TimeCurrent(et); // get current date
-   et.hour   = newYorkEndHour;
-   et.min    = newYorkEndMin;
-   et.sec    = 0;
-   endDateTime = StructToTime(et);
-
-
    MqlDateTime sdate,edate;
    datetime start_Time = 0, end_Time = 0;
-   if(startDateTime > endDateTime)
+   if(newYorkSessionDay == prev)
      {
       if(onInit)
         {
@@ -834,9 +874,9 @@ void timeFilter(bool onInit,string startTime,string endTime,datetime & sessionSt
         }
       else
         {
-         start_Time = sessionStart;
-         end_Time = sessionEnd;
-         if(TimeCurrent() >= sessionEnd && sessionEnd != 0)
+         start_Time = newYorkStartTrading;
+         end_Time = newYorkEndTrading;
+         if(TimeCurrent() >= newYorkEndTrading && newYorkEndTrading != 0)
            {
             start_Time = iTime(Symbol(),PERIOD_D1,0);
             end_Time = start_Time + 86400;
@@ -848,7 +888,6 @@ void timeFilter(bool onInit,string startTime,string endTime,datetime & sessionSt
       start_Time = iTime(Symbol(),PERIOD_D1,0);
       end_Time = iTime(Symbol(),PERIOD_D1,0);
      }
-
    if(TimeToStruct(end_Time,edate))
      {
       edate.hour = newYorkEndHour;
@@ -861,7 +900,7 @@ void timeFilter(bool onInit,string startTime,string endTime,datetime & sessionSt
 
    if(TimeToStruct(start_Time,sdate))
      {
-      sdate.hour = newYorkStartHour;
+      sdate.hour = newYorkStartTime;
       sdate.min  = newYorkStartMin;
       sdate.sec  = 0;
      }
@@ -869,8 +908,9 @@ void timeFilter(bool onInit,string startTime,string endTime,datetime & sessionSt
       Print("Error in Converting Time: ",GetLastError());
    newYorkStartTrading = StructToTime(sdate);
 
-   sessionStart = newYorkStartTrading;
-   sessionEnd   = newYorkEndTrading;
+// if(onInit)
+//Print("NewYork Start Time ",newYorkStartTrading,"End Date: ",newYorkEndTrading);
+//Print("Edate: ",edate.hour," ",edate.min," Sdate: ",sdate.hour," ",sdate.min);
   }
 //+------------------------------------------------------------------+
 //|                                                                  |
@@ -941,8 +981,17 @@ void virtualSLHitCheck()
         {
          if(TimeCurrent() > newTradeStore[i].start_time && TimeCurrent() < newTradeStore[i].end_time)
            {
-            double buy_sl = newTradeStore[i].price - (newTradeStore[i].stop_loss * Point());
-            double sell_sl = newTradeStore[i].price + (newTradeStore[i].stop_loss * Point());
+            double buy_sl = 0, sell_sl = 0;
+            if(!useTpSlPips)
+              {
+               buy_sl = newTradeStore[i].stop_loss_buy;
+               sell_sl = newTradeStore[i].stop_loss_sell;
+              }
+            else
+              {
+               buy_sl = stopLoss != 0 ? newTradeStore[i].price - (stopLoss * 10 * Point()) : 0;
+               sell_sl = stopLoss != 0 ? newTradeStore[i].price + (stopLoss * 10 * Point()) : 0;
+              }
             if(newTradeStore[i].buy_hit_virtual_sl == false)
               {
                if((tickPreviousBid < buy_sl && tickCurrentBid > buy_sl))
@@ -1017,6 +1066,11 @@ void breakEven()
         {
          if(PositionGetString(POSITION_SYMBOL)==Symbol()  && PositionGetInteger(POSITION_MAGIC) == magic_no)
            {
+            if(isCounterpartOpen(ticket))
+              {
+               // counterpart still open -> skip trailing for this position
+               continue;
+              }
             //========================================================Buy Condition=========================================================================
             if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
               {
@@ -1061,6 +1115,48 @@ void breakEven()
 //+------------------------------------------------------------------+
 //|                                                                  |
 //+------------------------------------------------------------------+
+bool isCounterpartOpen(ulong ticket)
+  {
+// scan stored pairs
+   for(int k=0; k<MaxOrders; k++)
+     {
+      // check if this ticket is the buy side in the pair
+      if(newTradeStore[k].buy_ticket == ticket)
+        {
+         ulong other = newTradeStore[k].sell_ticket;
+         if(other <= 0)
+            return false; // no counterpart recorded -> treat as closed
+         // check if counterpart ticket exists in current positions
+         for(int p = PositionsTotal()-1; p >= 0; p--)
+           {
+            ulong t = PositionGetTicket(p);
+            if(t == other)
+               return true; // counterpart still open
+           }
+         return false; // counterpart not found -> closed
+        }
+
+      // check if this ticket is the sell side in the pair
+      if(newTradeStore[k].sell_ticket == ticket)
+        {
+         ulong other = newTradeStore[k].buy_ticket;
+         if(other <= 0)
+            return false; // no counterpart recorded -> treat as closed
+         for(int p = PositionsTotal()-1; p >= 0; p--)
+           {
+            ulong t = PositionGetTicket(p);
+            if(t == other)
+               return true; // counterpart still open
+           }
+         return false; // counterpart not found -> closed
+        }
+     }
+// ticket not found in the stored pairs -> treat as no counterpart open
+   return false;
+  }
+//+------------------------------------------------------------------+
+//|                                                                  |
+//+------------------------------------------------------------------+
 void Individual_Trailing()
   {
    int openedpositions;
@@ -1075,13 +1171,19 @@ void Individual_Trailing()
          ulong ticket = PositionGetTicket(i);
          if(PositionSelectByTicket(ticket))
            {
-            if(PositionGetString(POSITION_SYMBOL)==Symbol()  && PositionGetInteger(POSITION_MAGIC) ==magic_no) // only look if mygrid and symbol. ..
+            if(PositionGetString(POSITION_SYMBOL)==Symbol()  && PositionGetInteger(POSITION_MAGIC) == magic_no) // only look if mygrid and symbol. ..
               {
+               if(isCounterpartOpen(ticket))
+                 {
+                  // counterpart still open -> skip trailing for this position
+                  continue;
+                 }
 
                double SymbolAsk           = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_ASK);
                double SymbolBid           = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_BID);
                int SymbolDigits           = (int)SymbolInfoInteger(PositionGetString(POSITION_SYMBOL), SYMBOL_DIGITS);
                double SymbolTickSize      = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_SIZE);
+
                int type= (int)PositionGetInteger(POSITION_TYPE);
 
                if(type==POSITION_TYPE_BUY) // its a long position
@@ -1154,9 +1256,11 @@ void saveNewTradeStoreFile()
       // convert values to strings
       string buyTicketStr  = IntegerToString((long)newTradeStore[i].buy_ticket);
       string sellTicketStr = IntegerToString((long)newTradeStore[i].sell_ticket);
-      string priceStr      = DoubleToString(newTradeStore[i].price, _Digits);
-      string slStr         = DoubleToString(newTradeStore[i].stop_loss, _Digits);
-      string tpStr         = DoubleToString(newTradeStore[i].take_profit, _Digits);
+      string priceStr      = DoubleToString(newTradeStore[i].price, Digits());
+      string slBuyStr      = DoubleToString(newTradeStore[i].stop_loss_buy, Digits());
+      string tpBuyStr      = DoubleToString(newTradeStore[i].take_profit_buy, Digits());
+      string slSellStr      = DoubleToString(newTradeStore[i].stop_loss_sell, Digits());
+      string tpSellStr      = DoubleToString(newTradeStore[i].take_profit_sell, Digits());
 
       string startTimeStr  = (newTradeStore[i].start_time != 0) ? TimeToString(newTradeStore[i].start_time, TIME_DATE|TIME_SECONDS) : "";
       string endTimeStr    = (newTradeStore[i].end_time   != 0) ? TimeToString(newTradeStore[i].end_time, TIME_DATE|TIME_SECONDS)   : "";
@@ -1185,7 +1289,8 @@ void saveNewTradeStoreFile()
       // build CSV line and write
       string line = buyTicketStr + "," + sellTicketStr + "," +
                     newTradeStore[i].symbol + "," +
-                    priceStr + "," + slStr + "," + tpStr + "," +
+                    priceStr + "," + slBuyStr + "," + tpBuyStr + "," +
+                    slSellStr + "," + tpSellStr + "," +
                     startTimeStr + "," + endTimeStr + "," +
                     buyHitStr + "," + sellHitStr + "\r\n";
 
@@ -1220,8 +1325,10 @@ void loadNewTradeStoreFile()
       newTradeStore[j].sell_ticket          = (ulong)-1;
       newTradeStore[j].symbol               = "";
       newTradeStore[j].price                = 0.0;
-      newTradeStore[j].stop_loss            = 0.0;
-      newTradeStore[j].take_profit          = 0.0;
+      newTradeStore[j].stop_loss_buy        = 0.0;
+      newTradeStore[j].take_profit_buy      = 0.0;
+      newTradeStore[j].stop_loss_sell       = 0.0;
+      newTradeStore[j].take_profit_sell     = 0.0;
       newTradeStore[j].start_time           = 0;
       newTradeStore[j].end_time             = 0;
       newTradeStore[j].buy_hit_virtual_sl   = false;
@@ -1238,24 +1345,26 @@ void loadNewTradeStoreFile()
       string tokens[];
       int total = StringSplit(line, ',', tokens);
 
-      if(total >= 10)
+      if(total >= 12)
         {
          newTradeStore[idx].buy_ticket  = (ulong)tokens[0];
          newTradeStore[idx].sell_ticket = (ulong)tokens[1];
          newTradeStore[idx].symbol      = tokens[2];
          newTradeStore[idx].price       = StringToDouble(tokens[3]);
-         newTradeStore[idx].stop_loss   = StringToDouble(tokens[4]);
-         newTradeStore[idx].take_profit = StringToDouble(tokens[5]);
+         newTradeStore[idx].stop_loss_buy   = StringToDouble(tokens[4]);
+         newTradeStore[idx].take_profit_buy = StringToDouble(tokens[5]);
+         newTradeStore[idx].stop_loss_sell  = StringToDouble(tokens[6]);
+         newTradeStore[idx].take_profit_sell = StringToDouble(tokens[7]);
 
-         string sStart = tokens[6];
-         string sEnd   = tokens[7];
+         string sStart = tokens[8];
+         string sEnd   = tokens[9];
          newTradeStore[idx].start_time = (StringLen(sStart) > 0) ? StringToTime(sStart) : 0;
          newTradeStore[idx].end_time   = (StringLen(sEnd)   > 0) ? StringToTime(sEnd)   : 0;
 
          bool bHit = false;
          bool sHit = false;
 
-         if(tokens[8] == "true")
+         if(tokens[10] == "true")
            {
             bHit = true;
            }
@@ -1264,7 +1373,7 @@ void loadNewTradeStoreFile()
             bHit = false;
            }
 
-         if(tokens[9] == "true")
+         if(tokens[11] == "true")
            {
             sHit = true;
            }
@@ -1282,9 +1391,11 @@ void loadNewTradeStoreFile()
             " buy_ticket=", newTradeStore[idx].buy_ticket,
             " sell_ticket=", newTradeStore[idx].sell_ticket,
             " symbol=", newTradeStore[idx].symbol,
-            " price=", DoubleToString(newTradeStore[idx].price, _Digits),
-            " \n sl=", DoubleToString(newTradeStore[idx].stop_loss, _Digits),
-            " tp=", DoubleToString(newTradeStore[idx].take_profit, _Digits),
+            " price=", DoubleToString(newTradeStore[idx].price, Digits()),
+            " \n sl buy=", DoubleToString(newTradeStore[idx].stop_loss_buy, Digits()),
+            " tp buy=", DoubleToString(newTradeStore[idx].take_profit_buy, Digits()),
+            " sl sell=", DoubleToString(newTradeStore[idx].stop_loss_sell, Digits()),
+            " tp sell=", DoubleToString(newTradeStore[idx].take_profit_sell, Digits()),
             " start=", (newTradeStore[idx].start_time != 0 ? TimeToString(newTradeStore[idx].start_time, TIME_DATE|TIME_SECONDS) : ""),
             " end=", (newTradeStore[idx].end_time   != 0 ? TimeToString(newTradeStore[idx].end_time,   TIME_DATE|TIME_SECONDS) : ""),
             " buyHit=", newTradeStore[idx].buy_hit_virtual_sl,