Quantora Trailing Stop Manager MT4
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «quantora_trailing_stop_manager.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Quantora Trailing Stop Manager MT4 — советник для MetaTrader 4, предназначенный для автоматического управления стоп-лоссами ручных торговых позиций. Программа отслеживает открытые рыночные ордера и модифицирует уровни стоп-лосса в соответствии с заданными параметрами трейлинга. Работает в режиме реального времени, реагируя на тики и таймерные события.
Советник поддерживает фильтрацию ордеров по символу, Magic Number и направлению сделки, что позволяет управлять конкретными позициями или всеми открытыми сделками на текущем счёте. Предусмотрена возможность принудительного применения трейлинга по запросу через панель управления.
Интерфейс включает информационную панель с отображением текущего состояния, баланса, маржи, количества управляемых сделок и плавающей прибыли. Панель интерактивна: позволяет включать и отключать менеджер, а также запускать однократную проверку трейлинга. Логирование событий настраивается отдельным параметром.
Настройки программы
| Настройка | Описание |
|---|---|
| InpScopeHeader | Заголовок области торговли — Текстовый заголовок раздела, определяющего область действия советника по символам. |
| InpScope | Область торговли — Определяет, на каком символе работает советник: только на текущем или на всех доступных. |
| InpMagicFilter | Фильтр Magic Number — Выбор режима фильтрации ордеров по Magic Number: только ручные, все или с конкретным значением. |
| InpSpecificMagic | Конкретный Magic Number — Значение Magic Number для фильтрации ордеров, когда режим фильтра установлен на конкретный номер. |
| InpManageBuyTrades | Управлять покупками — Включает или отключает обработку ордеров на покупку (OP_BUY). |
| InpManageSellTrades | Управлять продажами — Включает или отключает обработку ордеров на продажу (OP_SELL). |
| InpTrailingHeader | Заголовок трейлинга — Текстовый заголовок раздела параметров трейл-стопа. |
| InpTrailingStartPoints | Старт трейлинга в пунктах — Количество пунктов прибыли, после которого трейлинг начинает активироваться. |
| InpTrailingDistancePoints | Расстояние трейла в пунктах — Отступ стоп-лосса от текущей цены при установке или изменении трейл-стопа. |
| InpTrailingStepPoints | Шаг трейлинга в пунктах — Минимальное смещение стоп-лосса при каждом последующем изменении. |
| InpMinimumProfitPoints | Минимальная прибыль в пунктах — Порог минимальной прибыли, используемый для активации трейлинга. |
| InpExecutionHeader | Заголовок исполнения — Текстовый заголовок раздела параметров исполнения. |
| InpTimerSeconds | Интервал таймера в секундах — Период срабатывания таймера для проверки и обновления трейл-стопов. |
| InpSlippagePoints | Проскальзывание в пунктах — Допустимое отклонение цены при модификации ордеров. |
| InpPrintLogs | Вывод логов — Включает или отключает вывод информационных сообщений в журнал терминала. |
| InpPanelHeader | Заголовок панели — Текстовый заголовок раздела настроек информационной панели. |
| InpShowPanel | Показывать панель — Включает или отключает отображение информационной панели на графике. |
| InpPanelCorner | Угол панели — Угол привязки информационной панели на графике. |
| InpPanelX | Позиция панели X — Горизонтальная координата привязки панели на графике. |
| InpPanelY | Позиция панели Y — Вертикальная координата привязки панели на графике. |
Поиск по коду файла
#property version "1.00"
#property strict
#property description "Professional automatic trailing stop manager for MetaTrader 4."
#property description "Manages manual trades, all trades or a specific Magic Number."
enum ENUM_Q_SCOPE
{
Q_CURRENT_SYMBOL = 0,
Q_ALL_SYMBOLS = 1
};
enum ENUM_Q_MAGIC_FILTER
{
Q_MANUAL_ONLY = 0,
Q_ALL_TRADES = 1,
Q_SPECIFIC_MAGIC = 2
};
input string InpScopeHeader = "========== TRADE SCOPE ==========";
input ENUM_Q_SCOPE InpScope = Q_CURRENT_SYMBOL;
input ENUM_Q_MAGIC_FILTER InpMagicFilter = Q_MANUAL_ONLY;
input int InpSpecificMagic = 0;
input bool InpManageBuyTrades = true;
input bool InpManageSellTrades = true;
input string InpTrailingHeader = "========== TRAILING STOP ==========";
input int InpTrailingStartPoints = 600;
input int InpTrailingDistancePoints = 350;
input int InpTrailingStepPoints = 50;
input int InpMinimumProfitPoints = 600;
input string InpExecutionHeader = "========== EXECUTION ==========";
input int InpTimerSeconds = 1;
input int InpSlippagePoints = 30;
input bool InpPrintLogs = true;
input string InpPanelHeader = "========== DASHBOARD ==========";
input bool InpShowPanel = true;
input ENUM_BASE_CORNER InpPanelCorner = CORNER_LEFT_UPPER;
input int InpPanelX = 15;
input int InpPanelY = 145;
#define Q_BG C'8,23,38'
#define Q_GOLD C'212,175,55'
#define Q_WHITE C'245,245,245'
#define Q_GRAY C'169,176,184'
#define Q_GREEN C'0,200,83'
#define Q_RED C'255,82,82'
#define Q_BUTTON C'18,48,75'
#define Q_BORDER C'62,76,89'
string g_prefix = "QTSM4_";
bool g_manager_enabled = true;
string g_status = "ACTIVE";
int g_update_count = 0;
int g_error_count = 0;
void LogMessage(string message)
{
if(InpPrintLogs)
Print("Quantora Trailing Stop Manager MT4: ",message);
}
double SymbolPoint(string symbol)
{
return MarketInfo(symbol,MODE_POINT);
}
int SymbolDigits(string symbol)
{
return (int)MarketInfo(symbol,MODE_DIGITS);
}
double NormalizePrice(string symbol,double price)
{
return NormalizeDouble(price,SymbolDigits(symbol));
}
double CurrentBid(string symbol)
{
if(symbol==Symbol())
{
RefreshRates();
return Bid;
}
return MarketInfo(symbol,MODE_BID);
}
double CurrentAsk(string symbol)
{
if(symbol==Symbol())
{
RefreshRates();
return Ask;
}
return MarketInfo(symbol,MODE_ASK);
}
bool IsMarketOrder(int type)
{
return (type==OP_BUY || type==OP_SELL);
}
bool MatchesSelectedOrder()
{
int type=OrderType();
if(!IsMarketOrder(type))
return false;
if(InpScope==Q_CURRENT_SYMBOL && OrderSymbol()!=Symbol())
return false;
if(type==OP_BUY && !InpManageBuyTrades)
return false;
if(type==OP_SELL && !InpManageSellTrades)
return false;
int magic=OrderMagicNumber();
if(InpMagicFilter==Q_MANUAL_ONLY && magic!=0)
return false;
if(InpMagicFilter==Q_SPECIFIC_MAGIC && magic!=InpSpecificMagic)
return false;
return true;
}
int CountMatchedTrades()
{
int count=0;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
continue;
if(MatchesSelectedOrder())
count++;
}
return count;
}
double MatchedFloatingProfit()
{
double result=0.0;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
continue;
if(!MatchesSelectedOrder())
continue;
result+=OrderProfit()+OrderSwap()+OrderCommission();
}
return result;
}
string ScopeText()
{
return (InpScope==Q_CURRENT_SYMBOL ? "CURRENT SYMBOL" : "ALL SYMBOLS");
}
string MagicText()
{
if(InpMagicFilter==Q_MANUAL_ONLY)
return "MANUAL ONLY";
if(InpMagicFilter==Q_SPECIFIC_MAGIC)
return "MAGIC "+IntegerToString(InpSpecificMagic);
return "ALL TRADES";
}
string AccountTypeText()
{
return (IsDemo() ? "DEMO" : "REAL");
}
bool IsTradeEnvironmentReady()
{
if(!IsConnected())
{
g_status="NO CONNECTION";
return false;
}
if(!IsTradeAllowed())
{
g_status="TRADING DISABLED";
return false;
}
return true;
}
double MinimumStopDistance(string symbol)
{
double point=SymbolPoint(symbol);
int stop_level=(int)MarketInfo(symbol,MODE_STOPLEVEL);
int freeze_level=(int)MarketInfo(symbol,MODE_FREEZELEVEL);
int minimum=MathMax(stop_level,freeze_level);
return minimum*point;
}
bool IsCandidateValid(string symbol,int type,double candidate)
{
double min_distance=MinimumStopDistance(symbol);
double bid=CurrentBid(symbol);
double ask=CurrentAsk(symbol);
if(bid<=0.0 || ask<=0.0)
return false;
if(type==OP_BUY)
return (candidate < bid-min_distance);
if(type==OP_SELL)
return (candidate > ask+min_distance);
return false;
}
bool ModifySelectedOrder(double new_sl)
{
int ticket=OrderTicket();
string symbol=OrderSymbol();
double normalized_sl=NormalizePrice(symbol,new_sl);
ResetLastError();
bool modified=OrderModify(ticket,
OrderOpenPrice(),
normalized_sl,
OrderTakeProfit(),
0,
clrNONE);
if(!modified)
{
int error=GetLastError();
g_error_count++;
g_status="MODIFY ERROR "+IntegerToString(error);
LogMessage("OrderModify failed. Ticket="+IntegerToString(ticket)+
" Error="+IntegerToString(error));
ResetLastError();
return false;
}
g_update_count++;
g_status="TRAILING UPDATED";
LogMessage("Trailing Stop updated. Ticket="+IntegerToString(ticket)+
" New SL="+DoubleToString(normalized_sl,SymbolDigits(symbol)));
return true;
}
bool ApplyTrailingToSelectedOrder(bool force_now)
{
int type=OrderType();
if(!IsMarketOrder(type))
return false;
string symbol=OrderSymbol();
double point=SymbolPoint(symbol);
if(point<=0.0)
return false;
double open_price=OrderOpenPrice();
double old_sl=OrderStopLoss();
double bid=CurrentBid(symbol);
double ask=CurrentAsk(symbol);
if(bid<=0.0 || ask<=0.0)
return false;
double profit_points=(type==OP_BUY)
? (bid-open_price)/point
: (open_price-ask)/point;
int activation_points=MathMax(InpTrailingStartPoints,InpMinimumProfitPoints);
if(!force_now && profit_points<activation_points)
return false;
if(force_now && profit_points<=0.0)
return false;
double candidate=(type==OP_BUY)
? bid-InpTrailingDistancePoints*point
: ask+InpTrailingDistancePoints*point;
candidate=NormalizePrice(symbol,candidate);
if(!IsCandidateValid(symbol,type,candidate))
return false;
double step=InpTrailingStepPoints*point;
bool improves=false;
if(type==OP_BUY)
{
improves=(old_sl<=0.0 || candidate>old_sl+step);
if(candidate<=open_price && !force_now)
return false;
}
else
{
improves=(old_sl<=0.0 || candidate<old_sl-step);
if(candidate>=open_price && !force_now)
return false;
}
if(!improves)
return false;
return ModifySelectedOrder(candidate);
}
void ManageTrailingStops(bool force_now=false)
{
if(!g_manager_enabled && !force_now)
return;
if(!IsTradeEnvironmentReady())
return;
int matched=0;
int changed=0;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
continue;
if(!MatchesSelectedOrder())
continue;
matched++;
if(ApplyTrailingToSelectedOrder(force_now))
changed++;
}
if(force_now)
{
if(changed>0)
Показано первые 50% кода (символов: 13118)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.