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

brt_virtualtrail.mqh

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

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

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

О программе

Данный файл представляет собой библиотеку исходного кода для MetaTrader 4, реализующую модуль виртуального трейлинга стоп-лосса на основе множителя R (equity trailing). Модуль отслеживает открытые ордера и управляет их закрытием через OrderClose без использования OrderModify, что позволяет фиксировать прибыль по виртуальным уровням без модификации ордеров на сервере.

Библиотека поддерживает несколько фаз трейлинга: ожидание прибыли, подготовка к выходу в безубыток, активация трейла и собственно трейлинг пикового R-множителя. Состояние каждого ордера хранится в динамическом массиве без ограничения по количеству, что позволяет отслеживать неограниченное число позиций одновременно.

Модуль предоставляет API для инициализации, регистрации новых ордеров, обработки состояний на каждом тике, восстановления состояний для предшествующих сделок и синхронизации с текущими открытыми позициями. Все операции закрытия выполняются через стандартный OrderClose с заданным проскальзыванием.

Состав библиотеки

Классов: 1 · методов: 0 · конструкторов: 0 · деструкторов: 0 · отдельных функций: 12

Классы
Класс class OrderTrailState

Структура, хранящая состояние отслеживаемого ордера: тикет, цена открытия, расстояние риска, пиковый R-множитель, текущая фаза трейла и флаг активности.

Функции
Функция void BRT_VT_Recover()

Восстанавливает состояния трейла для ордеров, открытых до начала текущей сессии советника, сканируя существующие сделки и пересоздавая внутренние данные трейла.

Функция int BRT_VT_RegisterOrder(int ticket, double openPrice, double riskDist)

Регистрирует новый ордер для виртуального трейлинга после успешной отправки OrderSend, сохраняя начальную цену и расстояние стоп-лосса.

Функция void BRT_VT_Process()

Выполняет проверку всех отслеживаемых ордеров на каждом тике: рассчитывает текущий R-множитель, обновляет пиковое значение и выполняет виртуальный выход при достижении условий безубытка или трейла.

Функция void BRT_VT_Reconcile()

Синхронизирует внутренние данные трейла с текущими открытыми ордерами, удаляя записи для уже закрытых позиций.

Функция int BRT_VT_GetTrailCount()

Возвращает количество активных отслеживаемых ордеров в данный момент.

Функция double BRT_VT_GetPeakR(int ticket)

Возвращает максимальный достигнутый R-множитель прибыли для указанного тикета ордера.

Функция ENUM_TRAIL_PHASE BRT_VT_GetPhase(int ticket)

Возвращает текущую фазу трейла для указанного тикета ордера.

Функция bool BRT_VT_IsTracking(int ticket)

Проверяет, находится ли указанный тикет ордера под виртуальным трейлингом в данный момент.

Функция bool BRT_VT_IsInitialized()

Проверяет, была ли библиотека инициализирована вызовом BRT_VT_Init.

Функция bool BRT_VT_IsEnabled()

Проверяет, включён ли в данный момент модуль виртуального трейлинга.

Функция int BRT_VT_FindSlot(int ticket)

Находит внутренний индекс слота в массиве трейла по тикету ордера.

Функция void BRT_VT_FreeSlot(int slot)

Удаляет состояние трейла из внутреннего массива по индексу слота с компактификацией.

Получить полный код

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

#property strict

#ifndef BRT_VIRTUAL_TRAIL_MQH
#define BRT_VIRTUAL_TRAIL_MQH

enum ENUM_TRAIL_PHASE { 
   PHASE_IDLE,        // No profit yet
   PHASE_BE_ARMED,    // In profit but below BE trigger
   PHASE_TRAIL_ARMED, // BE trigger reached but below trail activation
   PHASE_TRAILING     // Trail activated, tracking peak R
};

struct OrderTrailState {
   int    ticket;        // Order ticket
   double openPrice;     // Order open price
   double riskDist;      // Initial SL distance in price (fixed at entry)
   double peakR;         // Peak R-multiple reached
   ENUM_TRAIL_PHASE phase;
   bool   active;        // Is this slot tracking an order
};

static int    vt_magic       = 0;
static string vt_symbol      = "";
static bool   vt_enabled     = false;
static double vt_activationR = 1.0;
static double vt_drawdownR   = 0.5;
static bool   vt_useBE       = true;
static double vt_beTriggerR  = 0.5;
static double vt_beLockR     = 0.05;
static int    vt_slippage    = 30;
static bool   vt_initialized = false;

static OrderTrailState vt_trail[];

