← К каталогу
Исходный код · ID 4493

equity 2026.mq4

Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Equity 2026 — это советник для MetaTrader 4, предназначенный для отслеживания баланса и управления открытыми позициями. Он не открывает новые сделки, а только контролирует существующие позиции, отфильтрованные по MagicNumber (или все без фильтра, если MagicNumber=0), на любом символе. Основная задача — закрытие позиций при достижении целевого уровня доходности, а также автоматическая корректировка стоп-лоссов, тейк-профитов и трейлинг-стопов.

Советник вычисляет начальный баланс (InitialEquity), сохраняя его в файл, и отслеживает текущий баланс относительно заданной целевой прибыли. При достижении целевого уровня все позиции закрываются. Также реализована логика закрытия убыточных позиций при превышении порога «Balance − TargetEquity». Имеются дополнительные механизмы: ограничение максимального плавающего убытка/прибыли, закрытие по проценту от наибольшего убытка и корректировка позиций при перевесе прибыльных/убыточных сделок.

Встроена информационная панель с данными о начальном и текущем балансе, целевом уровне и плавающем P/L по направлениям. Доступна аварийная кнопка «Close All» для ручного закрытия всех позиций. Параметры стоп-лосса, тейк-профита и трейлинг-стопа настраиваются через множители ATR с отдельными периодами и таймфреймами для каждого.

Версия 3.1 убрала ограничение по символу — советник управляет всеми открытыми позициями, отфильтрованными только по MagicNumber. При отсутствии открытых позиций баланс пересчитывается и сохраняется как новая начальная точка отсчёта.

Настройки программы

