//---------------------------------------------------------------------
//	Ïîñòðîåíèå êàíàëà ïî òðåì ýêñòðåìóìàì.
//---------------------------------------------------------------------
//	- ýêñòðåìóìû çàäàþòñÿ âðó÷íóþ òðåìÿ âåðòèêàëüíûìè ëèíèÿìè;
//	- îòñëåæèâàþòñÿ ïåðåìåùåíèÿ ýòèõ ëèíèé â ðåàëüíîì âðåìåíè;
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//	Èñòîðèÿ âåðñèé:
//---------------------------------------------------------------------
//	17.09.2009ã. - V2b01
//	 - ïåðåâåäåíî ïîñòðîåíèå óðàâíåíèé ñ âðåìåíè íà áàðû ( ÷òîáû íå áûëî
//		 èñêàæåíèé êàíàëà â ñâÿçè ñ ïðîïóñêàìè áàðîâ èëè âûõîäíûõ äíåé );
//	 - èñïðàâëåíà íåòî÷íîñòü ïðè âûêëþ÷åíèè îòîáðàæàåíèÿ ïàðàìåòðîâ êàíàëà
//		 ( îñòàâàëèñü çàãîëîâêè íà ýêðàíå );
//	 - èçìåíåí òèï ôëàãà óïðàâëåíèÿ îòîáðàæåíèåì ïàðàìåòðîâ êàíàëà íâ öåëûé
//		 (ò.ê. åñòü ïðîáëåìû ñ ëîãè÷åñêèì òèïîì);
//	 - îñòàâëåí ðàñ÷åò óðàâíåíèÿ òîëüêî îäíîé ëèíèè êàíàëà ( íà êîòîðîé
//		 ëåæàò äâå òî÷êè ýêñòðåìóìà ), îñòàëüíûå ëèíèè ïðîñòî ñìåùàþòñÿ
//		 íà âûñîòó êàíàëà;
//	 - äîáàâëåí âûâîä ðàçìåðà ïðîöåíòíîé çîíû â ïóíêòàõ;
//
//	18.09.2009ã. - V2b02
//	 - èñïðàâëåí íîìåð âåðñèè â äåôàéíå;
//	 - èñïðàâëåí ðàñ÷åò òåêóùèõ öåí ãðàíèö êàíàëà ( óáðàí àíàëèç òèïà êàíàëà );
//	 - äîáàâëåí âûâîä ïðîöåíòíîé çîíû âîêðóã ñðåäíåé ëèíèè êàíàëà;
//
//	21.09.2009ã. - V2b03
//	 - äîáàâëåíà çàïèñü òåêóùèõ çíà÷åíèé íà ãðàíèöàõ êàíàëà â ãëîáàëüíûå
//		 ïåðåìåííûå;
//	 - èñïðàâëåíà íåòî÷íîñòü ïðè ñîçäàíèè èìåíè òàáëèöà ( íå èñïîëüçîâàëñÿ
//		 ïðåôèêñ );
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#property copyright "Copyright © 2009, Dima S., ddd003@mail.ru"
#property link      "No site"
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#property  indicator_chart_window
#property  indicator_buffers	3
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#define INDICATOR_NAME					"SlideChannel"
#define INDICATOR_VERSION				"V2"
#define INDICATOR_SUB_VERSION		"b03"
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#define COLUMNS_IN_TABLE	5
#define ROWS_IN_TABLE			3
//---------------------------------------------------------------------
#define TREND_UP					1
#define TREND_DN				 -1
#define NO_TREND					0
//---------------------------------------------------------------------
//---------------------------------------------------------------------
double	DistanceToUpBuffer[ ];									// ðàññòîÿíèå îò òåêóùåé öåíû äî âåðõíåé ãðàíèöû êàíàëà
double	DistanceToDnBuffer[ ];									// ðàññòîÿíèå îò òåêóùåé öåíû äî íèæíåé ãðàíèöû êàíàëà
double	DistanceToMdBuffer[ ];									// ðàññòîÿíèå îò òåêóùåé öåíû äî ñðåäíåé ëèíèè êàíàëà
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//	Âíåøíèå ïîäêëþ÷àåìûå ìîäóëè:
//---------------------------------------------------------------------
#include <stdlib.mqh>														// ñòàíäàðòíàÿ áèáëèîòåêà
#include <lib_display.mq4>											// áèáëèîòåêà äëÿ âûâîäà äàííûõ íà ýêðàí
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//	Âíåøíèå çàäàâàåìûå ïàðàìåòðû:
//---------------------------------------------------------------------
//---------------------------------------------------------------------
extern string t1 = "Ðàáî÷èå ïàðàìåòðû";
//---------------------------------------------------------------------
extern color	ExtremumLineColor = LawnGreen;		// öâåò ëèíèé, çàäàþùèõ ýêñòðåìóìû
//---------------------------------------------------------------------
extern color	UpBorderColor = PaleGreen;				// öâåò âåðõíåé ãðàíèöû êàíàëà
extern color	DnBorderColor = Pink;							// öâåò íèæíåé ãðàíèöû êàíàëà
extern color	MdBorderColor = Khaki;						// öâåò ñðåäíåé ëèíèè êàíàëà
extern int		UpBorderWidth = 2;								// òîëùèíà ëèíèè äëÿ îòðèñîâêè âåðõíåé ãðàíèöû êàíàëà
extern int		DnBorderWidth = 2;								// òîëùèíà ëèíèè äëÿ îòðèñîâêè íèæíåé ãðàíèöû êàíàëà
extern int		MdBorderWidth = 1;								// òîëùèíà ëèíèè äëÿ îòðèñîâêè ñðåäíåé ëèíèè êàíàëà
//---------------------------------------------------------------------
extern string	PrefixString = "MainChannel";			// ïðåôèêñ äëÿ âîçìîæíîñòè óñòàíîâêè íåñêîëüêèõ èíäèêàòîðîâ íà ãðàôèê
//---------------------------------------------------------------------
extern string	i1 = "Îòîáðàæåíèå èíôîðìàöèè";
//---------------------------------------------------------------------
extern int		ShowInfo = 1;											// ïîêàçûâàòü ëè èíôîðìàöèþ ïî òåêóùåìó êàíàëó
extern int		InfoTopShift = 25;								// ñìåùåíèå ñâåðõó äëÿ âûâîäèìîé íà ýêðàí èíôîðìàöèè
extern int		InfoLeftShift = 10;								// ñìåùåíèå ñëåâà äëÿ âûâîäèìîé íà ýêðàí èíôîðìàöèè
//---------------------------------------------------------------------
extern int		UseOpenClosePrices = 1;						// 1 - èñïîëüçîâàòü öåíû Open/Close â ýêñòðåìóìàõ;
																								// 0 - èñïîëüçîâàòü öåíû High/Low â ýêñòðåìóìàõ;
