Re: Supertrend indicators for MT4

651
KstSarVik wrote: Mon Feb 09, 2026 9:52 pm Good afternoon. A few days ago, using the indicators iTrend (+histo), WPR (smoothed + Vinini BB), TDI (+new) BT 1.4, I created an indicator with the help of the builder. But I ran into a problem. With the builder, I can use the default indicator settings. Based on that, I set the conditions for when an arrow is drawn. I would like to ask esteemed programmers to review the entry conditions and suggest what can be changed or request to modify the indicator conditions to improve entries so that they do not repaint TDI (+new) BT 1.4. The problem is that at the moment the signal candle forms, the indicator changes its data, and the arrow either disappears or appears. I need it so that it does not disappear. I use it for scalping.
Hello, TDI (+new) BT 1.4 indicator is non repaint, What you are describing is a normal calculation process that closes and does not change after the current candle closes.


Re: Supertrend indicators for MT4

652
Dimkin wrote: Mon Feb 09, 2026 1:41 pm Dear kvak,
I’ve added the indicators to the chart and have been observing them. I noticed that only the existing signals were calculated and plotted immediately, but no new signals appear afterward
Yes, this exit arrows not working perfectly, last arrows repaint, I must look to code, if it is possible correct it., Sorry for problems.
These users thanked the author kvak for the post (total 2):
Dimkin, Akela
Rating: 1.2%

Re: Supertrend indicators for MT4

653
kvak wrote: Tue Feb 10, 2026 10:09 am Hello, TDI (+new) BT 1.4 indicator is non repaint, What you are describing is a normal calculation process that closes and does not change after the current candle closes.
Good afternoon. The thing is, I’m not a programmer))) The indicator I posted is just assembled in the constructor and reacts to the matching conditions from these three indicators: iTrend(+histo), wpr (smoothed+vinini BB), TDI(+new) BT 1.4. In each indicator, I selected the down and up buffers accordingly. And I look for matches of these conditions. But for some reason, as you correctly noted, the arrows don’t always appear correctly. I don’t know how to fix this, which is why I asked for help. Maybe I incorrectly identified the 'up' and 'down' buffers?

Re: Supertrend indicators for MT4

654
KstSarVik wrote: Tue Feb 10, 2026 5:29 pm Good afternoon. The thing is, I’m not a programmer))) The indicator I posted is just assembled in the constructor and reacts to the matching conditions from these three indicators: iTrend(+histo), wpr (smoothed+vinini BB), TDI(+new) BT 1.4. In each indicator, I selected the down and up buffers accordingly. And I look for matches of these conditions. But for some reason, as you correctly noted, the arrows don’t always appear correctly. I don’t know how to fix this, which is why I asked for help. Maybe I incorrectly identified the 'up' and 'down' buffers?
Your indicators comment are not readable for me in my metaeditor....
These users thanked the author kvak for the post:
KstSarVik
Rating: 0.6%

Re: Supertrend indicators for MT4

655
kvak wrote: Wed Feb 11, 2026 10:11 am Your indicators comment are not readable for me in my metaeditor....

Code: Select all

#property copyright "Copyright 2026, @Oops_SergeyKV"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrBlue
#property indicator_color2 clrRed
#property indicator_width1 1
#property indicator_width2 1
//============================================
enum BEAR_BULL_OFF {
             uBull_dBear, //UP-бычья, DOWN-медвежья
             uBear_dBull, //UP-медвежья, DOWN-бычья
             none //ВЫКЛ
             };
enum TYPE_EXP {
             fix_exp, //фиксированная (в минутах)
             to_close //до конца свечи
             };
enum TYPE_INP{
             cur_bar, //на текущей свече
             next_bar //на следующей свече
             };
enum TYPE_MIN_EXP {
             no_trade,         //отмена сделки
             trade_next_close, //экспирация до конца след. свечи
             trade_fix_exp     //экспирация на размер фиксированной
             };
enum ON_OFF {
             on, //ON
             off //OFF
             };
enum TYPE_MAIL { 
             one_time, // один раз при первом появлении сигнала
             all_time  // при каждом появлении сигнала
             };
