Follow along with the video below to see how to install our site as a web app on your home screen.
Примечание: This feature may not be available in some browsers.
код индиуатора в тексте скинь сюда я передам кому следует, и тз, в каком случае надо что бы?
мт5 нету по этому такие условия
Просто надо чтобы он выдавал алерт при пересечении индикатором линии перекупленности и перепроданности.код индиуатора в тексте скинь сюда я передам кому следует, и тз, в каком случае надо что бы?
мт5 нету по этому такие условия
А возможно его сделать как выше я выложил вместе с кодом? Я совершенный профан в Ваших программных делах и не знаю как этот Ваш индикатор втиснуть в терминал.Пробуй, должно работать
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2026, MetaQuotes Ltd."
#property link "Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5"
#property description "Larry Williams' Percent Range with Alerts"
//--- indicator settings
#property indicator_separate_window
#property indicator_level1 -20.0
#property indicator_level2 -80.0
#property indicator_levelstyle STYLE_DOT
#property indicator_levelcolor clrSilver
#property indicator_levelwidth 1
#property indicator_maximum 0.0
#property indicator_minimum -100.0
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
//--- input parameters
input int InpWPRPeriod=14; // Period
input bool InpAlertEnabled=true; // Enable Alerts
input bool InpAlertPopup=true; // Show Popup Alert
input bool InpAlertSound=true; // Play Sound Alert
input string InpAlertSoundFile="alert.wav"; // Sound File Name
input bool InpAlertEmail=false; // Send Email Alert
input bool InpAlertPush=false; // Send Push Notification
//--- indicator buffers
double ExtWPRBuffer[];
//--- global variables
int ExtPeriodWPR;
double prevWPRValue; // Для отслеживания предыдущего значения
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- check for input value
if(InpWPRPeriod<3)
{
ExtPeriodWPR=14;
Print("Incorrect InpWPRPeriod value. Indicator will use value=",ExtPeriodWPR);
}
else
ExtPeriodWPR=InpWPRPeriod;
//--- indicator's buffer
SetIndexBuffer(0,ExtWPRBuffer,INDICATOR_DATA);
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodWPR-1);
//--- name for DataWindow and indicator subwindow label
IndicatorSetString(INDICATOR_SHORTNAME,"%R"+"("+string(ExtPeriodWPR)+")");
//--- digits
IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- initialize previous value
prevWPRValue=EMPTY_VALUE;
}
//+------------------------------------------------------------------+
//| Williams' Percent Range |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total<ExtPeriodWPR)
return(0);
//--- start working
int i,pos=prev_calculated-1;
if(pos<ExtPeriodWPR-1)
{
pos=ExtPeriodWPR-1;
for(i=0; i<pos; i++)
ExtWPRBuffer=0.0;
}
//--- main cycle
for(i=pos; i<rates_total && !IsStopped(); i++)
{
double max_high=Highest(high,ExtPeriodWPR,i);
double min_low =Lowest(low,ExtPeriodWPR,i);
//--- calculate WPR
if(max_high!=min_low)
ExtWPRBuffer=-(max_high-close)*100/(max_high-min_low);
else
ExtWPRBuffer=(i>0) ? ExtWPRBuffer[i-1] : -50.0;
}
//--- Check for alerts (only on the last completed bar)
if(InpAlertEnabled && rates_total>1)
{
int lastBar=rates_total-2; // Предпоследний бар - последний завершённый
if(prev_calculated<=rates_total-1 && lastBar>=ExtPeriodWPR-1)
{
double currentWPR=ExtWPRBuffer[lastBar];
double previousWPR=(lastBar>0) ? ExtWPRBuffer[lastBar-1] : currentWPR;
// Проверка пересечений
CheckCrossings(previousWPR, currentWPR, time[lastBar]);
}
}
//--- return new prev_calculated value
return(rates_total);
}
//+------------------------------------------------------------------+
//| Проверка пересечений уровней и генерация алертов |
//+------------------------------------------------------------------+
void CheckCrossings(double prevValue, double currentValue, datetime barTime)
{
const double OVERBOUGHT=-20.0;
const double OVERSOLD=-80.0;
// --- Пересечение уровня перекупленности (-20) ---
// Пересечение СНИЗУ ВВЕРХ (выход из перекупленности)
if(prevValue<=OVERBOUGHT && currentValue>OVERBOUGHT)
{
SendAlert("%R crossed ABOVE -20 (exit overbought) at "+TimeToString(barTime));
}
// Пересечение СВЕРХУ ВНИЗ (вход в перекупленность)
if(prevValue>OVERBOUGHT && currentValue<=OVERBOUGHT)
{
SendAlert("%R crossed BELOW -20 (enter overbought) at "+TimeToString(barTime));
}
// --- Пересечение уровня перепроданности (-80) ---
// Пересечение СНИЗУ ВВЕРХ (выход из перепроданности) - бычий сигнал
if(prevValue<=OVERSOLD && currentValue>OVERSOLD)
{
SendAlert("%R crossed ABOVE -80 (exit oversold) at "+TimeToString(barTime));
}
// Пересечение СВЕРХУ ВНИЗ (вход в перепроданность)
if(prevValue>OVERSOLD && currentValue<=OVERSOLD)
{
SendAlert("%R crossed BELOW -80 (enter oversold) at "+TimeToString(barTime));
}
}
//+------------------------------------------------------------------+
//| Отправка алерта |
//+------------------------------------------------------------------+
void SendAlert(string message)
{
string symbol=Symbol();
string timeframe=PeriodToString();
string fullMessage=symbol+" "+timeframe+": "+message;
if(InpAlertPopup)
Alert(fullMessage);
if(InpAlertSound)
PlaySound(InpAlertSoundFile);
if(InpAlertEmail)
SendMail(symbol+" %R Alert", message);
if(InpAlertPush)
SendNotification(fullMessage);
}
//+------------------------------------------------------------------+
//| Преобразование периода в строку |
//+------------------------------------------------------------------+
string PeriodToString()
{
switch(Period())
{
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("D1");
case PERIOD_W1: return("W1");
case PERIOD_MN1: return("MN1");
default: return("");
}
}
//+------------------------------------------------------------------+
//| Maximum High |
//+------------------------------------------------------------------+
double Highest(const double &array[],int period,int cur_position)
{
double res=array[cur_position];
for(int i=cur_position-1; i>cur_position-period && i>=0; i--)
if(res<array)
res=array;
return(res);
}
//+------------------------------------------------------------------+
//| Minimum Low |
//+------------------------------------------------------------------+
double Lowest(const double &array[],int period,int cur_position)
{
double res=array[cur_position];
for(int i=cur_position-1; i>cur_position-period && i>=0; i--)
if(res>array)
res=array;
return(res);
}
//+------------------------------------------------------------------+
А возможно его сделать как выше я выложил вместе с кодом? Я совершенный профан в Ваших программных делах и не знаю как этот Ваш индикатор втиснуть в терминал.![]()
![]()
![]()
Завтра и в понедельник я его протестирую и тогда определюсь. А пока, по-моему, если он будет просто "пиликать"Вам нужно написать подробное ТЗ что вы хотите, алерт по первому пересечению или по каждому пересечению, по закрытой свече или в любом моменте по факту пересечения, пересечение может быть сверху вниз и снизу вверх все нужно указать. Тогда у алертов будет логика, а не просто так пиликать через каждые пять минут.