class OrderTrailState
Структура, хранящая состояние отслеживаемого ордера: тикет, цена открытия, расстояние риска, пиковый R-множитель, текущая фаза трейла и флаг активности.
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «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? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.