//============================================
extern string             txt0         = "~~~~~~ Сторонние буферные индикаторы (4 шт.) ~~~~~~"; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int                cnt_main     = 4;  // Кол-во сторонних индикаторов
extern string             name_ind     = "iTrend(+histo),wpr (smoothed+vinini BB),TDI(+new) BT 1.4,TDI(+new) BT 1.4";               // Список имен 4 индикаторов (через запятую)
extern string             bufferUP     = "0,3,7,8";               // Список условий с буферами, для сигнала "ВВЕРХ" (через запятую)
extern string             bufferDN     = "1,4,9,10";               // Список условий с буферами, для сигнала "ВНИЗ" (через запятую)
extern string             main_diap    = "1,1,1,1";              // Список диапазонов влияния сигнала (кол-во баров, через запятую)
extern string             txt01        = "";                  //.
extern BEAR_BULL_OFF      filtr_bar    = 1; // Включение фильтра по цвету свечи
extern string             txt_f        = "";                  //.
extern string             txt28        = "___Статистика___";  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
extern ON_OFF             statistika   = on;                 //Включение подсчета статистики
extern int                cntMinut     = 20;                //Через сколько минут обновлять статистику
extern int                cnt_bars     = 1000;                //Кол-во баров для подсчета сигналов
extern int                expir        = 1;                   //Кол-во баров экспирации
extern string             txt29        = "";                  //.
extern int                ots          = 15;                  //Расстояние стрелок от свечей (в пипсах)
extern ON_OFF             AlertSound   = 1;                 //Включение звукового оповещения
extern int                alert_bar    = 0;                   //Оповещение при сигнале на свече ... (0-текущей)
extern TYPE_MAIL          alert_type   = 1;                   //Оповещение во время формирования свечи ...
extern string             txt30        = "";                  //.
extern ON_OFF             AlertMail    = 1;                 //Включение оповещения на E-mail
extern ON_OFF             AlertNotif   = 1;                 //Включение оповещения на мобильн.терминал
extern TYPE_MAIL          mail_type    = 0;                   //Оповещение во время формирования свечи ...

extern string              txt31        = "";                   //.
extern string              trade_txt    = "--- Торговля через BotBinaryV10.4 ---";//.
extern ON_OFF              on_trade     = on;                           //Отправлять сигналы программе BotBinaryV10.4
extern int                 gmt_hour     = 3;                             //Разница часового пояса терминала относительно gmt_0
extern TYPE_INP            inp_type     = 0;                       //Входить в сделку...
extern double              bet          = 1.00;                          //Размер ставки
extern TYPE_EXP            exp_type     = 0;                       //Тип экспирации
extern int                 size_exp     = 5;                             //Размер фиксированной экспирации (в минутах)
extern int                 min_exp      = 3;                             //Минимально допустимая экспирация (для типа "до конца свечи")
extern TYPE_MIN_EXP        min_exp_type = 0;                      //Если экспирация меньше минимальной ...

double buyBuffer[];
double sellBuffer[];

bool   indicatorsON=true;
int time_cnt = 0;
bool soundBuy = false;
bool soundSell = false;
bool sendMail = true;
datetime send_time = 0;
datetime timeBar_prev = 0;

int cnt_ind,inds;
string result_nameMain[];      // массив для получения строк имен индикаторов
string diap_Main[];            // массив для получения строк диапазонов
string result_UP[];            // массив для получения строк буферов ВВЕРХ
string result_DN[];            // массив для получения строк буферов ВНИЗ

