FiboTrader Scaner
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «fibotrader scaner mt4.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
FiboTrader Scaner — советник для MetaTrader 4, предназначенный для автоматического сканирования инструментов из списка наблюдения и поиска торговых сигналов на основе анализа фибоначчи-импульсов и ценовых уровней. Советник отслеживает динамику цены относительно ключевых уровней и формирует сигналы на покупку или продажу при достижении заданных условий входа.
В качестве дополнительного фильтра используется комбинация скользящей средней и параболического SAR, настройка которых доступна пользователю. Советник поддерживает различные режимы торговли: только лонги, только шорты или оба направления одновременно.
Система уведомлений включает отправку Push-уведомлений, email-алертов и сводку за конец торгового дня. Вся информация о текущих сигналах отображается на графике в виде таблицы с возможностью открытия графика соответствующего инструмента по клику.
Советник содержит встроенную систему проверки лицензии с шифрованием и ограниченным пробным режимом. Данные о сигналах сохраняются в файл и обновляются в течение торгового дня.
Настройки программы
| Настройка | Описание |
|---|---|
| Debug mode (Debug) | Отладка — Включает или отключает режим отладки. |
| TradeMode | Режим торговли — Режим торговли: только лонги, только шорты или оба направления. |
| Default template for signal charts (DefaultTemplate) | Шаблон по умолчанию — Имя шаблона графика, применяемого при открытии нового графика по сигналу. |
| Push alert (AlertPush) | Push-алерт — Включает или отключает отправку Push-уведомлений о торговых сигналах. |
| Mail alert (AlertMail) | Email-алерт — Включает или отключает отправку email-уведомлений о торговых сигналах. |
| Alert in end day (AlertEndDay) | Алерты в конце дня — Включает или отключает отправку сводки о сигналах в конце торгового дня. |
| TimeAlert | Время алерта — Время в формате ЧЧ:ММ, до которого отправляется сводка о сигналах за день. |
| tf (tf) | Таймфрейм анализа — Таймфрейм для основного анализа ценовых данных. |
| Flat Minimal Bars (FlatMinimalBars) | Минимальные бары для флэта — Минимальное количество баров для коррекции при анализе импульса. |
| Open Level1 (OpenLevel1) | Уровень входа 1 — Процент от размера импульса, на котором происходит вход в позицию. |
| Filter mode (Filter) | Режим фильтра — Режим фильтрации сигналов. Доступны варианты: отключён фильтр или фильтр на основе MA+SAR. |
| Filter tf (FilterTF) | Таймфрейм фильтра — Таймфрейм, на котором рассчитывается фильтрующий индикатор. |
Поиск по коду файла
#property version "1.15"
#property strict
/*
1.14
- исправление загрузки и расчета фильтров
- отображение статуса поиска сигнала
- исправление отправки сигналов
- исправление лагов из-за анализа
*/
#define LICENSE_OFF
#define LICENSE_DEMO
#define TRIAL_DAYS 30
#define LICENSE_NAME "$zq2fl{t}{n~~~@mf5j#y|~b@aanx66x"
#define LICENSE_FILE "ftl"
#define VALID_KEY "Expert active. "
#define EMPTY_KEY "You must activate the adviser."
#define INVALID_KEY "Invalid license."
#define EXPERIED "License expired."
#define NOTESTER "No testing."
bool bcheck=false;
#define LINE_HEIGTH 16
#define LINE_WIDTH 400
#define TABLE_X1 100
#define TABLE_X2 250
#define START_Y 35
#define POINTS_NEW
#include <sovetnikovNET\Orders.mqh>
#include <sovetnikovNET\Time.mqh>
#include <sovetnikovNET\Draw.mqh>
#include <sovetnikovNET\Bcrypt.mqh>
enum enum_filter
{
FILTER_OFF, //Off
FILTER_MASAR, //MA+SAR
};
B Debug=true; //Debug mode
input ENUM_TRADEMODE TradeMode=TRADEMODE_LONG;
S DefaultTemplate="FiboTrader Scaner.tpl"; //Default template for signal charts
B AlertPush=false; //Push alert
B AlertMail=false; //Mail alert
B AlertEndDay=true; //Alert in end day
S TimeAlert="23:00";
TF tf=PERIOD_D1; //tf
bool ManualFirstFibo=false; //Manual first fibo
bool NewFibo=true; //Draw new fibo
I FlatMinimalBars=1; //Flat Minimal Bars
double ReverseSensitivity=5; //Reverse signal sensitivity %
double ImpulseSizeMin=0; //Impulse minimal at points (0 - off)
double ImpulseSizeMax=0; //Impulse maximum at points (0 - off)
D OpenLevel1=38.2; //Open Level1
double SL_Level=100; //SL Level %
double CloseSensitivity=30; //Close signal sensitivity %
input enum_filter Filter=FILTER_MASAR; //Filter mode
TF FilterTF=PERIOD_D1; //Filter tf
int MA_Fast=20;
int MA_Slow=200;
double SAR_Step=0.002;
double SAR_Maximum=0.02;
C Long_Color=clrGreen; //Long color
C Short_Color=clrRed; //Short color
C Long_Text_Color=clrWhite; //Long text color
C Short_Text_Color=clrWhite;//Short text color
C Table_Lines_Color=clrBlack; //Table lines color
CGlobal m_global;
class CDataSignals
{
public:
bool bfile;
datetime timeSignal; //время сигнала
string smb; //символ
int direct; //направление бай 1, -1 селл, 0 -нет
datetime time100;
datetime time0;
double price100;
double price0;
double priceOpen;
bool balert; //был отправлен алерт
};
class CAlertsSignals
{
public:
CTime m_time;
CDataSignals data[];
bool m_day_alerts;
int hfile;
ENUM_TIMEFRAMES m_tf;
string m_FileName;
CCanvas m_canvas;
string TypeToDir(int itype)
{
if(itype>0)
return "LONG";
if(itype<0)
return "SHORT";
return "INVALID";
}
void Reset(bool bNewDay)
{
if(bNewDay)
m_day_alerts=false;
}
void SendSignals(bool bSend,bool bAlertDay,string stime,bool bTelegram,bool bMail,bool bPush)
{
datetime tmDay=iTime(_Symbol,PERIOD_D1,0); //грузим текущий день
string ssignal=StringFormat("Signals %s\n",TimeToString(tmDay,TIME_DATE));
string stema=ssignal;
int isize=ArraySize(data);
int icount=0;
bool btime=m_time.IsEndTime(TimeAlert);
bool bDayDebug=false;
if(bDayDebug)
btime=true;
if(bSend)
{
for(int i=0; i<isize; i++)
{
if(data[i].timeSignal>=tmDay && (!data[i].balert || (bAlertDay && btime && !m_day_alerts)))
{
int idgt=(int)SymbolInfoInteger(data[i].smb,SYMBOL_DIGITS);
MqlTick tick;
SymbolInfoTick(data[i].smb,tick);
double drisk=0,dopen=0,ddelta=0;
bool bShow=true;
if(data[i].direct>0)
{
drisk=ND2(MathAbs(tick.ask-data[i].price100)*100/tick.ask);
dopen=tick.ask;
ddelta=data[i].priceOpen-tick.ask;
if(ddelta<0)
bShow=false;
}
if(data[i].direct<0)
{
drisk=ND2(MathAbs(data[i].price100-tick.bid)*100/tick.bid);
dopen=tick.bid;
ddelta=tick.bid-data[i].priceOpen;
if(ddelta<0)
bShow=false;
}
if(bShow)
{
ssignal=StringFormat("%s%s %s OPEN(%s): %s SL: %s (%.2f%%)\n",
ssignal,data[i].smb,TypeToDir(data[i].direct),DoubleToString(data[i].priceOpen,idgt),DoubleToString(dopen,idgt),
DoubleToString(data[i].price100,idgt),drisk);
DEBUG("%s %s OPEN(%s): %s SL: %s (%.2f%%)",
data[i].smb,TypeToDir(data[i].direct),DoubleToString(data[i].priceOpen,idgt),DoubleToString(dopen,idgt),
DoubleToString(data[i].price100,idgt),drisk);
}
data[i].balert=true;
icount++;
}
}
if(icount>0)
{
if(bMail)
{
SendMail(stema,ssignal);
}
if(bPush)
SendNotification(ssignal);
if(btime)
{
m_day_alerts=true; //поставим флаг что в этот день уже отправляли суммарные данные
}
Save();
}
}
int x_size=ChartWidth();
int y_size=ChartHeight();
m_canvas.Resize(x_size,y_size);
tmDay=iTime(_Symbol,PERIOD_D1,1); //грузим за текущий и вчерашний
ssignal=StringFormat("Signals %s\n",TimeToString(tmDay,TIME_DATE));
int j=0;
for(int i=0; i<isize; i++)
{
if(data[i].timeSignal>=tmDay)
{
int idgt=(int)SymbolInfoInteger(data[i].smb,SYMBOL_DIGITS);
MqlTick tick;
SymbolInfoTick(data[i].smb,tick);
double drisk=0,dopen=0,ddelta=0;
bool bShow=true;
if(data[i].direct>0 && tick.ask>0)
{
drisk=ND2(MathAbs(tick.ask-data[i].price100)*100/tick.ask);
dopen=tick.ask;
ddelta=data[i].priceOpen-tick.ask;
if(ddelta<0)
bShow=false;
}
if(data[i].direct<0 && tick.bid>0)
{
drisk=ND2(MathAbs(data[i].price100-tick.bid)*100/tick.bid);
dopen=tick.bid;
ddelta=tick.bid-data[i].priceOpen;
if(ddelta<0)
bShow=false;
}
if(bShow)
{
ssignal=StringFormat("%s LEVEL(%s): %s SL: %s (%.2f%%)",
data[i].smb,DoubleToString(data[i].priceOpen,idgt),DoubleToString(dopen,idgt),
DoubleToString(data[i].price100,idgt),drisk);
int x=5,y=START_Y+(LINE_HEIGTH+1)*j;
m_canvas.FillRectangle(x,y,x+LINE_WIDTH,y+LINE_HEIGTH,ColorToARGB(data[i].direct>0?Long_Color:Short_Color));
m_canvas.Line(x,y+LINE_HEIGTH,x+LINE_WIDTH,y+LINE_HEIGTH,ColorToARGB(Table_Lines_Color));
m_canvas.TextOut(x+5,y+2,data[i].smb,ColorToARGB(data[i].direct>0?Long_Text_Color:Short_Text_Color),TA_LEFT|TA_TOP);
m_canvas.Line(x+TABLE_X1-5,y+1,x+TABLE_X1-5,y+LINE_HEIGTH-1,ColorToARGB(Table_Lines_Color));
m_canvas.TextOut(x+TABLE_X1,y+2,StringFormat("LEVEL(%s): %s",DoubleToString(data[i].priceOpen,idgt),DoubleToString(dopen,idgt)),ColorToARGB(data[i].direct>0?Long_Text_Color:Short_Text_Color),TA_LEFT|TA_TOP);
m_canvas.Line(x+TABLE_X2-5,y+1,x+TABLE_X2-5,y+LINE_HEIGTH-1,ColorToARGB(Table_Lines_Color));
m_canvas.TextOut(x+TABLE_X2,y+2,StringFormat("SL: %s (%.2f%%)",DoubleToString(data[i].price100,idgt),drisk),ColorToARGB(data[i].direct>0?Long_Text_Color:Short_Text_Color),TA_LEFT|TA_TOP);
j++;
}
}
}
m_canvas.Update();
}
int getIndex(int iindex)
{
datetime tmDay=iTime(_Symbol,PERIOD_D1,0); //грузим текущий день
int isize=ArraySize(data);
int j=0;
for(int i=0; i<isize; i++)
{
if(data[i].timeSignal>=tmDay)
{
int idgt=(int)SymbolInfoInteger(data[i].smb,SYMBOL_DIGITS);
MqlTick tick;
SymbolInfoTick(data[i].smb,tick);
double drisk=0,dopen=0,ddelta=0;
bool bShow=true;
if(data[i].direct>0 && tick.ask>0)
{
drisk=ND2(MathAbs(tick.ask-data[i].price100)*100/tick.ask);
dopen=tick.ask;
ddelta=data[i].priceOpen-tick.ask;
if(ddelta<0)
bShow=false;
}
if(data[i].direct<0 && tick.bid>0)
{
drisk=ND2(MathAbs(data[i].price100-tick.bid)*100/tick.bid);
dopen=tick.bid;
ddelta=tick.bid-data[i].priceOpen;
if(ddelta<0)
bShow=false;
}
if(bShow)
{
if(iindex==j)
return i;
j++;
}
}
}
return -1;
}
bool Find(string smb,datetime &time100,datetime &time0,double &price100,double &price0)
{
int isize=ArraySize(data);
for(int i=isize-1; i>=0; i--)
{
if(smb==data[i].smb)
{
time100=data[i].time100;
time0=data[i].time0;
price100=data[i].price100;
price0=data[i].price0;
return true;
}
}
return false;
}
void AddSignal(bool bfile,string smb,datetime time100,datetime time0,double price100,double price0,double priceOpen,bool bAlert)
{
int isize=ArraySize(data);
bool bfind=false;
for(int i=0; i<isize; i++)
{
if(data[i].price100==price100 && data[i].time100==time100 && smb==data[i].smb)
{
bfind=true;
}
if(smb==data[i].smb)
{
data[i].bfile=bfile;
data[i].timeSignal=iTime(smb,m_tf,0);
data[i].smb=smb;
data[i].direct=0;
if(price0>price100)
data[i].direct=1;
if(price0<price100)
data[i].direct=-1;
data[i].time100=time100;
data[i].time0=time0;
data[i].price100=price100;
data[i].price0=price0;
data[i].priceOpen=priceOpen;
bfind=true;
}
if(bfind)
break;
}
if(!bfind)
{
if(ArrayResize(data,isize+1)!=-1)
{
int i=isize;
data[i].bfile=bfile;
data[i].timeSignal=iTime(smb,m_tf,0);
data[i].smb=smb;
data[i].direct=0;
if(price0>price100)
data[i].direct=1;
if(price0<price100)
data[i].direct=-1;
data[i].time100=time100;
data[i].time0=time0;
data[i].price100=price100;
data[i].price0=price0;
data[i].priceOpen=priceOpen;
data[i].balert=bAlert;
}
}
}
int Load()
{
if(hfile==INVALID_HANDLE)
return 0;
datetime tmDay=iTime(_Symbol,PERIOD_D1,1); //грузим 2 дня прошлый и текущий
ArrayResize(data,0);
int i=0;
string sline="";
FileSeek(hfile,0,SEEK_SET);//ставим на начало файла
while(!IsStopped() && !FileIsEnding(hfile))
{
sline=FileReadString(hfile);
string sret[];
int iread=string_explode(";",sline,sret);
if(iread==9)
{
datetime timeSignal=StringToTime(sret[0]);
if(timeSignal>=tmDay)
{
string smb=sret[1];
int direct=(int)StringToInteger(sret[2]);
datetime time100=StringToTime(sret[3]);
datetime time0=StringToTime(sret[4]);
double price100=StringToDouble(sret[5]);
double price0=StringToDouble(sret[6]);
double priceOpen=StringToDouble(sret[7]);
bool bAlert=(bool)StringToInteger(sret[8]);
AddSignal(true,smb,time100,time0,price100,price0,priceOpen,bAlert);//сохраняем в памяти данныые
}
}
}
return ArraySize(data);
}
void Save()
{
if(hfile==INVALID_HANDLE)
{
this.OnInit(m_tf,m_FileName);
if(hfile==INVALID_HANDLE)
{
Print("Invalid file");
return;
}
}
string sline="";
FileSeek(hfile,0,SEEK_END);//ставим на начало файла и переписываем файл
ulong itell=FileTell(hfile);
int isize=ArraySize(data);
int i=0;
datetime tmDay=iTime(_Symbol,PERIOD_D1,1);
while(!IsStopped() && i<isize)
{
/*
datetime timeSignal; //время сигнала
string smb; //символ
int direct; //направление бай 1, -1 селл, 0 -нет
datetime time100;
datetime time0;
double price100;
double price0;
double priceOpen;
};
*/
if(data[i].timeSignal>0)
{
int idgt=(int)SymbolInfoInteger(data[i].smb,SYMBOL_DIGITS);
sline=StringFormat("%s;%s;%d;%s;%s;%s;%s;%s;%d\r\n",
TimeToString(data[i].timeSignal),
data[i].smb,
data[i].direct,
TimeToString(data[i].time100),
TimeToString(data[i].time0),
DoubleToString(data[i].price100,idgt),
DoubleToString(data[i].price0,idgt),
DoubleToString(data[i].priceOpen,idgt),
data[i].balert
);
itell=FileTell(hfile);
FileSeek(hfile,0,SEEK_SET); //вернем положение в начало
bool bfind=false;
while(!IsStopped() && !FileIsEnding(hfile))
{
ulong ilastread=FileTell(hfile);
string sline_check=FileReadString(hfile);
string sret[];
int iread=string_explode(";",sline_check,sret);
if(iread==9)
{
datetime timeSignal=StringToTime(sret[0]);
string smb=sret[1];
int direct=(int)StringToInteger(sret[2]);
datetime time100=StringToTime(sret[3]);
datetime time0=StringToTime(sret[4]);
double price100=StringToDouble(sret[5]);
double price0=StringToDouble(sret[6]);
double priceOpen=StringToDouble(sret[7]);
if(data[i].timeSignal>=tmDay && smb==data[i].smb && direct==data[i].direct && time100==data[i].time100
&& price100==data[i].price100)
{
FileSeek(hfile,ilastread,SEEK_SET); //вернем положение в начало этой строчки и перепишем ее
FileWriteString(hfile,sline); //обновляем строчку
bfind=true;
}
}
if(bfind)
break;
}
FileSeek(hfile,itell,SEEK_SET); //вернем положение в последнюю точку
if(!bfind)
{
if(data[i].bfile==false)
{
if(FileWriteString(hfile,sline)>0) //сохраняем строчку
data[i].bfile=true; //сохранили в файл
}
}
else
{
data[i].bfile=true; //сохранили в файл
}
}
i++;
}
}
bool OnInit(ENUM_TIMEFRAMES etf,string sFileName)
{
// код доступен только после оплаты
}
void OnDeinit()
{
if(hfile!=INVALID_HANDLE)
{
FileClose(hfile);
}
m_canvas.Destroy();
ObjectDelete(ChartID(),"symbol"); //патч для мт4
ArrayFree(data);
}
};
class CFiboSignal
{
public:
string m_name;
double ma_fast;
double ma_slow;
double sar;
int iFlatMinimalBars;
double dLevel0,dLevel100;
datetime tmTime0,tmTime100;
int hma_fast,hma_slow,hsar;
bool IsWork(string sSymbol=NULL)
{
if(sSymbol==NULL)
sSymbol=m_name;
if(IsTesting() || IsOptimization())
return true;
if(TerminalInfoInteger(TERMINAL_CONNECTED)==false)
return false; //дисконнект
return true;
}
virtual void Reset()
{
dLevel0=0;
dLevel100=0;
tmTime0=0;
tmTime100=0;
}
virtual bool OnInit(string m_smb)
{
// код доступен только после оплаты
}
virtual bool OnDeinit()
{
#ifdef __MQL5__
IndicatorRelease(hsar);
IndicatorRelease(hma_fast);
IndicatorRelease(hma_slow);
#endif
return true;
}
int filterMASAR(ENUM_TIMEFRAMES etf,int ibar=0)
{
ma_fast=0;
ma_slow=0;
sar=0;
#ifdef __MQL5__
double buf1[],buf2[],buf3[];
if(BarsCalculated(hma_fast)>0 && BarsCalculated(hma_slow)>0 && BarsCalculated(hsar)>0)
{
if(CopyBuffer(hma_fast,0,ibar,1,buf1)==1)
ma_fast=buf1[0];
if(CopyBuffer(hma_slow,0,ibar,1,buf2)==1)
ma_slow=buf2[0];
if(CopyBuffer(hsar,0,ibar,1,buf3)==1)
sar=buf3[0];
}
#else
ma_fast=iMA(m_name,etf,MA_Fast,0,MODE_EMA,PRICE_CLOSE,ibar);
ma_slow=iMA(m_name,etf,MA_Slow,0,MODE_EMA,PRICE_CLOSE,ibar);
sar=iSAR(m_name,etf,SAR_Step,SAR_Maximum,ibar);
#endif
if(sar>0 && ma_fast>0 && ma_slow>0)
{
if(ma_fast>0 && ma_fast>ma_slow && sar<ma_fast && iClose(m_name,etf,1)>ma_fast && iClose(m_name,etf,1)>ma_slow)
return OP_BUY;
if(ma_fast>0 && ma_fast<ma_slow && sar>ma_fast && iClose(m_name,etf,1)<ma_fast && iClose(m_name,etf,1)<ma_slow)
return OP_SELL;
}
return -1;
}
void FindImpulse(string name,bool bFilter,ENUM_TIMEFRAMES etf,datetime &time0,double &level0,datetime &time100,double &level100)
{
if(level0<=0 || level100<=0)
{
return;
}
int icount=0;
int ibar0=-1,ibar100=-1;
double dhigh=0,dlow=0,dopen=0,dclose=0;
ibar0=iBarShift(m_name,etf,time0); //определим сколько баров от 0 точки
ibar100=iBarShift(m_name,etf,time100); //определим сколько баров от 100 точки
int imaxSize=(int)MathMin(ibar0,ibar100);
MqlRates rates[];
bool bUpdate=false;
if(CopyRates(m_name,etf,0,imaxSize+1,rates)==imaxSize+1) //загрузим данные
{
ArraySetAsSeries(rates,true);
for(int i=imaxSize; i>=0; i--)
{
dhigh=rates[i].high;//iHigh(m_name,etf,i);
dlow=rates[i].low;//iLow(m_name,etf,i);
dclose=rates[i].close;//iClose(m_name,etf,i);
dopen=rates[i].open; //iOpen(m_name,etf,i);
ibar0=iBarShift(m_name,etf,time0); //определим сколько баров от 0 точки
ibar100=iBarShift(m_name,etf,time100); //определим сколько баров от 100 точки
datetime tmDebug=iTime(m_name,tf,i);
if(level0>level100)
{
if((dclose<dopen || icount>0) && i>0)
{
icount++; //нужна хотя бы одна коррекционная свечка, с нее включаем анализ коррекций, но не от этйо свечки. от тайм0
}
if(dhigh>=level0 && level0>0)
{
level0=dhigh;
time0=rates[i].time;
int ibarsHigh=ibar0-i;
int ibarsLow=ibar0-i;
if(ibarsHigh>=0)
{
if(icount>0 && icount>iFlatMinimalBars)
{
int ihigh=iHighest(m_name,etf,MODE_HIGH,ibarsHigh+1,i); //ищем реальный максимум от точки 0
int ilow=iLowest(m_name,etf,MODE_LOW,ibarsLow+1,i);
if(ihigh!=-1)
{
time0=iTime(m_name,etf,ihigh); //верхняя точка
level0=iHigh(m_name,etf,ihigh);
Показано первые 50% кода (символов: 26809)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.