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);
}