int init()
{
  if(cnt_main>0) 
  {
   ArrayResize(result_nameMain,cnt_main);
   ArrayResize(result_UP,cnt_main);
   ArrayResize(result_DN,cnt_main);
   ArrayResize(diap_Main,cnt_main);
    cnt_ind = StringSplit(name_ind,StringGetCharacter(",",0),result_nameMain);
    if(cnt_ind!=cnt_main) 
        {Alert("Установленное количество используемых сторонних индикаторов не соответствует количеству указанных имен индикаторов");
         indicatorsON=false;
         return (INIT_SUCCEEDED);}
   cnt_ind = StringSplit(bufferUP,StringGetCharacter(",",0),result_UP);
    if(cnt_ind!=cnt_main)
        {Alert("Установленное количество используемых сторонних индикаторов не соответствует количеству указанных буферов \"ВВЕРХ\"");
         indicatorsON=false;
         return (INIT_SUCCEEDED);}
   cnt_ind = StringSplit(bufferDN,StringGetCharacter(",",0),result_DN);
    if(cnt_ind!=cnt_main)
        {Alert("Установленное количество используемых сторонних индикаторов не соответствует количеству указанных буферов \"ВНИЗ\"");
         indicatorsON=false;
         return (INIT_SUCCEEDED);}
   cnt_ind = StringSplit(main_diap,StringGetCharacter(",",0),diap_Main);
    if(cnt_ind!=cnt_main)
        {Alert("Установленное количество используемых сторонних индикаторов не соответствует количеству указанных диапазонов влияния");
         indicatorsON=false;
         return (INIT_SUCCEEDED);}
     for(inds=0; inds<cnt_main; inds++)
         {
          ResetLastError();
          iCustom(NULL, 0, result_nameMain[inds], 0, 0);
          if(GetLastError()==4072) {Alert("Ошибка доступа к стороннему индикатору "+result_nameMain[inds]+". Возможно ошибка в указанном названии либо такой индикатор отсутствует в папке Indicators.");
                                    indicatorsON=false;
                                    return (INIT_SUCCEEDED);}
          }}

// Buffers and style
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 225);
SetIndexBuffer(0, buyBuffer);
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 226);
SetIndexBuffer(1, sellBuffer);
// Data window
IndicatorShortName("!!!KSV 5");

send_time = Time[0]+PeriodSeconds();
MathSrand((int)TimeCurrent());

 return(INIT_SUCCEEDED);
}

int deinit()
{
 Comment("");
 return(0);
}

int start()
{
 if(indicatorsON) Tick();
 return(0);
}

void Tick()
  {
      double gap  = ots*Point;

    int limit;
    int counted_bars = IndicatorCounted();
    if(counted_bars < 0) 
        return;
    if(counted_bars > 0) 
        counted_bars--;
    limit = Bars - counted_bars;

    for(int i = 0; i < limit; i++)
     {   
      

       // Long signal
      if(BuySell_signal("buy",i))
       buyBuffer[i] = Low[i]-gap;
       else
       buyBuffer[i] = EMPTY_VALUE;

        // Short signal
      if(BuySell_signal("sell",i))
       sellBuffer[i] = High[i]+gap;
       else
       sellBuffer[i] = EMPTY_VALUE;
        }

        string  messageBuy  =  StringConcatenate("!!!KSV 5 (", Symbol(), ", ", Period(), ")  -  BUY!!!" ,"-" ,TimeToStr(TimeLocal(),TIME_SECONDS));
        string  messageSell =  StringConcatenate("!!!KSV 5 (", Symbol(), ", ", Period(), ")  -  SELL!!!","-"  ,TimeToStr(TimeLocal(),TIME_SECONDS));
      if (timeBar_prev!=Time[0])
       {
        if(mail_type==0) sendMail = true;
        if(alert_type==0) {soundBuy = true; soundSell = true;}
        }
      timeBar_prev = Time[0];

     if (buyBuffer[alert_bar] == Low[alert_bar]-gap && soundBuy)
         {
           soundBuy = false;
           if(AlertSound==0) Alert(messageBuy);
          if(sendMail)
           {sendMail = false;
            if(AlertNotif==0) SendNotification(messageBuy);
            if(AlertMail==0)  SendMail("!!!KSV 5",messageBuy);}
          }
      if (!soundBuy && (buyBuffer[alert_bar] == EMPTY_VALUE)) {if(alert_type==1) soundBuy = true;  if(mail_type==1) sendMail = true;}
     if (sellBuffer[alert_bar] == High[alert_bar]+gap && soundSell)
         {
           soundSell = false;
           if(AlertSound==0) Alert(messageSell);
          if(sendMail)
           {sendMail = false;
            if(AlertNotif==0) SendNotification(messageSell);
            if(AlertMail==0)  SendMail("!!!KSV 5",messageSell);}
          }
      if (!soundSell && (sellBuffer[alert_bar] == EMPTY_VALUE)) {if(alert_type==1) soundSell = true;  if(mail_type==1) sendMail = true;}

  if(on_trade==0 && TimeCurrent()>=send_time && TimeCurrent()<(Time[0]+PeriodSeconds()))
     {
      if(buyBuffer[(inp_type==cur_bar?0:1)]!=EMPTY_VALUE)
         {
          Send_BinaryBot("CALL");
          send_time = Time[0]+PeriodSeconds();
          }
      if(sellBuffer[(inp_type==cur_bar?0:1)]!=EMPTY_VALUE)
         {
          Send_BinaryBot("PUT");
          send_time = Time[0]+PeriodSeconds();
          }
      }
    if(statistika==0)
     {
      if ((int(TimeCurrent()) - time_cnt) >= (cntMinut*60))
       { cnt_Statist();
         time_cnt = int(TimeCurrent());
         Print("==!!!KSV 5==: Статистика пересчитана ",TimeCurrent()," по времени терминала"); }
       }
}

