//+------------------------------------------------------------------+
//|                                  Большая Коллекция Семафоров.mq4 |
//+------------------------------------------------------------------+
#property copyright "Сергеев Алексей (с) 2008"
// Индикатор-эксперт
// Положен принцип сопоставления сигналов от индикаторов 
// и исторических данных по достижению тейкпрофита или стоплоса на чарте
// Желательно применять на таймфреймах, ход цены за бар на которых 
// сравним со значениями тейкпрофита и стоплоса

// !!!!Для ознакомления рекомендуется использовать на таймфреймах с числом баров до 50000!!!

#property indicator_separate_window
#property indicator_minimum -1
#property indicator_maximum 1
#property indicator_buffers 4
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2
#property indicator_width4 2
#property indicator_color1 Orange
#property indicator_color2 SteelBlue
#property indicator_color3 Orange
#property indicator_color4 SteelBlue
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_SOLID
#property indicator_style3 STYLE_SOLID
#property indicator_style4 STYLE_SOLID

extern int TP=100;// значение тейкпрофита в пунктах
extern int SL=50;// значение стоплоса в пунктах

//---- буфера индикатора
double BuyTP[];//бар, при открытии на котором в покупку сработал тейкпрофит
double BuySL[];//бар, при открытии на котором в покупку сработал стоплос
double SellTP[];//бар, при открытии на котором в продажу сработал тейкпрофит
double SellSL[];//бар, при открытии на котором в продажу сработал стоплос
double M2[];// масиив сигналов индикатора

//------------------------------------------------------------------- init
int init()
{
	IndicatorBuffers(5);
	SetIndexBuffer(0,BuyTP);	SetIndexStyle(0,DRAW_HISTOGRAM);	
	SetIndexBuffer(1,BuySL);	SetIndexStyle(1,DRAW_HISTOGRAM);
	SetIndexBuffer(2,SellTP);	SetIndexStyle(2,DRAW_HISTOGRAM);
	SetIndexBuffer(3,SellSL);	SetIndexStyle(3,DRAW_HISTOGRAM);
	SetIndexBuffer(4,M2);			SetIndexStyle(4,DRAW_NONE);				
	IndicatorShortName("Подсчет для TP= "+TP+", SL= "+SL+" ");
	return(0);
}
//------------------------------------------------------------------- deinit
int deinit()  { return(0); }
//------------------------------------------------------------------- start
int start()
{
	int spread = MarketInfo(Symbol(), MODE_SPREAD); // получаем спред инструмента
	int i, k;
	double OpenPrice;
	bool find;
	//*********************************************************************************
	// 1. Вначале составляем массив М1 - исторически достижимые профит ТП и стоплос СЛ
	//*********************************************************************************
	int z = IndicatorCounted(); if (z>0) z--;
	i=Bars-1-z;
	while (i>0)
	{
		// ищем номер бара, на котором сработал ТП или СЛ для покупки
		OpenPrice = Open[i]+spread*Point; // цена открытия при покупке
		k=i; find= false;
		while (k>=0 && !find) 
		{
			if (Low[k]<=OpenPrice-SL*Point) { BuyTP[i] = 0.0; BuySL[i] = 1.0; find = true; }//если нашли бар СЛ
			else if (High[k]>=OpenPrice+TP*Point) { BuyTP[i] = 1; BuySL[i] = 0.0; find=true; } //если нашли бар ТП
			k--;
		}
		if (!find) { BuyTP[i] = 0.0; BuySL[i] = 0.0; }  // если не нашли баров, на которых сработа ТП или СЛ

		// ищем номер бара, на котором сработал ТП или СЛ для продажи
		OpenPrice = Open[i]; // цена открытия при продаже
		k=i; find=false;
		while (k>=0 && !find) 
		{
			if (High[k]>=OpenPrice+(SL+spread)*Point) { SellTP[i] = 0.0; SellSL[i] = -1.0; find = true; }//если нашли бар СЛ
			else if (Low[k]<=OpenPrice-(TP+spread)*Point) { SellTP[i] = -1.0; SellSL[i] = 0.0; find=true; } //если нашли бар ТП
			k--;
		}
		if (!find) { SellTP[i] = 0.0; SellSL[i] = 0.0; } // если не нашли баров, на которых сработа ТП или СЛ
		i--;
	}
	//****************************************************************************
	// 2. В этом блоке вы можете составить свой алгоритм поиска сигналов входа М2
	// Пример сделан для MACD
	//****************************************************************************
	int FastEMA=12;
	int SlowEMA=26;
	int SignalMA=9;
	int Price=PRICE_CLOSE;
	double main0, sign0, main1, sign1;
	i=Bars-1;
	while (i>0)
	{
		M2[i]=0.0;
		main0 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalMA, Price, MODE_MAIN, i);
		main1 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalMA, Price, MODE_MAIN, i-1);
		sign0 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalMA, Price, MODE_SIGNAL, i);
		sign1 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalMA, Price, MODE_SIGNAL, i-1);
		if (main0>sign0 && main1<sign1)	M2[i]=1.0;//если есть сигнал на покупку
		else if (main0<sign0 && main1>sign1)	M2[i]=-1.0;//если есть сигнал на продажу
		i--;
	}
	//**********************************************************************************
	// 3. Блок сравнения массивов М1 и М2. Вывод результатов в комментарии
	//**********************************************************************************
	//переменные для вывода статистики
	int nBuy=0, nSell=0, N=0, nBuyTP=0, nBuySL=0, nSellTP=0, nSellSL=0;
	i=Bars-1;
	while (i>0)
	{
		if (BuyTP[i]>0) nBuyTP++;//число баров с ТП при покупке
		if (BuySL[i]>0) nBuySL++;//число баров с СЛ при покупке
		if (SellTP[i]<0) nSellTP++;//число баров с ТП при продаже
		if (SellSL[i]<0) nSellSL++;//число баров с СЛ при продаже
		// подсчитываем полученную прибыль/убытки
		if (M2[i]==1.0 && BuyTP[i-1]==1.0)	nBuy++;//число совпавших профитных баров и сигналов на покупку
		if (M2[i]==-1.0 && SellTP[i-1]==-1.0)	nSell++;//число совпавших профитных баров и сигналов на продажу
		if (M2[i]!=0.0 && (BuySL[i-1]==-1.0 || SellSL[i-1]==-1.0))	N++;//число полученных убыточных баров
		i--;
	}
	// подготовка статистики
	string st="\n";
	st = st+ "Тейкпрофит= "+TP+",  Стоплос=  "+SL+"\n";
	st = st+ "ПОКУПКА: - прибыльных баров всего  "+ nBuyTP +", взятых по сигналу индикатора " + nBuy +"\n";
	st = st+ "ПРОДАЖА: - прибыльных баров всего  "+ nSellTP +", взятых по сигналу индикатора " + nSell+"\n";
	st = st+ "УБЫТОЧНЫХ: - баров всего  "+ (nBuySL+nSellSL) +", взятых по сигналу индикатора " + N+"\n";
	st = st+ "РЕЗУЛЬТАТ: " + ((nBuy+nSell)*TP-(N*SL)) + " пунктов \n";
	Comment(st);
	return(0);
}
//+----------------------------------------------------------------------------------+