class CTradeManager
Класс-обёртка для управления торговыми операциями: открытие позиций, трейлинг-стоп и расчёт pip-множителя.
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «trademanager.mqh» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
TradeManager.mqh — это MQL5-библиотека (include-файл), предоставляющая класс CTradeManager для управления торговыми операциями в MetaTrader 5. Класс инкапсулирует логику отправки ордеров Buy и Sell с встроенными проверками спреда, свободной маржи и требований брокера к минимальному расстоянию стоп-лосса и тейк-профита. Библиотека поддерживает трейлинг-стоп для открытых позиций и автоматическую нормализацию объёмов и цен. Внутренне используется объект CTrade из стандартной библиотеки MQL5 для исполнения торговых операций и модификации позиций.
Классов: 1 · методов: 4 · конструкторов: 1 · деструкторов: 1 · отдельных функций: 0
class CTradeManager
Класс-обёртка для управления торговыми операциями: открытие позиций, трейлинг-стоп и расчёт pip-множителя.
CTradeManager(const ulong magic, const double lot, const double max_spread, const bool use_trail, const int trail_start, const int trail_step)
Конструктор класса, задающий магический номер, фиксированный лот, максимальный спред, параметры трейлинга и настраивает тип заполнения ордера через торговый объект CTrade.
~CTradeManager(void)
Деструктор класса, освобождающий ресурсы при уничтожении экземпляра.
bool ExecuteBuy(const string symbol, const double entry_price, const double sl, const double tp, const string comment)
Открывает позицию Buy на указанном символе с заданными ценой входа, стоп-лоссом, тейк-профитом и комментарием, выполняя проверку спреда, маржи и требований брокера к stops level.
bool ExecuteSell(const string symbol, const double entry_price, const double sl, const double tp, const string comment)
Открывает позицию Sell на указанном символе с заданными ценой входа, стоп-лоссом, тейк-профитом и комментарием, выполняя проверку спреда, маржи и требований брокера к stops level.
void UpdateTrailingStop(const string symbol)
Обновляет трейлинг-стоп для открытых позиций на указанном символе, перемещая стоп-лосс при достижении нужного движения цены в пользу позиции.
double GetPipMultiplier(const string symbol)
Возвращает множитель pip для указанного символа с учётом количества знаков после запятой (3/5-значные котировки).
#property version "1.00"
#include <Trade\Trade.mqh>
class CTradeManager
{
private:
CTrade trade;
ulong magic_number;
double fixed_lot;
double max_spread_pts;
bool enable_trailing;
int trailing_start;
int trailing_step;
bool IsPositionOpen(string symbol);
public:
CTradeManager(const ulong magic, const double lot, const double max_spread, const bool use_trail, const int trail_start, const int trail_step);
~CTradeManager(void);
bool ExecuteBuy(const string symbol, const double entry_price, const double sl, const double tp, const string comment);
bool ExecuteSell(const string symbol, const double entry_price, const double sl, const double tp, const string comment);
void UpdateTrailingStop(const string symbol);
double GetPipMultiplier(const string symbol) const;
};
CTradeManager::CTradeManager(const ulong magic, const double lot, const double max_spread, const bool use_trail, const int trail_start, const int trail_step)
: magic_number(magic),
fixed_lot(lot),
max_spread_pts(max_spread),
enable_trailing(use_trail),
trailing_start(trail_start),
trailing_step(trail_step)
{
trade.SetExpertMagicNumber(magic_number);
uint filling=(uint)SymbolInfoInteger(_Symbol,SYMBOL_FILLING_MODE);
if((filling & SYMBOL_FILLING_FOK)!=0)
trade.SetTypeFilling(ORDER_FILLING_FOK);
else
if((filling & SYMBOL_FILLING_IOC)!=0)
trade.SetTypeFilling(ORDER_FILLING_IOC);
else
trade.SetTypeFilling(ORDER_FILLING_RETURN);
}
CTradeManager::~CTradeManager(void)
{
}
double CTradeManager::GetPipMultiplier(const string symbol) const
{
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
return (digits == 3 || digits == 5) ? SymbolInfoDouble(symbol, SYMBOL_POINT) * 10.0 : SymbolInfoDouble(symbol, SYMBOL_POINT);
}
bool CTradeManager::IsPositionOpen(const string symbol)
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionGetSymbol(i) == symbol)
{
if(PositionGetInteger(POSITION_MAGIC) == magic_number)
return true;
}
}
return false;
}
bool CTradeManager::ExecuteBuy(const string symbol, const double entry_price, const double sl, const double tp, const string comment)
{
if(IsPositionOpen(symbol))
return false;
double current_ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
double current_bid = SymbolInfoDouble(symbol, SYMBOL_BID);
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double current_spread_points = (current_ask - current_bid) / point;
if(max_spread_pts > 0 && current_spread_points > max_spread_pts)
{
PrintFormat(">>> [TRADE SPREAD BLOCK] Execution rejected on %s. Current Spread: %.1f pts | Max Allowed: %.1f pts", symbol, current_spread_points, max_spread_pts);
return false;
}
double volume_min = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
double volume_step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
double normalized_lot = MathMax(MathFloor(fixed_lot / volume_step) * volume_step, volume_min);
double required_margin = 0.0;
if(OrderCalcMargin(ORDER_TYPE_BUY, symbol, normalized_lot, current_ask, required_margin))
{
if(AccountInfoDouble(ACCOUNT_MARGIN_FREE) < required_margin)
{
PrintFormat(">>> [VALIDATION SAFETY GATE] Buy Order blocked programmatically. Required Margin: %.2f | Free Margin: %.2f", required_margin, AccountInfoDouble(ACCOUNT_MARGIN_FREE));
return false;
}
}
long broker_stops = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
if(broker_stops <= 0)
broker_stops = (long)MathMax(current_spread_points * 1.5, 10);
double stops_level_price = (broker_stops + 2) * point;
double final_sl = sl;
double final_tp = tp;
if(final_sl > 0 && (current_ask - final_sl) < stops_level_price)
{
final_sl = current_ask - stops_level_price;
}
if(final_tp > 0 && (final_tp - current_ask) < stops_level_price)
{
final_tp = current_ask + stops_level_price;
}
final_sl = NormalizeDouble(final_sl, digits);
final_tp = NormalizeDouble(final_tp, digits);
if(trade.Buy(normalized_lot, symbol, current_ask, final_sl, final_tp, comment))
{
if(trade.ResultRetcode() == TRADE_RETCODE_DONE || trade.ResultRetcode() == TRADE_RETCODE_PLACED)
return true;
}
PrintFormat(">>> [TRADE ERROR] Buy execution failed on %s. Retcode: %I64u", symbol, trade.ResultRetcode());
return false;
}
bool CTradeManager::ExecuteSell(const string symbol, const double entry_price, const double sl, const double tp, const string comment)
{
if(IsPositionOpen(symbol))
return false;
double curreПоказано первые 50% кода (символов: 7457)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.