bool BuySell_signal(string b_s, int i)
 {
     if(b_s=="buy")
       // Long signal
      {if(
         (filtr_bar==2 || ((filtr_bar==1&&Open[i]>Close[i])||(filtr_bar==0&&Open[i]<Close[i])))
&&         (cnt_main==0 || fun_main("up",i))
         )
       return(true);
       else
       return(false);}

     if(b_s=="sell")
        // Short signal
      {if(
         (filtr_bar==2 || ((filtr_bar==1&&Open[i]<Close[i])||(filtr_bar==0&&Open[i]>Close[i])))
&&         (cnt_main==0 || fun_main("dn",i))
         )
       return(true);
       else
       return(false);}
    return(false);
  }

void cnt_Statist()
 { int total_cnt=0, profit_cnt=0, losses_cnt=0;
   double winrate=0;
   string msg;

   for(int s=cnt_bars; s>expir; s--)
     { if(s>=Bars) continue;
       if((buyBuffer[s]!=EMPTY_VALUE && Open[s-1]<Close[s-expir]) ||(sellBuffer[s]!=EMPTY_VALUE && Open[s-1]>Close[s-expir]))  profit_cnt++;
       if((buyBuffer[s]!=EMPTY_VALUE && Open[s-1]>=Close[s-expir])||(sellBuffer[s]!=EMPTY_VALUE && Open[s-1]<=Close[s-expir])) losses_cnt++; }

    total_cnt = profit_cnt+losses_cnt;
   if(total_cnt>0) winrate = ((profit_cnt)*1.0/(total_cnt)*1.0)*100.0;

        msg = "\n---<<< !!!KSV 5 >>>---\n\n" +
        "Статистика за " + IntegerToString(MathMin(Bars,cnt_bars)) + " баров:\n" +
        IntegerToString(profit_cnt) + "+  " + IntegerToString(losses_cnt) + "- \n" +
        "Винрейт " + DoubleToString(winrate,1) + "% \n\n" +
        "Обновлено " + TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES);

   Comment(msg);
   }

bool fun_main (string up_dn, int index)
 {
  double _buff = EMPTY_VALUE;
  int i_diap;
  bool diap_true = false;
  for(inds=0; inds<cnt_main; inds++)
      {
            diap_true = false;
                   for(i_diap=index; i_diap<(index+StrToInteger(diap_Main[inds])); i_diap++)
                   {
                    if(i_diap+1>=Bars) continue;
                    if(signal_buff((up_dn=="up"?result_UP[inds]:result_DN[inds]),inds,i_diap)) {diap_true = true; break;} else continue;
                    }
            if(diap_true) continue; else return(false);
        }
  return(true);
  }