НастройкаОписание
Main_Settings Раздел основных настроек советника.
TargetEquityGain Базовый целевой прирост баланса в единицах валюты (умножается на ATR, если UseATR включён).
FileName Имя файла для сохранения и загрузки значения InitialEquity.
ATRPeriod Период ATR для расчёта волатильности при отслеживании баланса.
ATRTimeframe Таймфрейм ATR для расчёта волатильности при отслеживании баланса.
ATREquityMultiplier Множитель ATR для масштабирования целевого прироста баланса (используется при включённом UseATR).
UseATR Включает или отключает корректировку TargetEquityGain множителем ATR.
MagicNumber Магический номер для фильтрации позиций (0 — фильтрация отключена, управляются все позиции).
Offset_Closure_Settings Раздел настроек закрытия позиций.
ActivationLevel Уровень прибыли, при котором инициируется закрытие позиций buy или sell.
MinimumProfit Минимальная общая прибыль закрытых позиций, необходимая для продолжения закрытия.
MaximumProfit Максимальная общая прибыль закрытых позиций, при которой прекращается дальнейшее закрытие.
MinimumRemainingProfit Минимальная прибыль, которая должна остаться в прибыльных позициях после закрытия.
TradeGap Минимальная разница между количеством прибыльных и убыточных позиций для инициирования закрытия (0 — отключено).
MinimumValue Минимальное суммарное P/L (USD на сделку), умноженное на количество сделок, для закрытия крупнейших прибыльных и убыточных позиций одного направления (0 — отключено).
Balance_TargetEquity_Closure Раздел настроек закрытия по разнице баланса и целевого баланса.
BalanceTargetEquityThreshold Порог для разницы «Balance − TargetEquity», при достижении которого инициируется закрытие убыточных позиций.
Info_Panel_Settings Раздел настроек информационной панели.
PanelCorner Угол графика для размещения информационной панели (0=верхний левый, 1=верхний правый, 2=нижний левый, 3=нижний правый).
PanelWidth Ширина информационной панели в пикселях.
PanelHeight Высота информационной панели в пикселях (подстраивается под содержимое).
FontSize Размер шрифта текста на информационной панели.
LineSpacing Дополнительное расстояние между строками текста на панели (в пикселях).
TextColor Цвет текста на информационной панели (используется для меток и прибыли).
LossColor Цвет для отображения убытков на панели.
BackgroundColor Цвет фона информационной панели.
BackgroundOpacity Непрозрачность фона (0–255, 0=прозрачный, 255=непрозрачный). Значение указано для справки, в MQL4 не применяется.
ButtonYDistance Вертикальное расстояние аварийной кнопки от угла графика (в пикселях).
Profit_Loss_Settings Раздел настроек прибыли и убытка (стоп-лосс, тейк-профит, трейлинг-стоп).
StopLoss_ATRPeriod Период ATR для расчёта уровня стоп-лосса и трейлинг-стопа.
StopLoss_ATRTimeframe Таймфрейм ATR для расчёта уровня стоп-лосса и трейлинг-стопа.
StopLoss_ATRMultiplier Множитель ATR для расчёта уровня стоп-лосса.
TakeProfit_ATRPeriod Период ATR для расчёта уровня тейк-профита.
TakeProfit_ATRTimeframe Таймфрейм ATR для расчёта уровня тейк-профита.
TakeProfit_ATRMultiplier Множитель ATR для расчёта уровня тейк-профита.
OnlyNewPositions При значении true корректировка применяется только к позициям без установленного стоп-лосса и тейк-профита.
EnableStopLoss Включает или отключает корректировку стоп-лосса.
EnableTakeProfit Включает или отключает корректировку тейк-профита.
MaxFloatingLoss Максимальный допустимый плавающий убыток в валюте счёта (0 — отключено). При превышении все позиции закрываются.
MaxFloatingProfit Максимальный допустимый плавающий доход в валюте счёта (0 — отключено). При превышении все позиции закрываются.
ThresholdFloatingLoss Порог для начала мониторинга закрытия при минимальном убытке (0 — отключено).
PercentageClosure Процент от наибольшего убытка для закрытия позиций (0 — отключено). Используется совместно с ThresholdFloatingLoss.
EnableTrailingStop Включает или отключает трейлинг-стоп.
TrailingStopStart Множитель ATR, при котором трейлинг-стоп начинает следовать за ценой (например, 0.5 × ATR).
TrailingStopStep Шаг обновления трейлинг-стопа в пипсах.
TrailingStopSizeMode Режим определения размера трейлинг-стопа: PercentOfProfit — процент от прибыли, ATRTrailMultiplier — множитель ATR.
TrailingStopSize Размер трейлинг-стопа в процентах от прибыли (используется при режиме PercentOfProfit).
TrailingStopATRMultiplier Множитель ATR для определения размера трейлинг-стопа (используется при режиме ATRTrailMultiplier).
Получить полный код

Поиск по коду файла

#property version   "3.1"
#property strict

enum ENUM_TRAILING_SIZE_MODE
{
   PercentOfProfit = 0, // % of profit
   ATRTrailMultiplier = 1    // ATR * multiplier (renamed from ATRMultiplier)
};

input string Main_Settings;
input double TargetEquityGain = 10.0; // Base equity gain in currency units (multiplied by ATR if UseATR is true)
input string FileName = "EquityTracker.txt"; // File to store InitialEquity
input int ATRPeriod = 14; // ATR period for volatility calculation (Equity tracking)
input ENUM_TIMEFRAMES ATRTimeframe = PERIOD_CURRENT; // ATR timeframe (Equity tracking)
input double ATREquityMultiplier = 0.5; // Multiplier for ATR to scale equity gain target (Equity tracking, renamed from ATRMultiplier)
input bool UseATR = false; // Enable/disable ATR-based adjustment for TargetEquityGain
input int MagicNumber = 0; // Magic number to filter positions (set to 0 to disable filtering)

input string Offset_Closure_Settings; // Section Header
input double ActivationLevel = 80.0; // Profit level to trigger closure of buy or sell positions
input double MinimumProfit = 5.0; // Minimum overall profit of closed positions
input double MaximumProfit = 20.0; // Maximum overall profit of closed positions
input double MinimumRemainingProfit = 30.0; // Minimum profit to remain in profitable positions after closure
input int TradeGap = 0; // Min difference between profitable and losing positions to trigger closure (0 = disabled)
input double MinimumValue = 0.0; // Min combined P/L (USD per trade) * number of trades to close largest winning and losing positions of same direction (0 = disabled)