void BRT_VT_Init(
   int    magic,
   string symbol,
   bool   enabled,
   double activationR,
   double drawdownR,
   bool   useBE,
   double beTriggerR,
   double beLockR,
   int    slippage
)
{
   vt_magic       = magic;
   vt_symbol      = symbol;
   vt_enabled     = enabled;
   vt_activationR = activationR;
   vt_drawdownR   = drawdownR;
   vt_useBE       = useBE;
   vt_beTriggerR  = beTriggerR;
   vt_beLockR     = beLockR;
   vt_slippage    = slippage;
   vt_initialized = true;

   ArrayResize(vt_trail, 0);

   Print("BRT_VT | Initialized. Magic=", magic, 
         " Symbol=", symbol,
         " Enabled=", enabled ? "YES" : "NO",
         " Activation=", DoubleToString(activationR, 2), "R",
         " Drawdown=", DoubleToString(drawdownR, 2), "R",
         " BE=", useBE ? "ON" : "OFF",
         " BE_Trigger=", DoubleToString(beTriggerR, 2), "R",
         " BE_Lock=", DoubleToString(beLockR, 2), "R");
}

void BRT_VT_Recover()
{
   if(!vt_initialized) return;
   if(!vt_enabled) return;

   ArrayResize(vt_trail, 0);

   int recovered = 0;
   int skipped   = 0;

   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != vt_symbol) continue;
      if(OrderMagicNumber() != vt_magic) continue;
      if(OrderType() != OP_BUY && OrderType() != OP_SELL) continue;

      int    ticket = OrderTicket();
      double open   = OrderOpenPrice();
      double sl     = OrderStopLoss();

      double riskDist = 0.0;
      if(sl > 0.0)
      {
         if(OrderType() == OP_BUY)
            riskDist = open - sl;
         else
            riskDist = sl - open;
      }

      if(riskDist <= 0.0)
      {
         Print("BRT_VT | RECOVER SKIP #", ticket,
               " — no valid SL to reconstruct riskDist");
         skipped++;
         continue;
      }

      int slot = BRT_VT_RegisterOrder(ticket, open, riskDist);

      if(slot >= 0)
      {
         Print("BRT_VT | RECOVERED trail state for #", ticket,
               " Open=", DoubleToString(open, Digits),
               " RiskDist=", DoubleToString(riskDist / _Point, 0), "pts");
         recovered++;
      }
      else
      {
         Print("BRT_VT | RECOVER FAIL #", ticket,
               " — could not allocate trail state");
         skipped++;
      }
   }

   Print("BRT_VT | Recovery complete: ", recovered, " recovered, ", skipped, " skipped");
}

int BRT_VT_RegisterOrder(int ticket, double openPrice, double riskDist)
{
   if(!vt_initialized)
   {
      Print("BRT_VT | RegisterOrder called but module not initialized");
      return -1;
   }

   if(!vt_enabled) return -1;

   if(ticket <= 0)
   {
      Print("BRT_VT | RegisterOrder called with invalid ticket: ", ticket);
      return -1;
   }

   if(riskDist <= 0)
   {
      Print("BRT_VT | RegisterOrder called with invalid riskDist: ", riskDist);
      return -1;
   }

   int existing = BRT_VT_FindSlot(ticket);
   if(existing >= 0)
   {
      Print("BRT_VT | Ticket #", ticket, " already registered at slot ", existing);
      return existing;
   }

   int slot = ArraySize(vt_trail);

   if(ArrayResize(vt_trail, slot + 1) != slot + 1)
   {
      Print("BRT_VT | Failed to allocate trail state for #", ticket);
      return -1;
   }

   vt_trail[slot].ticket    = ticket;
   vt_trail[slot].openPrice = openPrice;
   vt_trail[slot].riskDist  = riskDist;
   vt_trail[slot].peakR     = 0.0;
   vt_trail[slot].phase     = PHASE_IDLE;
   vt_trail[slot].active    = true;

   Print("BRT_VT | Registered #", ticket,
         " Open=", DoubleToString(openPrice, Digits),
         " RiskDist=", DoubleToString(riskDist / _Point, 0), "pts");

   return slot;
}

void BRT_VT_Process()
{
   if(!vt_initialized) return;
   if(!vt_enabled) return;

   for(int i = ArraySize(vt_trail) - 1; i >= 0; i--)
   {
      if(!vt_trail[i].active) continue;

      int ticket = vt_trail[i].ticket;

      bool s

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

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

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

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

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

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

Стоимость полного кода
681,60₽ ≈ $8.33