bool signal_buff(string string_find, int index, int _diap)
 {
  string arr_find[];
  ushort _sep;
  int _h=0, find_buff;
  string find_usl;
  double find_target, i_cust;  
    _sep=StringGetCharacter(" ",0); 
    _h=StringSplit(string_find,_sep,arr_find);    
  for(int num=0;num<_h;num++)
  {
   find_buff = StrToInteger(StringSubstr(arr_find[num],0,1));
   if(StringLen(string_find)>1)
      {find_usl = StringSubstr(arr_find[num],1,1);
       switch(StringGetCharacter(arr_find[num],2))
        {case 'o': 
         find_target = Open[_diap]; 
         break;
         case 'c': 
         find_target = Close[_diap]; 
         break;
         case 'h': 
         find_target = High[_diap]; 
         break;
         case 'l': 
         find_target = Low[_diap]; 
         break;
         default: 
         find_target = StrToDouble(StringSubstr(arr_find[num],2)); 
         break; 
         }}
   else 
      {
       find_usl = "-";
       find_target = 0;
       }
   i_cust = Ind_custom(index+1,find_buff,_diap);   
   if(find_usl=="-")
      {
       if(i_cust!=EMPTY_VALUE && i_cust!=0) continue; else return(false);
       }
   else if(find_usl==">")
      {
       if(i_cust>find_target) continue; else return(false);
       }
   else if(find_usl=="<")
      {
       if(i_cust<find_target) continue; else return(false);
       }
   else if(find_usl=="=")
      {
       if(i_cust==find_target) continue; else return(false);
       }
   }   
   return(true);
  }

double Ind_custom (int num_ind, int find_buff, int _diap)
{
 switch(num_ind) 
     { 
      case 1:
        return(iCustom(NULL, 0, result_nameMain[0], find_buff, _diap));
      case 2:
        return(iCustom(NULL, 0, result_nameMain[1], find_buff, _diap));
      case 3:
        return(iCustom(NULL, 0, result_nameMain[2], find_buff, _diap));
      case 4:
        return(iCustom(NULL, 0, result_nameMain[3], find_buff, _diap));
     }
 return(0);
 }

void Send_BinaryBot(string call_put)
{   
     string expiration = (exp_type==fix_exp?("duration="+IntegerToString(size_exp)+"=m"):("endtime="+endtime()+"=s"));
     string symbol = binary_symbol();
     if(expiration=="endtime=0=s") 
        {
         Print("Экспирация меньше минимальной. Сигнал отклонен.");
         return;
         }
     int file_handle = FileOpen(
         "Signal//" + 
         symbol + "=" +         
         call_put + "=" +
         DoubleToStr(bet,2) + "=" +
         expiration + "=" +
         IntegerToString(MathRand()) +
         ".txt", FILE_READ|FILE_WRITE|FILE_TXT|FILE_COMMON);
     if(file_handle != INVALID_HANDLE)
         Print("Сигнал "+call_put+" "+symbol+" для BotBinary сформирован успешно");
         FileClose(file_handle);
}

string endtime()
{
 datetime time_close_bar = Time[0]+PeriodSeconds();
 if((int)(time_close_bar-TimeCurrent())<=(min_exp*60)) 
    {if(min_exp_type==0) return("0");
     else if(min_exp_type==1) return(IntegerToString((int)time_close_bar+PeriodSeconds()-(gmt_hour*3600)));
     else return(IntegerToString((int)TimeCurrent()+(size_exp*60)-(gmt_hour*3600)));}
 return(IntegerToString((int)time_close_bar-(gmt_hour*3600)));
}

string binary_symbol()
{
 string symb = StringSubstr(Symbol(),0,6);
 if(symb=="GoldUSD") return("frxXAUUSD");
 if(symb=="SilverUSD") return("frxXAGUSD");
 if(symb=="OilUSD") return("frxBROUSD");
 if(symb=="PalladiumUSD") return("frxXPDUSD");
 if(symb=="PlatinumUSD") return("frxXPTUSD");
 return("frx"+symb);
}