input string Balance_TargetEquity_Closure;
input double BalanceTargetEquityThreshold = 50.0; // Threshold for Balance - TargetEquity to trigger losing position closure

input string Info_Panel_Settings;
input ENUM_BASE_CORNER PanelCorner = CORNER_LEFT_UPPER; // Chart corner for info panel (0=Top-Left, 1=Top-Right, 2=Bottom-Left, 3=Bottom-Right)
input int PanelWidth = 270; // Panel width in pixels
input int PanelHeight = 135; // Panel height in pixels (adjusted to fit content after YDISTANCE change)
input int FontSize = 12; // Font size for text
input int LineSpacing = 4; // Additional spacing between lines (pixels)
input color TextColor = clrLime; // Text color (used for labels and profits)
input color LossColor = clrRed; // Color for losses
input color BackgroundColor = clrIndigo; // Background color
input int BackgroundOpacity = 255; // Background opacity (0-255, 0=transparent, 255=opaque) - used for reference, not applied in MQL4
input int ButtonYDistance = 145; // Y-distance for emergency button

input string Profit_Loss_Settings = "===== Profit/Loss Settings ====="; // Section Header

input int StopLoss_ATRPeriod = 14;        // ATR period for Stop Loss and Trailing Stop
input ENUM_TIMEFRAMES StopLoss_ATRTimeframe = PERIOD_M15; // ATR timeframe for Stop Loss and Trailing Stop
input double StopLoss_ATRMultiplier = 2.5; // ATR multiplier for Stop Loss

input int TakeProfit_ATRPeriod = 14;      // ATR period for Take Profit
input ENUM_TIMEFRAMES TakeProfit_ATRTimeframe = PERIOD_M15; // ATR timeframe for Take Profit
input double TakeProfit_ATRMultiplier = 2.5; // ATR multiplier for Take Profit

input bool OnlyNewPositions = true;      // Modify only positions without SL/TP when true
input bool EnableStopLoss = false;        // Enable stop-loss modification
input bool EnableTakeProfit = false;       // Enable take-profit modification
input double MaxFloatingLoss = 18.0;     // Max floating loss (0 = disabled, in account currency)
input double MaxFloatingProfit = 10.0;     // Max floating profit (0 = disabled, in account currency)
input double ThresholdFloatingLoss = 0; // Threshold to start monitoring for minimal loss closure (0 = disabled)
input double PercentageClosure = 40.0;     // % of highest loss to close positions (0 = disabled)
input bool EnableTrailingStop = false;    // Enable trailing stop
input double TrailingStopStart = 1.3;     // ATR multiplier to start trailing (e.g., 0.5 * ATR)
input double TrailingStopStep = 0.5;      // Step size in pips for trailing update
input ENUM_TRAILING_SIZE_MODE TrailingStopSizeMode = ATRTrailMultiplier; // Trailing stop size mode
input double TrailingStopSize = 50.0;     // Trailing stop size (% of profit)
input double TrailingStopATRMultiplier = 0.7; // Trailing stop size (ATR multiplier)

double InitialEquity = 0.0; // Stores equity when no positions are open
bool EquitySet = false;     // Flag to check if initial equity is set
double ChartATR = 0.0;      // Stores ATR value for Equity tracking
double BuyFloatingPL = 0.0; // Total floating profit/loss for buy positions
double SellFloatingPL = 0.0; // Total floating profit/loss for sell positions
int TotalBuyPositions = 0;  // Total number of open buy positions
int TotalSellPositions = 0; // Total number of open sell positions
datetime LastEquityUpdateTime = 0; // Timestamp of the last InitialEquity update

