Files
mql5_indicators_mt5_part4/ThreeCandles_HTF - indicator for MetaTrader 5/threecandles.mq5
T

330 lines
29 KiB
Plaintext

//+------------------------------------------------------------------+
//| ThreeCandles.mq5 |
//| Copyright © 2016, Tor |
//| http://einvestor.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Tor"
#property link "http://einvestor.ru/"
#property description "Индикатор пытается, анализируя свечные графики, искать точки возможного разворота — паттерны"
//---- номер версии индикатора
#property version "1.20"
//---- отрисовка индикатора в основном окне
#property indicator_chart_window
//---- для расчета и отрисовки индикатора использовано пять буферов
#property indicator_buffers 5
//---- использовано всего одно графическое построение
#property indicator_plots 1
//+----------------------------------------------+
//| Параметры отрисовки индикатора |
//+----------------------------------------------+
//---- в качестве индикатора использованы цветные свечи
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrRed,clrLightPink,clrGray,clrPaleTurquoise,clrMediumSeaGreen
//---- отображение метки индикатора
#property indicator_label1 "ThreeCandles Open;High;Low;Close"
//+----------------------------------------------+
//| объявление констант |
//+----------------------------------------------+
#define RESET 0 // Константа для возврата терминалу команды на пересчёт индикатора
//+----------------------------------------------+
//| объявление перечислений |
//+----------------------------------------------+
enum ENUM_APPLIED_VOLUME_ //Тип константы
{
VOLUME_TICK_=0, //VOLUME_TICK
VOLUME_REAL_, //VOLUME_REAL
VOLUME_NONE //Без объёмов
};
//+----------------------------------------------+
//| Входные параметры индикатора |
//+----------------------------------------------+
input int maxBar1=300; //Max Bar #1 size for disable Volume filter, pips
input ENUM_APPLIED_VOLUME_ VolumeType=VOLUME_TICK_; //объём
input uint NumberofBar=1; //Номер бара для подачи сигнала
input bool SoundON=true; //Разрешение алерта
input uint NumberofAlerts=2; //Количество алертов
input bool EMailON=false; //Разрешение почтовой отправки сигнала
input bool PushON=false; //Разрешение отправки сигнала на мобильный
//+----------------------------------------------+
//---- объявление динамических массивов, которые будут в дальнейшем использованы в качестве индикаторных буферов
double ExtOpenBuffer[];
double ExtHighBuffer[];
double ExtLowBuffer[];
double ExtCloseBuffer[];
double ExtColorBuffer[];
//---- Объявление целых переменных начала отсчёта данных
int min_rates_total;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//----
min_rates_total=4;
//---- превращение динамических массивов в индикаторные буферы
SetIndexBuffer(0,ExtOpenBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ExtHighBuffer,INDICATOR_DATA);
SetIndexBuffer(2,ExtLowBuffer,INDICATOR_DATA);
SetIndexBuffer(3,ExtCloseBuffer,INDICATOR_DATA);
//---- превращение динамического массива в цветовой, индексный буфер
SetIndexBuffer(4,ExtColorBuffer,INDICATOR_COLOR_INDEX);
//---- индексация элементов в буферах как в таймсериях
ArraySetAsSeries(ExtOpenBuffer,true);
ArraySetAsSeries(ExtHighBuffer,true);
ArraySetAsSeries(ExtLowBuffer,true);
ArraySetAsSeries(ExtCloseBuffer,true);
ArraySetAsSeries(ExtColorBuffer,true);
//---- осуществление сдвига начала отсчета отрисовки индикатора 1
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
//---- установка значений индикатора, которые не будут видимы на графике
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//---- Установка формата точности отображения индикатора
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---- имя для окон данных и метка для субъокон
string short_name="ThreeCandles";
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- завершение инициализации
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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<min_rates_total) return(RESET);
//---- объявления локальных переменных
int limit,bar;
//---- расчёты необходимого количества копируемых данных и стартового номера limit для цикла пересчёта баров
if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчёта индикатора
{
limit=rates_total-min_rates_total-1; // стартовый номер для расчёта всех баров
}
else
{
limit=rates_total-prev_calculated; // стартовый номер для расчёта новых баров
}
//---- индексация элементов в массивах, как в таймсериях
ArraySetAsSeries(low,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(open,true);
ArraySetAsSeries(tick_volume,true);
ArraySetAsSeries(volume,true);
//---- Основной цикл расчёта индикатора
for(bar=limit; bar>=0 && !IsStopped(); bar--)
{
bool chkVol=true;
ExtCloseBuffer[bar]=NULL;
ExtHighBuffer[bar]=NULL;
ExtLowBuffer[bar]=NULL;
ExtOpenBuffer[bar]=NULL;
ExtColorBuffer[bar]=2.0;
if((high[bar+3]-low[bar+3])/_Point>maxBar1) chkVol=false;
if(open[bar+3]<close[bar+3] && open[bar+2]<close[bar+2] && close[bar+2]<high[bar+3] && open[bar+1]>close[bar+1] && close[bar+1]<open[bar+2])
{
if(chkVol && VolumeType!=VOLUME_NONE)
{
if(VolumeType==VOLUME_TICK_)
{
if(tick_volume[bar+3]<tick_volume[bar+2] || tick_volume[bar+1]>tick_volume[bar+2] || tick_volume[bar+1]>tick_volume[bar+3])
{
ExtCloseBuffer[bar]=close[bar];
ExtHighBuffer[bar]=high[bar];
ExtLowBuffer[bar]=low[bar];
ExtOpenBuffer[bar]=open[bar];
if(close[bar]<open[bar]) ExtColorBuffer[bar]=0.0;
else ExtColorBuffer[bar]=1.0;
}
}
if(VolumeType==VOLUME_REAL_)
{
if(volume[bar+3]<volume[bar+2] || volume[bar+1]>volume[bar+2] || volume[bar+1]>volume[bar+3])
{
ExtCloseBuffer[bar]=close[bar];
ExtHighBuffer[bar]=high[bar];
ExtLowBuffer[bar]=low[bar];
ExtOpenBuffer[bar]=open[bar];
if(close[bar]<open[bar]) ExtColorBuffer[bar]=0.0;
else ExtColorBuffer[bar]=1.0;
}
}
}
else
{
ExtCloseBuffer[bar]=close[bar];
ExtHighBuffer[bar]=high[bar];
ExtLowBuffer[bar]=low[bar];
ExtOpenBuffer[bar]=open[bar];
if(close[bar]<open[bar]) ExtColorBuffer[bar]=0.0;
else ExtColorBuffer[bar]=1.0;
}
}
if(open[bar+3]>close[bar+3] && open[bar+2]>close[bar+2] && close[bar+2]>low[bar+3] && open[bar+1]<close[bar+1] && close[bar+1]>open[bar+2])
{
if(chkVol && VolumeType!=VOLUME_NONE)
{
if(VolumeType==VOLUME_TICK_)
{
if(tick_volume[bar+3]<tick_volume[bar+2] || tick_volume[bar+1]>tick_volume[bar+2] || tick_volume[bar+1]>tick_volume[bar+3])
{
ExtCloseBuffer[bar]=close[bar];
ExtHighBuffer[bar]=high[bar];
ExtLowBuffer[bar]=low[bar];
ExtOpenBuffer[bar]=open[bar];
if(close[bar]<open[bar]) ExtColorBuffer[bar]=3.0;
else ExtColorBuffer[bar]=4.0;
}
}
if(VolumeType==VOLUME_REAL_)
{
if(volume[bar+3]<volume[bar+2] || volume[bar+1]>volume[bar+2] || volume[bar+1]>volume[bar+3])
{
ExtCloseBuffer[bar]=close[bar];
ExtHighBuffer[bar]=high[bar];
ExtLowBuffer[bar]=low[bar];
ExtOpenBuffer[bar]=open[bar];
if(close[bar]<open[bar]) ExtColorBuffer[bar]=3.0;
else ExtColorBuffer[bar]=4.0;
}
}
}
else
{
ExtCloseBuffer[bar]=close[bar];
ExtHighBuffer[bar]=high[bar];
ExtLowBuffer[bar]=low[bar];
ExtOpenBuffer[bar]=open[bar];
if(close[bar]<open[bar]) ExtColorBuffer[bar]=3.0;
else ExtColorBuffer[bar]=4.0;
}
}
}
//---
BuySignal("ThreeCandles",ExtColorBuffer,rates_total,prev_calculated,close,spread);
SellSignal("ThreeCandles",ExtColorBuffer,rates_total,prev_calculated,close,spread);
//---
return(rates_total);
}
//+------------------------------------------------------------------+
//| Buy signal function |
//+------------------------------------------------------------------+
void BuySignal(string SignalSirname, // текст имени индикатора для почтовых и пуш-сигналов
double &Arrow[], // индикаторный буфер с сигналами для покупки
const int Rates_total, // текущее количество баров
const int Prev_calculated, // количество баров на предыдущем тике
const double &Close[], // цена закрытия
const int &Spread[]) // спред
{
//---
static uint counter=0;
if(Rates_total!=Prev_calculated) counter=0;
bool BuySignal=false;
bool SeriesTest=ArrayGetAsSeries(Arrow);
int index;
if(SeriesTest) index=int(NumberofBar);
else index=Rates_total-int(NumberofBar)-1;
if(Arrow[index]==3 || Arrow[index]==4) BuySignal=true;
if(BuySignal && counter<=NumberofAlerts)
{
counter++;
MqlDateTime tm;
TimeToStruct(TimeCurrent(),tm);
string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min);
SeriesTest=ArrayGetAsSeries(Close);
if(SeriesTest) index=int(NumberofBar);
else index=Rates_total-int(NumberofBar)-1;
double Ask=Close[index];
double Bid=Close[index];
SeriesTest=ArrayGetAsSeries(Spread);
if(SeriesTest) index=int(NumberofBar);
else index=Rates_total-int(NumberofBar)-1;
Bid+=Spread[index]*_Point;
string sAsk=DoubleToString(Ask,_Digits);
string sBid=DoubleToString(Bid,_Digits);
string sPeriod=GetStringTimeframe(ChartPeriod());
if(SoundON) Alert("BUY signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);
if(EMailON) SendMail(SignalSirname+": BUY signal alert","BUY signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
if(PushON) SendNotification(SignalSirname+": BUY signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
}
//---
}
//+------------------------------------------------------------------+
//| Sell signal function |
//+------------------------------------------------------------------+
void SellSignal(string SignalSirname, // текст имени индикатора для почтовых и пуш-сигналов
double & Arrow[], // индикаторный буфер с сигналами для покупки
const int Rates_total, // текущее количество баров
const int Prev_calculated, // количество баров на предыдущем тике
const double &Close[], // цена закрытия
const int &Spread[]) // спред
{
//---
static uint counter=0;
if(Rates_total!=Prev_calculated) counter=0;
bool SellSignal=false;
bool SeriesTest=ArrayGetAsSeries(Arrow);
int index;
if(SeriesTest) index=int(NumberofBar);
else index=Rates_total-int(NumberofBar)-1;
if(Arrow[index]==0 || Arrow[index]==1) SellSignal=true;
if(SellSignal && counter<=NumberofAlerts)
{
counter++;
MqlDateTime tm;
TimeToStruct(TimeCurrent(),tm);
string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min);
SeriesTest=ArrayGetAsSeries(Close);
if(SeriesTest) index=int(NumberofBar);
else index=Rates_total-int(NumberofBar)-1;
double Ask=Close[index];
double Bid=Close[index];
SeriesTest=ArrayGetAsSeries(Spread);
if(SeriesTest) index=int(NumberofBar);
else index=Rates_total-int(NumberofBar)-1;
Bid+=Spread[index]*_Point;
string sAsk=DoubleToString(Ask,_Digits);
string sBid=DoubleToString(Bid,_Digits);
string sPeriod=GetStringTimeframe(ChartPeriod());
if(SoundON) Alert("SELL signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);
if(EMailON) SendMail(SignalSirname+": SELL signal alert","SELL signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
if(PushON) SendNotification(SignalSirname+": SELL signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
}
//---
}
//+------------------------------------------------------------------+
//| Получение таймфрейма в виде строки |
//+------------------------------------------------------------------+
string GetStringTimeframe(ENUM_TIMEFRAMES timeframe)
{
//----
return(StringSubstr(EnumToString(timeframe),7,-1));
//----
}
//+------------------------------------------------------------------+