class CHiddenTrailManager
Класс для управления скрытым трейлинг-стопом и корзиной ордеров
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «hiddentrail_mt4.mqh» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
Данная библиотека для MetaTrader 4 реализует систему скрытого трейлинг-стопа для управления открытыми позициями. Она предоставляет класс CHiddenTrailManager, который отслеживает прибыльность ордеров и перемещает уровень стоп-лосса при достижении заданного уровня прибыли. Библиотека поддерживает три режима работы: трейлинг отдельных ордеров, корзина по текущему символу и корзина по всему аккаунту. Визуально уровни трейлинга отображаются на графике с помощью горизонтальных линий и текстовых меток.
Классов: 1 · методов: 4 · конструкторов: 1 · деструкторов: 0 · отдельных функций: 0
class CHiddenTrailManager
Класс для управления скрытым трейлинг-стопом и корзиной ордеров
CHiddenTrailManager(string pref)
Конструктор с указанием префикса для имен графических объектов на графике
void Reset()
Сброс внутреннего состояния и удаление графических объектов
void SetSettings(int magic, int slippage, int atrPeriod, double atrMult, int trailStart, int tf, double accStart, double accDrop, ENUM_BASKET_MODE mode)
Установка параметров трейлинга: магический номер, проскальзывание, период и множитель индикатора, начало трейла, таймфрейм, пороги аккаунта и режим корзины
void Update()
Обновление состояния трейлинга: расчёт уровня и проверка условий закрытия ордеров
void Deinit()
Очистка графических объектов при деинициализации
#ifndef HIDDENTRAIL_MT4_MQH
#define HIDDENTRAIL_MT4_MQH
#property strict
#property version "2.00"
#property description "Pure MQL4 Code. Do not compile in MT5."
enum ENUM_BASKET_MODE {
SINGLE_TRAIL_PROFIT, // Individual Order Trailing
BASKET_SYMBOL, // Current Symbol Basket
BASKET_ACCOUNT_EQUITY // Whole Account Basket
};
class CHiddenTrailManager {
private:
int m_magic;
int m_slippagePoints;
int m_atrPeriod;
double m_atrMultiplier;
int m_trailStartPips;
int m_timeframe; // PERIOD_M1, PERIOD_H1 etc.
double m_accTrailStart;
double m_accTrailDrop;
ENUM_BASKET_MODE m_mode;
int m_prevTrend;
double m_accountPeak;
int m_lastOrdersTotal;
string m_prefix;
double GetPipValue() {
double point = MarketInfo(Symbol(), MODE_POINT);
int digits = (int)MarketInfo(Symbol(), MODE_DIGITS);
return (digits == 3 || digits == 5) ? point * 10 : point;
}
bool IsOrderManaged(int index) {
if (OrderMagicNumber() == m_magic) return(true);
if (m_magic == -1) return(true); // All trades
if (m_magic == 0 && OrderMagicNumber() == 0) return(true); // Manual trades
return(false);
}
void CalculateSupertrend(double &atr, double &hl2, int &trend, double &band) {
atr = iATR(NULL, m_timeframe, m_atrPeriod, 0);
hl2 = (iHigh(NULL, m_timeframe, 0) + iLow(NULL, m_timeframe, 0)) / 2.0;
double atr1 = iATR(NULL, m_timeframe, m_atrPeriod, 1);
double close1 = iClose(NULL, m_timeframe, 1);
double close0 = iClose(NULL, m_timeframe, 0);
double hl2_1 = (iHigh(NULL, m_timeframe, 1) + iLow(NULL, m_timeframe, 1)) / 2.0;
double upper0 = hl2 + m_atrMultiplier * atr;
double lower0 = hl2 - m_atrMultiplier * atr;
double upper1 = hl2_1 + m_atrMultiplier * atr1;
double lower1 = hl2_1 - m_atrMultiplier * atr1;
trend = m_prevTrend;
if (close1 <= upper1 && close0 > upper0) trend = 1;
else if (close1 >= lower1 && close0 < lower0) trend = -1;
else if (trend == 0) trend = (close0 >= hl2) ? 1 : -1;
m_prevTrend = trend;
band = (trend == 1) ? lower0 : upper0;
}
void UpdateObject(string name, string type, double price, string text, color clr) {
datetime time_anchor = iTime(NULL, 0, 10) + PeriodSeconds() * 20;
datetime time_current = iTime(NULL, 0, 0) + PeriodSeconds() * 10;
if (ObjectFind(name) < 0) { // Create new
bool created = false;
if (type == "HLINE") {
created = ObjectCreate(name, OBJ_HLINE, 0, 0, price);
} else if (type == "TEXT") {
created = ObjectCreate(name, OBJ_TEXT, 0, time_anchor, price);
}
if (created) {
ObjectSet(name, OBJPROP_COLOR, clr);
ObjectSet(name, OBJPROP_STYLE, STYLE_DASH);
ObjectSet(name, OBJPROP_WIDTH, (type == "HLINE") ? 2 : 1);
if (type == "TEXT") {
ObjectSetText(name, text, 10, "Arial", clr);
}
} else {
Print("ObjectCreate failed: ", name, " Error=", GetLastError());
}
} else { // Update existing
if (type == "HLINE") {
ObjectMove(name, 0, 0, price);
} else if (type == "TEXT") {
ObjectMove(name, 0, time_current, price);
if (ObjectGetString(0, name, OBJPROP_TEXT) != text) {
ObjectSetText(name, text, 10, "Arial", clr);
}
}
}
}
void ManageAccountEquity() {
double totalProfit = 0;
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
bool magicMatch = (m_magic == -1) || (m_magic == 0 && OrderMagicNumber() == 0) || (OrderMagicNumber() == m_magic);
if(magicMatch) {
totalProfit += OrderProfit() + OrderSwap();
count++;
}
}
}
if(count == 0) {
ObjectDelete(0, m_prefix + "ACC_TXT");
m_accountPeak = 0;
return;
}
string txt = m_prefix + "ACC_TXT";
string statusText = "ACCOUNT BASKET | Profit: $" + DoubleToString(totalProfit, 2) + " | Peak: $" + DoubleToString(m_accountPeak, 2);
UpdateObject(txt, "TEXT", 0, statusText, clrGold);
ObjectSetInteger(0, txt, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, txt, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, txt, OBJPROP_YDISTANCE, 20);
if(totalProfit > m_accTrailStart) {
if(totalProfit > m_accountPeak) m_accountPeak = totalProfit;
if(totalProfit <= (m_accountPeak - m_accTrailDrop)) {
Print("ACCOUNT BASKET HIT. Closing All.");
CloseManagedOrders();
}
}
}
void ManageSymbolBasket(double stBand, int stTrend) {
double totalLots = 0;
double weightedSumPrices = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && IsOrderManaged(i)) {
double lots = OrderLots();
int type = OrderType();
double signedLots = (type == OP_BUY) ? lots : -lots;
totalLots += signedLots;
weightedSumPrices += OrderOpenPrice() * signedLots;
}
Показано первые 50% кода (символов: 7611)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.