int PrevTotalBuyPositions = 0;
int PrevTotalSellPositions = 0;
double PrevBuyFloatingPL = 0.0;
double PrevSellFloatingPL = 0.0;
double PrevInitialEquity = 0.0;
datetime LastPositionLogTime = 0; // Timestamp of the last position log
datetime LastEquityLogTime = 0;   // Timestamp of the last equity log

int PreviousTickets[];
int PreviousTicketCount = 0;

struct PositionData
{
   int ticket;
   double maxProfitInPips;
};
PositionData positionData[];
int positionDataCount = 0;

double highestFloatingLoss = 0.0;  // Peak floating loss after threshold
bool thresholdTriggered = false;   // Flag to indicate threshold monitoring

int OnInit()
{
      // код доступен только после оплаты
   }

int GetPositionDataIndex(int ticket)
{
   for(int i = 0; i < positionDataCount; i++)
   {
      if(positionData[i].ticket == ticket)
         return i;
   }
   ArrayResize(positionData, positionDataCount + 1);
   positionData[positionDataCount].ticket = ticket;
   positionData[positionDataCount].maxProfitInPips = 0.0;
   positionDataCount++;
   return positionDataCount - 1;
}

void OnTick()
{
      // код доступен только после оплаты
   }

   ChartATR = iATR(Symbol(), ATRTimeframe, ATRPeriod, 1);
   if(ChartATR <= 0.0)
   {
      Print("Error retrieving ATR for ", Symbol(), ": ", GetLastError());
      ChartATR = 1.0; // Fallback to avoid zero multiplication
   }

   double totalFloatingProfit = 0.0;
   int totalFilteredPositions = 0;

   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderType() <= OP_SELL && (OrderMagicNumber() == MagicNumber || MagicNumber == 0))
         {
            totalFloatingProfit += OrderProfit() + OrderSwap() + OrderCommission();
            totalFilteredPositions++;
         }
      }
   }
   double totalFloatingLoss = -totalFloatingProfit;

   if(totalFilteredPositions == 0)
   {
      highestFloatingLoss = 0.0;
      thresholdTriggered = false;
   }

   if(MaxFloatingLoss > 0)
   {
      if(totalFloatingLoss > MaxFloatingLoss)
      {
         CloseAllPositions();
         highestFloatingLoss = 0.0;
         thresholdTriggered = false;
         return;
      }
   }

   if(MaxFloatingProfit > 0.0)
   {
      if(totalFloatingProfit > MaxFloatingProfit)
      {
         CloseAllPositions();
         Print("MaxFloatingProfit exceeded. All positions closed. Profit: ", DoubleToString(totalFloatingProfit, 2));
         return;
      }
   }

   if(ThresholdFloatingLoss > 0)
   {
      if(totalFloatingLoss > ThresholdFloatingLoss)
      {
         if(!thresholdTriggered)
         {
            thresholdTriggered = true;
            highestFloatingLoss = totalFloatingLoss;
         }
         else if(totalFloatingLoss > highestFloatingLoss)
         {
            highestFloatingLoss = totalFloatingLoss;
         }
      }

      if(thresholdTriggered)
      {
         double targetLoss = highestFloatingLoss * (PercentageClosure / 100.0);
         if(totalFloatingLoss <= targetLoss && totalFloatingLoss > 0)
         {
            CloseAllPositions();
            highestFloatingLoss = 0.0;
            thresholdTriggered = false;
            return;
         }
      }
   }

   BuyFloatingPL = 0.0;
   SellFloatingPL = 0.0;
   TotalBuyPositions = 0;
   TotalSellPositions = 0;
   int profitableBuys = 0;
   int losingBuys = 0;
   int profitableSells = 0;
   int losingSells = 0;

   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderType() <= OP_SELL && (OrderMagicNumber() == MagicNumber || MagicNumber == 0))
         {
            double pl = OrderProfit() + OrderSwap() + OrderCommission();
            if(OrderType() == OP_BUY)
            {
               BuyFloatingPL += pl;
               TotalBuyPositions++;
               if(pl >= 0) profitableBuys++;
               else losingBuys++;
            }
            else if(OrderType() == OP_SELL)
            {
               SellFloatingPL += pl;
               TotalSellPositions++;
               if(pl >= 0) profitableSells++;
               else losingSells++;
            }
         }
      }
   }

   int totalFilteredPositionsCheck = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderType() <= OP_SELL && (OrderMagicNumber() == MagicNumber || MagicNumber == 0))
         {
            totalFilteredPositionsCheck++;
         }
      }
   }
   if(totalFilteredPositionsCheck == 0 && EquitySet)
   {
      double currentEquity = AccountEquity();
      if(currentEquity != PrevInitialEquity && TimeCurrent() - LastEquityLogTime >= 60)
      {
         InitialEquity = currentEquity;
         SaveInitialEquity();
         LastEquityUpdateTime = TimeCurrent();
         Print("Initial equity updated to: ", InitialEquity);
         PrevInitialEquity = InitialEquity;
         LastEquityLogTime = TimeCurrent();
      }
   }

   if(totalFilteredPositionsCheck > 0)
   {
      if(BuyFloatingPL >= ActivationLevel)
      {
         int tradeGapDiff = profitableBuys - losingSells;
         if(TradeGap == 0 || tradeGapDiff >= TradeGap)
         {
            CloseBuyAndSomeSellPositions();
         }
      }
      else if(SellFloatingPL >= ActivationLevel)
      {
         int tradeGapDiff = profitableSells - losingBuys;
         if(TradeGap == 0 || tradeGapDiff >= TradeGap)
         {
            CloseSellAndSomeBuyPositions();
         }
      }

      if(MinimumValue > 0.0)
      {
         struct PositionDataPL
         {
            int ticket;
            double pl;
            int type; // OP_BUY or OP_SELL
         };
         PositionDataPL positions[];
         int positionCount = 0;

         for(int i = 0; i < OrdersTotal(); i++)
         {
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            {
               if(OrderType() <= OP_SELL && (OrderMagicNumber() == MagicNumber || MagicNumber == 0))
               {
                  ArrayResize(positions, positionCount + 1);
                  positions[positionCount].ticket = OrderTicket();
                  positions[positionCount].pl = OrderProfit() + OrderSwap() + OrderCommission();
                  positions[positionCount].type = OrderType();
                  positionCount++;
               }
            }
         }

         PositionDataPL buyPositions[];
         int buyCount = 0;
         PositionDataPL sellPositions[];
         int sellCount = 0;

         for(int i = 0; i < positionCount; i++)
         {
            if(positions[i].type == OP_BUY)
            {
               ArrayResize(buyPositions, buyCount + 1);
               buyPositions[buyCount] = positions[i];
               buyCount++;
            }
            else if(positions[i].type == OP_SELL)
            {
               ArrayResize(sellPositions, sellCount + 1);
               sellPositions[sellCount] = positions[i];
               sellCount++;
            }
         }

         if(TotalBuyPositions >= TotalSellPositions + 1 && buyCount >= 2 && profitableBuys > 0 && losingBuys > 0)
         {

            for(int i = 0; i < buyCount - 1; i++)
            {
               for(int j = i + 1; j < buyCount; j++)
               {
                  if(buyPositions[j].pl > buyPositions[i].pl)
                  {
                     PositionDataPL temp = buyPositions[i];
                     buyPositions[i] = buyPositions[j];
                     buyPositions[j] = temp;
                  }
               }
            }

            int largestWinnerIndex = -1;
            int largestLoserIndex = -1;
            double minPL = 0.0;

            for(int i = 0; i < buyCount; i++)
            {
               if(buyPositions[i].pl >= 0 && largestWinnerIndex == -1)
               {
                  largestWinnerIndex = i;
                  break;
               }
            }

            for(int i = 0; i < buyCount; i++)
            {
               if(buyPositions[i].pl < 0 && (largestLoserIndex == -1 || buyPositions[i].pl < minPL))
               {
                  largestLoserIndex = i;
                  minPL = buyPositions[i].pl;
               }
            }

            if(largestWinnerIndex != -1 && largestLoserIndex != -1)
            {
               double combinedPL = buyPositions[largestWinnerIndex].pl + buyPositions[largestLoserIndex].pl;
               double dynamicThreshold = MinimumValue * TotalBuyPositions;
               if(combinedPL >= dynamicThreshold)
               {
                  if(OrderSelect(buyPositions[largestWinnerIndex].ticket, SELECT_BY_TICKET, MODE_TRADES))
                  {
                     if(OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrNONE))
                        Print("Closed largest winning buy position #", buyPositions[largestWinnerIndex].ticket, " with P/L: ", buyPositions[largestWinnerIndex].pl);
                     else
                        Print("Error closing largest winning buy order #", OrderTicket(), ": ", GetLastError());
                  }
                  if(OrderSelect(buyPositions[largestLoserIndex].ticket, SELECT_BY_TICKET, MODE_TRADES))
                  {
                     if(OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrNONE))
                        Print("Closed largest losing buy position #", buyPositions[largestLoserIndex].ticket, " with P/L: ", buyPositions[largestLoserIndex].pl);
                     else
                        Print("Error closing largest losing buy order #", OrderTicket(), ": ", GetLastError());
                  }
               }
            }
         }

         else if(TotalSellPositions >= TotalBuyPositions + 1 && sellCount >= 2 && profitableSells > 0 && losingSells > 0)
         {
            for(int i = 0; i < sellCount - 1; i++)
            {
               for(int j = i + 1; j < sellCount; j++)
               {
                  if(sellPositions[j].pl > sellPositions[i].pl)
                  {
                     PositionDataPL temp = sellPositions[i];
                     sellPositions[i] = sellPositions[j];
                     sellPositions[j] = temp;
                  }
               }
            }

            int largestWinnerIndex = -1;
            int largestLoserIndex = -1;
            double minPL = 0.0;

            for(int i = 0; i < sellCount; i++)
            {
               if(sellPositions[i].pl >= 0 && largestWinnerIndex == -1)
               {
                  largestWinnerIndex = i;
                  break;
               }
            }

            for(int i = 0; i < sellCount; i++)
            {
               if(sellPositions[i].pl < 0 && (largestLoserIndex == -1 || sellPositions[i].pl < minPL))
               {
                  largestLoserIndex = i;
                  minPL = sellPositions[i].pl;
               }
            }

            if(largestWinnerIndex != -1 && largestLoserIndex != -1)
            {
               double combinedPL = sellPositions[largestWinnerIndex].pl + sellPositions[largestLoserIndex].pl;
               double dynamicThreshold = MinimumValue * TotalSellPositions;
               if(combinedPL >= dynamicThreshold)
               {
                  if(OrderSelect(sellPositions[largestWinnerIndex].ticket, SELECT_BY_TICKET, MODE_TRADES))
                  {
                     if(OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrNONE))
                        Print("Closed largest winning sell position #", sellPositions[largestWinnerIndex].ticket, " with P/L: ", sellPositions[largestWinnerIndex].pl);
                     else
                        Print("Error closing largest winning sell order #", OrderTicket(), ": ", GetLastError());
                  }
                  if(OrderSelect(sellPositions[largestLoserIndex].ticket, SELECT_BY_TICKET, MODE_TRADES))
                  {
                     if(OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrNONE))
                        Print("Closed largest losing sell position #", sellPositions[largestLoserIndex].ticket, " with P/L: ", sellPositions[largestLoserIndex].pl);
                     else
                        Print("Error closing largest losing sell order #", OrderTicket(), ": ", GetLastError());
                  }
               }
            }
         }
      }
   }

   if(EquitySet)
   {
      double currentEquity = AccountEquity();
      double dynamicTargetGain = UseATR ? (TargetEquityGain * ChartATR * ATREquityMultiplier) : TargetEquityGain;
      double targetEquity = InitialEquity + dynamicTargetGain;

      if(currentEquity >= targetEquity)
      {
         CloseAllPositions();
         if(UseATR)
            Print("Target equity gain reached. All positions closed. InitialEquity: ", InitialEquity, ", Current equity: ", currentEquity);
         else
            Print("Target equity gain reached. All positions closed. InitialEquity: ", InitialEquity, ", Current equity: ", currentEquity);
      }

      double currentBalance = AccountBalance();
      double balanceTargetEquityDiff = currentBalance - targetEquity;
      if(balanceTargetEquityDiff >= BalanceTargetEquityThreshold)
      {
         CloseSomeLosingPositions();
      }
   }

   int currentTickets[];
   ArrayResize(currentTickets, OrdersTotal());
   int currentCount = 0;

   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderType() <= OP_SELL && (OrderMagicNumber() == MagicNumber || MagicNumber == 0))
         {
            currentTickets[currentCount] = OrderTicket();
            currentCount++;
         }
      }
   }

   for(int i = 0; i < PreviousTicketCount; i++)
   {
      bool found = false;
      for(int j = 0; j < currentCount; j++)
      {
         if(PreviousTickets[i] == currentTickets[j])
         {
            found = true;
            break;
         }
      }
      if(!found)
      {
         if(OrderSelect(PreviousTickets[i], SELECT_BY_TICKET, MODE_HISTORY))
         {
            if(OrderMagicNumber() == MagicNumber || MagicNumber == 0)
            {
               Print("Position #", PreviousTickets[i], " closed. Profit: ", OrderProfit());
            }
         }
      }
   }

   ArrayResize(PreviousTickets, currentCount);
   for(int i = 0; i < currentCount; i++)
      PreviousTickets[i] = currentTickets[i];
   PreviousTicketCount = currentCount;

   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderType() <= OP_SELL && (OrderMagicNumber() == MagicNumber || MagicNumber == 0))
         {
            bool skip = OnlyNewPositions;
            if(EnableStopLoss && EnableTakeProfit)
               skip = skip && (OrderStopLoss() != 0 && OrderTakeProfit() != 0);
            else if(EnableStopLoss)
               skip = skip && (OrderStopLoss() != 0);
            else if(EnableTakeProfit)
               skip = skip && (OrderTakeProfit() != 0);

            string symbol = OrderSymbol();
            double StopLossAtrValue = iATR(symbol, StopLoss_ATRTimeframe, StopLoss_ATRPeriod, 1);
            double TakeProfitAtrValue = iATR(symbol, TakeProfit_ATRTimeframe, TakeProfit_ATRPeriod, 1);

            if(StopLossAtrValue <= 0)
            {
               Print("Error: Invalid Stop Loss ATR for ", symbol);
               continue;
            }
            if(TakeProfitAtrValue <= 0)
            {
               Print("Error: Invalid Take Profit ATR for ", symbol);
               continue;
            }

            double NewSL = OrderStopLoss();
            double NewTP = OrderTakeProfit();
            double PointValue = MarketInfo(symbol, MODE_POINT);
            double MinStop = MarketInfo(symbol, MODE_STOPLEVEL) * PointValue;
            int SymbolDigits = (int)MarketInfo(symbol, MODE_DIGITS);
            double Spread = MarketInfo(symbol, MODE_SPREAD) * PointValue;

            if(!skip || EnableTrailingStop)
            {
               if(OrderType() == OP_BUY)
               {
                  if(EnableStopLoss && !skip)
                  {
                     NewSL = OrderOpenPrice() - (StopLossAtrValue * StopLoss_ATRMultiplier);
                     if(OrderOpenPrice() - NewSL < MinStop)
                        NewSL = OrderOpenPrice() - MinStop;
                  }
                  if(EnableTakeProfit && !skip)
                  {
                     NewTP = OrderOpenPrice() + (TakeProfitAtrValue * TakeProfit_ATRMultiplier);
                     if(NewTP - OrderOpenPrice() < MinStop)
                        NewTP = OrderOpenPrice()

Показано первые 50% кода (символов: 33239)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
3 323,90₽ ≈ $40.63