//+------------------------------------------------------------------+
//| two_candles.mq4 |
//| Vlad Sergeev |
//| http://moneyinnetwork.ru |
//+------------------------------------------------------------------+
#property copyright "Vlad Sergeev"
#property link "http://moneyinnetwork.ru"
#property version "1.00"
#property strict
#property indicator_chart_window
input int TextSize = 8; //размер шрифта
input color TextColor = clrRed; //цвет текста
input int TextAngle = 0; //угол поворота текста
input int MaxBar = 200; //количество последних баров, для которых рассчитывается индикатор
input int Body_Size = 100; //минимальная сумма тел двух соседних свечей (пунктов)
input double Percent1 = 35; //тень последней свечи в процентах от размера тела
input double Percent2 = 40; //
input int Depth = 21; //глубина выборки
//структура будет описывать свечу
struct candle {
//параметры свечи
double open, close, high, low, body; //цены
bool bullish, bear, doji, big; //вид свечи: бычья, медвежья, доджи (без тела), большая белая/черная
datetime t; //время свечи
double up_shadow, down_shadow, shadow; //верхняя и нижняя тени
//функция инициализирует параметры свечи, принимая в качестве аргумента индекс значения из таймсерии
void load (int i) {
bullish=false; bear=false; doji = false; big = false;
open = NormalizeDouble(iOpen(Symbol(),Period(),i), Digits); //цена открытия
close = NormalizeDouble(iClose(Symbol(),Period(),i), Digits); //цена закрытия
high = NormalizeDouble(iHigh(Symbol(),Period(),i), Digits); //максимальная цена
low = NormalizeDouble(iLow(Symbol(),Period(),i), Digits); //минимальная цена
t = iTime(Symbol(),Period(),i); //время закрытия
body = MathAbs(close-open); //размер тела
//проверка на "бычье тело"
if ( close > open ) {
bullish = true; //бычье тело
up_shadow = high-close; //верхняя тень
down_shadow = open-low; //нижняя тень
}
//проверка на "медвежье тело"
if ( close < open ) {
bear = true; //медвежье тело
up_shadow = high-open; //верхняя тень
down_shadow = close-low; //нижняя тень
}
//проверка на доджи - свеча без тела
if ( close == open ) {
doji = true; //счеча без тела - доджи
up_shadow = high-close; //верхняя тень
down_shadow = open-low; //нижняя тень
}
//проверка на большую свечу (размер тела минимум в 2 раза больше размера теней)
if ( body>=2*(up_shadow+down_shadow) ) big = true;
shadow = up_shadow+down_shadow;
}
};
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
for ( int i = 0; i < MaxBar; i++ ) {
if ( ObjectFind ("candle1"+ IntegerToString(i)) >=0 ) {
ObjectDelete("candle1"+ IntegerToString(i));
ObjectDelete("candle2"+ IntegerToString(i));
}
}
}
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[])
{
candle c1, c2;
for ( int i = 0; i < MaxBar; i++ )
{
if ( ObjectFind ("candle1"+ IntegerToString(i)) >=0 )
{
ObjectDelete("candle1"+ IntegerToString(i));
ObjectDelete("candle2"+ IntegerToString(i));
}
c1.load(i);
c2.load(i+1);
if ( c1.body+c2.body > Body_Size*Point &&
c1.shadow <= Percent1*c1.body/100 &&
( c1.body>=Percent2*(c1.body+c2.body)/100 || c2.body>=Percent2*(c1.body+c2.body)/100 ) &&
( Search_Big_Body(c1.body, i+2, Depth) || Search_Big_Body(c2.body, i+2, Depth) ) &&
( ( c1.close>c2.close && c1.close>c2.open ) || ( c1.close<c2.close && c1.close<c2.open ) )
)
{
ObjectCreate ("candle1"+ IntegerToString(i),
OBJ_TEXT,
0,
time[i],
high[i]+StepPer()*Point);
ObjectCreate ("candle2"+ IntegerToString(i),
OBJ_TEXT,
0,
time[i+1],
high[i+1]+StepPer()*Point);
ObjectSet ("candle1"+IntegerToString(i),
OBJPROP_ANGLE,
TextAngle);
ObjectSet ("candle2"+IntegerToString(i),
OBJPROP_ANGLE,
TextAngle );
ObjectSetText("candle1"+IntegerToString(i),
"2",
TextSize,
NULL,
TextColor);
ObjectSetText ("candle2"+IntegerToString(i),
"1",
TextSize,
NULL,
TextColor);
}
}
return(rates_total);
}
bool Search_Big_Body (double Body, int Start_Index, int Length)
{
candle c;
int i = 0;
while ( i < Length )
{
c.load(i+Start_Index);
if ( Body<c.body )
{
return false;
}
i++;
}
return true;
}
int StepPer ()
{
int i = 0;
switch (Period())
{
case PERIOD_M1:
i = 5;
break;
case PERIOD_M5:
i = 15;
break;
case PERIOD_M15:
i = 25;
break;
case PERIOD_M30:
i = 40;
break;
case PERIOD_H1:
i = 60;
break;
case PERIOD_H4:
i = 90;
break;
case PERIOD_D1:
i = 220;
break;
case PERIOD_W1:
i = 500;
break;
case PERIOD_MN1:
i = 2000;
break;
default:
break;
}
return (i);
}