//---------------------------------------------------------------------
extern int		ShowPercentageLines = 1;					// 1 - ïîêàçûâàòü ëèíèè ïðîöåíòíîé çîíû âîêðóã ãðàíèö
extern double	PercentageZoneSize = 10.0;				// ðàçìåð çîíû âîêðóã ãðàíèöû, â ïðîöåíòàõ îò øèðèíû êàíàëà
//---------------------------------------------------------------------
extern int		ShowMeedlePercentageLines = 1;		// 1 - ïîêàçûâàòü ëèíèè ïðîöåíòíîé çîíû âîêðóã ñðåäíåé ëèíèè
extern double	PercentageMeedleZoneSize = 5.0;		// ðàçìåð çîíû âîêðóã ñðåäíåé ëèíèè, â ïðîöåíòàõ îò øèðèíû êàíàëà
//---------------------------------------------------------------------
//	Äëÿ ïîñòðîåíèÿ òàáëèöû îòêðûòûõ ïîçèöèé íà ýêðàíå:
//---------------------------------------------------------------------
static int		x_prefix_positions[ ] = {  0,      50,         150,        200,     250 };
//---------------------------------------------------------------------
static string	titles[ ] =             { "Size", "UpBorder", "DnBorder", "Meedle", " " };
static int		x_titles_positions[ ] = {  10,     80,         200,        320,     400 };
static int		x_cell_positions[ ] =   {  0,      60,         180,        300,     420 };
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//	Ïàðàìåòðû òåêóùåãî êàíàëà:
//---------------------------------------------------------------------
bool			is_channel_on_screen = false;					// åñòü ëè âîîáùå êàíàë íà ýêðàíå
//---------------------------------------------------------------------
int				current_channel_type = -1;						// òèï êàíàëà ïî ðàñïîëîæåíèþ ýêñòðåìóìîâ
double		current_channel_size = 0;							// øèðèíà êàíàëà ïî îñè öåí
double		percentage_delta = 0.0;								// ïðîöåíòíàÿ çîíà âîêðóã êàíàëà
double		md_percentage_delta = 0.0;						// ïðîöåíòíàÿ çîíà âîêðóã ñðåäíåé ëèíèè êàíàëà
//---------------------------------------------------------------------
double		current_up_border_price = 0;					// çíà÷åíèå öåíû íà âåðõíåé ãðàíèöå êàíàëà
double		current_dn_border_price = 0;					// çíà÷åíèå öåíû íà íèæíåé ãðàíèöå êàíàëà
double		current_meedle_line_price = 0;				// çíà÷åíèå öåíû íà ñðåäíåé ëèíèè ãðàíèöå êàíàëà
//---------------------------------------------------------------------
double		current_up_border_distance = 0;				// ðàññòîÿíèå îò âåðõíåé ãðàíèöû êàíàëà äî òåêóùåé öåíû
double		current_dn_border_distance = 0;				// ðàññòîÿíèå îò íèæíåé ãðàíèöû êàíàëà äî òåêóùåé öåíû
double		current_meedle_line_distance = 0;			// ðàññòîÿíèå îò ñðåäíåé ëèíèè êàíàëà äî òåêóùåé öåíû
//---------------------------------------------------------------------
datetime	ActivateLineTFBar = 0;
//---------------------------------------------------------------------
//	Ýêñòðåìóìû:
//---------------------------------------------------------------------
#define MAX_EXTR_NUMBER		128
//---------------------------------------------------------------------
double		extr_x[ MAX_EXTR_NUMBER ];						// ìàññèâ òî÷åê íàéäåííûõ ýêñòðåìóìîâ íà âðåìåííîé îñè
string		extr_name[ MAX_EXTR_NUMBER ];					// ìàññèâ èìåí âåðòèêàëüíûõ ëèíèé, ñîîòâåòñòâóþùèõ íàéäåííûì ýêñòðåìóìàì
//---------------------------------------------------------------------
double		current_extremum1_x = 0.0;
double		current_extremum2_x = 0.0;
double		current_extremum3_x = 0.0;
//---------------------------------------------------------------------
double		current_extr_bars1_x = 0;
double		current_extr_bars2_x = 0;
double		current_extr_bars3_x = 0;
//---------------------------------------------------------------------
double		current_extremum1_y = 0.0;
double		current_extremum2_y = 0.0;
double		current_extremum3_y = 0.0;
//---------------------------------------------------------------------
//	Êîîðäèíàòû ëèíèé òåêóùåãî êàíàëà:
//---------------------------------------------------------------------
double		x1, x2;																// îáùèå êîîðäèíàòû äëÿ âñåõ ëèíèé êàíàëà
double		y1, y2, y3, y4, y5, y6;
double		koeff_a, koeff_b;
//---------------------------------------------------------------------
double		y1_up, y2_up, y3_up, y4_up, y5_up, y6_up;
double		y1_dn, y2_dn, y3_dn, y4_dn, y5_dn, y6_dn;
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//	Òåêóùèå ïàðàìåòðû ðûíêà:
//---------------------------------------------------------------------
double		current_bid;
double		current_ask;
double		current_spread;
int				current_digits;
double		current_point;
//---------------------------------------------------------------------
double		current_multiplier = 1.0;
//---------------------------------------------------------------------
//	Áàçà äëÿ èìåí ëèíèé òåêóùåãî êàíàëà
//---------------------------------------------------------------------
string	base_up_line_name = "UpBorder";
string	base_dn_line_name = "DownBorder";
string	base_md_line_name = "MeedleLine";
//---------------------------------------------------------------------
//	Èíèöèàëèçàöèÿ èíäèêàòîðà:
//---------------------------------------------------------------------
int
init( )
{
	int column, row;
	if( ShowInfo == 1 )
	{
		create_table( 0, PrefixString + "-" + INDICATOR_NAME + "-" + INDICATOR_VERSION + "-" + INDICATOR_SUB_VERSION, ROWS_IN_TABLE, COLUMNS_IN_TABLE );
//	Èíèöèàëèçèðóåì ÿ÷åéêè äëÿ âûâîäà çàãîëîâêîâ:
		for( column = 0; column < COLUMNS_IN_TABLE; column++ )
		{
			set_cell_attributes( 0, column, x_prefix_positions[ column ] + InfoLeftShift, InfoTopShift );
		}
//	Èíèöèàëèçèðóåì ÿ÷åéêè äëÿ âûâîäà çàãîëîâêîâ:
		for( column = 0; column < COLUMNS_IN_TABLE; column++ )
		{
			set_cell_attributes( 1, column, x_titles_positions[ column ] + InfoLeftShift, InfoTopShift + 25 );
		}
//	Èíèöèàëèçèðóåì ÿ÷åéêè äëÿ âûâîäà èíôîðìàöèè:
		for( row = 2; row < ROWS_IN_TABLE; row++ )
		{
			for( column = 0; column < COLUMNS_IN_TABLE; column++ )
			{
				set_cell_attributes( row, column, x_cell_positions[ column ] + InfoLeftShift, InfoTopShift + row * 20 );
				set_cell_text( row, column, "" );
			}
		}
		clear_table( );
		for( column = 0; column < COLUMNS_IN_TABLE; column++ )
		{
			set_cell_text( 1, column, titles[ column ], LightCyan );
		}
		set_cell_text( 0, 0, PrefixString + ":", LightCyan, 9 );
	}
//---------------------------------------------------------------------
	RefreshCurrentMarketInfo( Symbol( ));
//	Ïðîâåðÿåì íàëè÷èå ëèíèé ýêñòðåìóìîâ:
	if( cheak_extremum_moving( ) == true )
	{
		RefreshChannelInfo( );
		RefreshGlobalVariables( );
		DisplayChannelInfo( );
	}
	return( 0 );
}
//---------------------------------------------------------------------
//	Äåèíèöèàëèçàöèÿ ýêñïåðòà:
//---------------------------------------------------------------------
int
deinit( )
{
	delete_table( );
	if( is_channel_on_screen == true )
	{
		delete_current_channel( PrefixString, Symbol( ));
	}
	return( 0 );
}
//---------------------------------------------------------------------
//	Âûçûâàåòñÿ ïðè êàæäîì òèêå:
//---------------------------------------------------------------------
int
start( )
{
	RefreshCurrentMarketInfo( Symbol( ));
//---------------------------------------------------------------------
//	1. Âûâåäåì èíôîðìàöèþ ïî òåêóùåìó ïîñòðîåííîìó êàíàëó:
	if( is_channel_on_screen == true )
	{
		RefreshChannelInfo( );
		RefreshGlobalVariables( );
		DisplayChannelInfo( );
	}
//---------------------------------------------------------------------
//	2. Ïðîâåðÿåì íàëè÷èå ëèíèé ýêñòðåìóìîâ:
	if( cheak_extremum_moving( ) == true )
	{
		RefreshChannelInfo( );
		RefreshGlobalVariables( );
		DisplayChannelInfo( );
	}
	return( 0 );
}
//---------------------------------------------------------------------
//	Îáíîâèòü òåêóùèå ïàðàìåòðû ðûíêà äëÿ çàäàííîãî ñèìâîëà:
//---------------------------------------------------------------------
void
RefreshCurrentMarketInfo( string _symbol )
{
	RefreshRates( );
	current_bid = MarketInfo( _symbol, MODE_BID );
	current_ask = MarketInfo( _symbol, MODE_ASK );
	current_spread = MarketInfo( _symbol, MODE_SPREAD );
	current_digits = MarketInfo( _symbol, MODE_DIGITS );
	current_point = MarketInfo( _symbol, MODE_POINT );
	if( current_digits == 5 || current_digits == 3 )
		current_multiplier = 0.1;
	else
		current_multiplier = 1.0;
}
//---------------------------------------------------------------------
//	Ïðîâåðêà ñîîòâåòñòâèÿ ïàðàìåòðîâ ãðàôè÷åñêîãî îáúåêòà òðåáóåìûì:
//---------------------------------------------------------------------
bool
is_graphic_object_good( string _name, int _type, color _color, int _width, int _style )
{
//	Ïðîâåðêà òèïà îáúåêòà:
	if( ObjectType( _name ) != _type )
		return( false );
//	Ïðîâåðêà öâåòà îáúåêòà:
	if( ObjectGet( _name, OBJPROP_COLOR ) != _color )
		return( false );
//	Ïðîâåðêà òîëùèíû ëèíèè:
	if( ObjectGet( _name, OBJPROP_WIDTH ) != _width )
		return( false );
//	Ïðîâåðêà ñòèëÿ ëèíèè:
	if( ObjectGet( _name, OBJPROP_STYLE ) != _style )
		return( false );
	return( true );
}
//---------------------------------------------------------------------
//	Ïðîâåðêà íàëè÷èÿ ëèíèé ýêñòðåìóìîâ íà ýêðàíå:
//---------------------------------------------------------------------
//	- äîëæíî áûòü ðîâíî òðè ëèíèè;
//	- ëèíèè äîëæíû áûòü ïóíêòèðíûìè;
//	- ëèíèè äîëæíû áûòü îäèíàðíîé òîëùèíû;
//---------------------------------------------------------------------
bool
find_extremum_lines( )
{
	string	name;
	int			total_lines = 0;
//	1. Èùåì îáùåå ÷èñëî âåðòèêàëüíûõ ëèíèé ñ çàäàííûìè ñâîéñòâàìè è çàïèñûâàåì èõ â ìàññèâ:
	int		total_objects = ObjectsTotal( );
	for( int i = 0; i < total_objects; i++ )
	{
		name = ObjectName( i );
		if( is_graphic_object_good( name, OBJ_VLINE, ExtremumLineColor, 1, STYLE_DOT ) == true )
		{
			extr_name[ total_lines ] = name;
			extr_x[ total_lines ] = ObjectGet( name, OBJPROP_TIME1 );
			total_lines++;
		}
		if( total_lines >= MAX_EXTR_NUMBER )			// ÷òîáû íå ïåðåïîëíèòü ìàññèâ
			break;
	}
//	2. Åñëè íàéäåíî ðîâíî òðè ýêñòðåìóìà, òî ìîæíî ïûòàòüñÿ ñòðîèòü êàíàë:
	if( total_lines == 3 )
		return( true );
	return( false );
}
//---------------------------------------------------------------------
//	Ïðîâåðêà, ïåðåìåñòèëèñü ëè ýêñòðåìóìû íà ýêðàíå:
//---------------------------------------------------------------------
//	- åñëè õîòÿ áû îäíà èç òî÷åê ýêñòðåìóìîâ ïåðåìåñòèëàñü, òî ïåðåðèñîâûâàåì êàíàë;
//---------------------------------------------------------------------
bool
cheak_extremum_moving( )
{
//	1. Çàïîìíèì ñòàðûå ýêñòðåìóìû:
	double	extr1 = extr_x[ 0 ];
	double	extr2 = extr_x[ 1 ];
	double	extr3 = extr_x[ 2 ];
	if( find_extremum_lines( ) == TRUE )
	{
		if( is_channel_on_screen == FALSE )
		{
			current_channel_type = calc_channel( NULL, Period( ), extr_x[ 0 ], extr_x[ 1 ], extr_x[ 2 ] );
			if( current_channel_type != -1 )
			{
				draw_current_channel( PrefixString, NULL, 0 );
				is_channel_on_screen = TRUE;
			}
		}
		else if( extr1 != extr_x[ 0 ] || extr2 != extr_x[ 1 ] || extr3 != extr_x[ 2 ] )
		{
			current_channel_type = calc_channel( NULL, Period( ), extr_x[ 0 ], extr_x[ 1 ], extr_x[ 2 ] );
			if( current_channel_type != -1 )
			{
				delete_current_channel( PrefixString, Symbol( ));
				draw_current_channel( PrefixString, NULL, 0 );
				is_channel_on_screen = TRUE;
			}
		}
	}
	else
	{
		delete_current_channel( PrefixString, Symbol( ));
		is_channel_on_screen = FALSE;
		current_channel_type = -1;
		return( FALSE );
	}
}
//---------------------------------------------------------------------
//	Ïîèñê óòî÷íåííîãî ýêñòðåìóìà íà ìèíèìàëüíîì ÒÔ ( M1 ):
//---------------------------------------------------------------------
datetime
SearchExactExtremum( int _timeframe, datetime _extremum, int _type, int _price_type )
{
//	Ïðîáåæèìñÿ ïî áàðàì Ì1, óêëàäûâàþùèìñÿ â çàäàííûé ÒÔ:
	datetime	beg_dt = iTime( NULL, _timeframe, iBarShift( NULL, _timeframe, _extremum, FALSE ));
	datetime	end_dt = iTime( NULL, _timeframe, iBarShift( NULL, _timeframe, _extremum + _timeframe * 60, FALSE ));
	int				beg_shift_m1 = iBarShift( Symbol( ), PERIOD_M1, beg_dt, FALSE );
	int				end_shift_m1 = iBarShift( Symbol( ), PERIOD_M1, end_dt, FALSE );
	int				count = beg_shift_m1 - end_shift_m1;
////	Debug( 3, "beg_dt = " + TimeToStr( beg_dt ), "end_dt = " + TimeToStr( end_dt ), "beg_shift_m1 = " + DoubleToStr( beg_shift_m1, 0 ), "end_shift_m1 = " + DoubleToStr( end_shift_m1, 0 ));
	if( _type == 1 )
	{
		return( iTime( NULL, PERIOD_M1, iHighest( NULL, PERIOD_M1, _price_type, count, end_shift_m1 )));
	}
	if( _type == 2 )
	{
		return( iTime( NULL, PERIOD_M1, iLowest( NULL, PERIOD_M1, _price_type, count, end_shift_m1 )));
	}
	return( 0 );
}
//---------------------------------------------------------------------
//	Âû÷èñëåíèå êîîðäèíàò ëèíèé êàíàëà ïî çàäàííûì êîîðäèíàòàì Õ òðåõ ýêñòðåìóìîâ:
//---------------------------------------------------------------------
//	âîçâðàùàåò òèï ýêñòðåìóìà:
//	 -1 - êîîðäèíàòû çàäàíû íå êîððåêòíî
//		1 - 2 ìèíèìóìà, 1 ìàêñèìóì
//		2 - 2 ìàêñèìóìà, 1 ìèíèìóì
//---------------------------------------------------------------------
int
calc_channel( string _symbol,  int _timeframe, double _extremum1_x, double _extremum2_x, double _extremum3_x )
{
	double		extremum1_x, extremum2_x, extremum3_x;
	double		extremum1_y, extremum2_y, extremum3_y;
	int				ch_type;
	double		h1, h2, h3, l1, l2, l3;
	double		ex1_shift, ex2_shift, ex3_shift;
	double		extr;
//	1. Îòñîðòèðóåì êîîðäèíàòû ïî âîçðàñòàíèþ, ñëåâà íàïðàâî:
	if( _extremum1_x < _extremum2_x && _extremum1_x < _extremum3_x )
		extremum1_x = _extremum1_x;
	else if( _extremum2_x < _extremum1_x && _extremum2_x < _extremum3_x )
		extremum1_x = _extremum2_x;
	else if( _extremum3_x < _extremum1_x && _extremum3_x < _extremum1_x )
		extremum1_x = _extremum3_x;
	else
		return( -1 );
	if( _extremum1_x > _extremum2_x && _extremum1_x > _extremum3_x )
		extremum3_x = _extremum1_x;
	else if( _extremum2_x > _extremum1_x && _extremum2_x > _extremum3_x )
		extremum3_x = _extremum2_x;
	else if( _extremum3_x > _extremum1_x && _extremum3_x > _extremum2_x )
		extremum3_x = _extremum3_x;
	else
		return( -1 );
	if( _extremum1_x > extremum1_x && _extremum1_x < extremum3_x )
		extremum2_x = _extremum1_x;
	else if( _extremum2_x > extremum1_x && _extremum2_x < extremum3_x )
		extremum2_x = _extremum2_x;
	else if( _extremum3_x > extremum1_x && _extremum3_x < extremum3_x )
		extremum2_x = _extremum3_x;
	else
		return( -1 );
//	2. Îïðåäåëèì ðàñïîëîæåíèå ýêñòðåìóìîâ ïî âåðòèêàëè:
	int				shift1 = iBarShift( NULL, _timeframe, extremum1_x, false );
	int				shift2 = iBarShift( NULL, _timeframe, extremum2_x, false );
	int				shift3 = iBarShift( NULL, _timeframe, extremum3_x, false );
	if( UseOpenClosePrices == 1 )
	{
		h1 = iClose( NULL, _timeframe, shift1 );
		h2 = iClose( NULL, _timeframe, shift2 );
		h3 = iClose( NULL, _timeframe, shift3 );
		l1 = iOpen( NULL, _timeframe, shift1 );
		l2 = iOpen( NULL, _timeframe, shift2 );
		l3 = iOpen( NULL, _timeframe, shift3 );
		double		temp;
		if( h1 < l1 )
		{
			temp = h1;
			h1 = l1;
			l1 = temp;
		}
		if( h2 < l2 )
		{
			temp = h2;
			h2 = l2;
			l2 = temp;
		}
		if( h3 < l3 )
		{
			temp = h3;
			h3 = l3;
			l3 = temp;
		}
	}
	else
	{
		h1 = iHigh( NULL, _timeframe, shift1 );
		h2 = iHigh( NULL, _timeframe, shift2 );
		h3 = iHigh( NULL, _timeframe, shift3 );
		l1 = iLow( NULL, _timeframe, shift1 );
		l2 = iLow( NULL, _timeframe, shift2 );
		l3 = iLow( NULL, _timeframe, shift3 );
	}
	if( h1 > h2 && h3 > h2 )
	{
		extremum1_y = h1;
		extremum2_y = l2;
		extremum3_y = h3;
		ch_type = 2;															// 2 ìàêñèìóìà, 1 ìèíèìóì
//	Îïðåäåëèì óòî÷íåííûå çíà÷åíèÿ âðåìåí äëÿ ýêñòðåìóìîâ:
/*		extr = SearchExactExtremum( _timeframe, extremum1_x, ch_type, PRICE_HIGH );
		if( extr != 0 )
		{
			extremum1_x = extr;
		}
		extr = SearchExactExtremum( _timeframe, extremum2_x, ch_type, PRICE_LOW );
		if( extr != 0 )
		{
			extremum2_x = extr;
		}
		
		extr = SearchExactExtremum( _timeframe, extremum3_x, ch_type, PRICE_HIGH );
		if( extr != 0 )
		{
			extremum3_x = extr;
		}*/
	}
	else if( l1 < l2 && l3 < l2 )
	{
		extremum1_y = l1;
		extremum2_y = h2;
		extremum3_y = l3;
		ch_type = 1;															// 1 ìàêñèìóì, 2 ìèíèìóìà
//	Îïðåäåëèì óòî÷íåííûå çíà÷åíèÿ âðåìåí äëÿ ýêñòðåìóìîâ:
/*		extr = SearchExactExtremum( _timeframe, extremum1_x, ch_type, PRICE_LOW );
		if( extr != 0 )
		{
			extremum1_x = extr;
		}
		
		extr = SearchExactExtremum( _timeframe, extremum2_x, ch_type, PRICE_HIGH );
		if( extr != 0 )
		{
			extremum2_x = extr;
		}
		
		extr = SearchExactExtremum( _timeframe, extremum3_x, ch_type, PRICE_LOW );
		if( extr != 0 )
		{
			extremum3_x = extr;
		}*/
	}
	else
		return( -1 );
////	Debug( 3, "extremum1_x = " + TimeToStr( extremum1_x ), "extremum2_x = " + TimeToStr( extremum2_x ), "extremum3_x = " + TimeToStr( extremum3_x ));
//	3. Ñîõðàíèì òåêóùèå ýêñòðåìóìû ( îòñîðòèðîâàíû ïî âîçðàñòàíèþ êîîðäèíàòû âðåìåíè ):
	current_extremum1_x = extremum1_x;
	current_extremum2_x = extremum2_x;
	current_extremum3_x = extremum3_x;
	current_extremum1_y = extremum1_y;
	current_extremum2_y = extremum2_y;
	current_extremum3_y = extremum3_y;
	current_extr_bars1_x = iBars( NULL, _timeframe ) - shift1;
	current_extr_bars2_x = iBars( NULL, _timeframe ) - shift2;
	current_extr_bars3_x = iBars( NULL, _timeframe ) - shift3;
//	4. Îïðåäåëèì âñå êîîðäèíàòû ëèíèé êàíàëà:
	if( ch_type == 2 )
	{
		y1 = extremum1_y;
		y2 = extremum3_y;
		koeff_a = ( y2 - y1 ) / ( current_extr_bars3_x - current_extr_bars1_x );
		koeff_b = ( y1 * current_extr_bars3_x - y2 * current_extr_bars1_x ) / ( current_extr_bars3_x - current_extr_bars1_x );
		current_channel_size = MathAbs( koeff_a * current_extr_bars2_x + koeff_b - current_extremum2_y );
		y3 = y1 - current_channel_size;
		y4 = y2 - current_channel_size;
		y5 = y1 - current_channel_size / 2.0;
		y6 = y2 - current_channel_size / 2.0;
	}
	else if( ch_type == 1 )
	{
		y3 = extremum1_y;
		y4 = extremum3_y;
		koeff_a = ( y4 - y3 ) / ( current_extr_bars3_x - current_extr_bars1_x );
		koeff_b = ( y3 * current_extr_bars3_x - y4 * current_extr_bars1_x ) / ( current_extr_bars3_x - current_extr_bars1_x );
		current_channel_size = MathAbs( koeff_a * current_extr_bars2_x + koeff_b - current_extremum2_y );
		y1 = y3 + current_channel_size;
		y2 = y4 + current_channel_size;
		y5 = y3 + current_channel_size / 2.0;
		y6 = y4 + current_channel_size / 2.0;
	}
	x1 = extremum1_x;
	x2 = extremum3_x;
//	Âû÷èñëèì ëèíèè ïðîöåíòíûõ çîí âîêðóã ãðàíèö êàíàëà:
	percentage_delta = current_channel_size * PercentageZoneSize / 100.0;
	md_percentage_delta = current_channel_size * PercentageMeedleZoneSize / 100.0;
//---------------------------------------------------------------------
	y1_up = y1 + percentage_delta;
	y2_up = y2 + percentage_delta;
	y3_up = y3 + percentage_delta;
	y4_up = y4 + percentage_delta;
	y5_up = y5 + md_percentage_delta;
	y6_up = y6 + md_percentage_delta;
//---------------------------------------------------------------------
	y1_dn = y1 - percentage_delta;
	y2_dn = y2 - percentage_delta;
	y3_dn = y3 - percentage_delta;
	y4_dn = y4 - percentage_delta;
	y5_dn = y5 - md_percentage_delta;
	y6_dn = y6 - md_percentage_delta;
//---------------------------------------------------------------------
	return( ch_type );
}
//---------------------------------------------------------------------
//	Îòðèñîâêà êàíàëà:
//---------------------------------------------------------------------
void
draw_current_channel( string _prefix, string _symbol,  int _timeframe )
{
//	Îñíîâíîé êàíàë, ïîñòðîåííûé ïî ýêñòðåìóìàì:
	draw_channel_trendline( _prefix + "_" + base_up_line_name, x1, y1, x2, y2, UpBorderColor, UpBorderWidth, STYLE_SOLID );
	draw_channel_trendline( _prefix + "_" + base_dn_line_name, x1, y3, x2, y4, DnBorderColor, DnBorderWidth, STYLE_SOLID );
	draw_channel_trendline( _prefix + "_" + base_md_line_name, x1, y5, x2, y6, MdBorderColor, MdBorderWidth, STYLE_DOT );
//	Åñëè íóæíî, òî ïîñòðîèì ïðîöåíòíûå çîíû âîêðóã ãðàíèö êàíàëà:
	if( ShowPercentageLines == 1 )
	{
		draw_channel_trendline( _prefix + "_" + base_up_line_name + "+%", x1, y1_up, x2, y2_up, UpBorderColor, MdBorderWidth, STYLE_DOT );
		draw_channel_trendline( _prefix + "_" + base_up_line_name + "-%", x1, y1_dn, x2, y2_dn, UpBorderColor, MdBorderWidth, STYLE_DOT );
		draw_channel_trendline( _prefix + "_" + base_dn_line_name + "+%", x1, y3_up, x2, y4_up, DnBorderColor, MdBorderWidth, STYLE_DOT );
		draw_channel_trendline( _prefix + "_" + base_dn_line_name + "-%", x1, y3_dn, x2, y4_dn, DnBorderColor, MdBorderWidth, STYLE_DOT );
	}
//	Åñëè íóæíî, òî ïîñòðîèì ïðîöåíòíûå çîíû âîêðóã ñðåäíåé ëèíèè êàíàëà:
	if( ShowMeedlePercentageLines == 1 )
	{
		draw_channel_trendline( _prefix + "_" + base_md_line_name + "+%", x1, y5_up, x2, y6_up, DarkKhaki, MdBorderWidth, STYLE_DOT );
		draw_channel_trendline( _prefix + "_" + base_md_line_name + "-%", x1, y5_dn, x2, y6_dn, DarkKhaki, MdBorderWidth, STYLE_DOT );
	}
}
//---------------------------------------------------------------------
//	Óäàëèòü òåêóùèé êàíàë:
//---------------------------------------------------------------------
void
delete_current_channel( string _prefix, string _symbol )
{
	ObjectDelete( _prefix + "_" + base_up_line_name );
	ObjectDelete( _prefix + "_" + base_dn_line_name );
	ObjectDelete( _prefix + "_" + base_md_line_name );
	if( ShowPercentageLines == 1 )
	{
		ObjectDelete( _prefix + "_" + base_up_line_name + "+%" );
		ObjectDelete( _prefix + "_" + base_up_line_name + "-%" );
		ObjectDelete( _prefix + "_" + base_dn_line_name + "+%" );
		ObjectDelete( _prefix + "_" + base_dn_line_name + "-%" );
	}
	if( ShowMeedlePercentageLines == 1 )
	{
		ObjectDelete( _prefix + "_" + base_md_line_name + "+%" );
		ObjectDelete( _prefix + "_" + base_md_line_name + "-%" );
	}
}
//---------------------------------------------------------------------
//	Îòðèñîâêà òðåíäîâîé ëèíèè, ñîîòâåòñòâóþùåé ãðàíèöå êàíàëà:
//---------------------------------------------------------------------
void
draw_channel_trendline( string _name, double _datetime_x1, double _price_y1, double _datetime_x2, double _price_y2, color _color, double _width = 1, double _style = STYLE_SOLID )
{
	ObjectCreate( _name, OBJ_TREND, 0, _datetime_x1, _price_y1, _datetime_x2, _price_y2 ); 
	ObjectSet( _name, OBJPROP_COLOR, _color ); 
	ObjectSet( _name, OBJPROP_WIDTH, _width ); 
	ObjectSet( _name, OBJPROP_STYLE, _style );
}
//---------------------------------------------------------------------
//	Îòðèñîâêà âåðòèêàëüíîé ëèíèè:
//---------------------------------------------------------------------
void
draw_vline( string _name, double _datetime, color _color )
{
	ObjectCreate( _name, OBJ_VLINE, 0, _datetime, 0.0 );
	ObjectSet( _name, OBJPROP_COLOR, _color );
	ObjectSet( _name, OBJPROP_STYLE, STYLE_DOT );
}
//---------------------------------------------------------------------
//	Âûâåñòè ïàðàìåòðû òåêóùåãî êàíàëà íà ýêðàí:
//---------------------------------------------------------------------
void
DisplayChannelInfo( )
{
	if( ShowInfo != 1 )
		return;
	set_cell_text( 0, 2, "K = " + DoubleToStr( koeff_a / current_point * current_multiplier, current_digits ), Khaki, 9 );
	set_cell_text( 0, 4, "%Zone = " + DoubleToStr( percentage_delta / current_point * current_multiplier, 1 ) + " p.", Khaki, 9 );
	set_cell_text( 2, 0, DoubleToStr( current_channel_size / current_point * current_multiplier, 1 ) + " p.", Khaki, 9 );
	set_cell_text( 2, 1, DoubleToStr( current_up_border_price, current_digits ) + " ( " + DoubleToStr( current_up_border_distance * current_multiplier, 1 ) + " p. )", UpBorderColor, 9 );
	set_cell_text( 2, 2, DoubleToStr( current_dn_border_price, current_digits ) + " ( " + DoubleToStr( current_dn_border_distance * current_multiplier, 1 ) + " p. )", DnBorderColor, 9 );
	set_cell_text( 2, 3, DoubleToStr( current_meedle_line_price, current_digits ) + " ( " + DoubleToStr( current_meedle_line_distance * current_multiplier, 1 ) + " p. )", MdBorderColor, 9 );
}
//---------------------------------------------------------------------
//	Îáíîâèòü çíà÷åíèÿ â ãëîáàëüíûõ ïåðåìåííûõ:
//---------------------------------------------------------------------
void
RefreshGlobalVariables( )
{
	GlobalVariableSet( PrefixString + "_" + base_up_line_name + "_" + DoubleToStr( Period( ), 0 ) + "_" + Symbol( ), NormalizeDouble( current_up_border_price, current_digits ));
	GlobalVariableSet( PrefixString + "_" + base_dn_line_name + "_" + DoubleToStr( Period( ), 0 ) + "_" + Symbol( ), NormalizeDouble( current_dn_border_price, current_digits ));
	GlobalVariableSet( PrefixString + "_" + base_md_line_name + "_" + DoubleToStr( Period( ), 0 ) + "_" + Symbol( ), NormalizeDouble( current_meedle_line_price, current_digits ));
}
//---------------------------------------------------------------------
//	Îáíîâèòü ïàðàìåòðû òåêóùåãî êàíàëà:
//---------------------------------------------------------------------
void
RefreshChannelInfo( )
{
////	double	curr_x = Bars - iBarShift( NULL, 0, TimeCurrent( ), FALSE );
//	Òåêóùèå öåíû ãðàíèö êàíàëà:
	current_up_border_price = ObjectGetValueByShift( PrefixString + "_" + base_up_line_name, 0 );
	current_dn_border_price = ObjectGetValueByShift( PrefixString + "_" + base_dn_line_name, 0 );
	current_meedle_line_price = ObjectGetValueByShift( PrefixString + "_" + base_md_line_name, 0 );
////	current_up_border_price = koeff_a * curr_x + koeff_b;
////	current_dn_border_price = current_up_border_price - current_channel_size;
////	current_meedle_line_price = current_up_border_price - current_channel_size / 2.0;
//	Ðàññòîÿíèå â ïóíêòàõ îò òåêóùåé öåíû äî ãðàíèö êàíàëà:
	current_up_border_distance = ( current_bid - current_up_border_price ) / current_point;
	current_dn_border_distance = ( current_bid - current_dn_border_price ) / current_point;
	current_meedle_line_distance = ( current_bid - current_meedle_line_price ) / current_point;
}
//---------------------------------------------------------------------
//	Âûâîäèò îòëàäî÷íóþ èíôîðìàöèþ:
//---------------------------------------------------------------------
//		0 - íå âûâîäèòü îòëàäî÷íóþ èíôîðìàöèþ;
//		1 - âûâîäèòü â æóðíàë;
//		2 - âûâîäèòü â Comment;
//		3 - îáúåäèíÿåò äâà ïðåäûäóùèõ;
//---------------------------------------------------------------------
void
Debug( int _print_mode, string p1 = "", string p2 = "", string p3 = "", string p4 = "", string p5 = "", string p6 = "", string p7 = "", string p8 = "", string p9 = "", string p10 = "", string p11 = "" )
{
	if( _print_mode == 1 || _print_mode == 3 )
	{
		Print( p1 + "  " + p2 + "  " + p3 + "  " + p4 + "  " + p5 + "  " + p6 + "  " + p7 + "  " + p8 + "  " + p9 + "  " + p10 + "  " + p11 );
	}
	if( _print_mode == 2 || _print_mode == 3 )
	{
		Comment( p1 + "\n" + p2 + "\n" + p3 + "\n" + p4 + "\n" + p5 + "\n" + p6 + "\n" + p7 + "\n" + p8 + "\n" + p9 + "\n" + p10 + "\n" + p11 );
	}
}
//---------------------------------------------------------------------
             
            
            
            
            
Comments