Fans von GUOs

 
Es war ein sehr lautes Thema der grafischen Auftragsverwaltung ......
Gestern erinnerte ich mich daran und dachte: Warum nicht umsetzen?

19.03.2005
Lesen Sie die Anleitung, bevor Sie es benutzen =)

//+------------------------------------------------------------------+
//|                                           Send_Pending_Order.mq4 |
//|                                                        komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
#property copyright "komposter"
#property link      "mailto:komposterius@mail.ru"
/*
-----------------------------В-Н-И-М-А-Н-И-Е---------------------------------
Перед запуском скрипта настоятельно рекомендую изучить следующее руководство:

Скрипт предназначен для установки отложенного ордера.
Для этого необходимо:
 1) Ознакомиться с данным руководством =), !установить значения по умолчанию! (находятся под описанием,
 	 начинаются и заканчиваются строкой //+----------------------------------------------+ ),
 	 разрешить импорт внешних экспертов через меню
 	 "Сервис" -> "Настройки" -> "Советники" -> "Разрешить импортирование внешних экспертов"
 	 (необходимо для описания ошибки, которая может возникнуть при установке ордера)
 2) Перетащить скрипт на график. При этом учитывать, что место прикрепления - это будущая
 	 цена открытия (OpenPrice). В процессе установки её можно будет менять, но для упрощения
 	 работы рекомендую перетаскивать скрипт сразу на нужный уровень.
 3) Переместить все линии на необходимые уровни:
		- Open_Price_Line (по умолчанию - белая) - цена открытия  (ОБЯЗАТЕЛЬНАЯ линия)
		- Stop_Loss_Line (красная) - уровень Стоп Лосс (ОБЯЗАТЕЛЬНАЯ)
		- Take_Profit_Line (зелёная) - уровень Тейк Профит (необязательная)
		- Expiration_Line (жёлтая) - время истечения (необязательная)
		(необязательные линии можно удалять)
		- "````" - размер позиции. Необходимо установить напротив нужного значения (от 0,1 до 10 лотов)
	В зависимости от расположения линий Open_Price и Stop_Loss выбирается тип ордера:
	Open_Price  >  Bid и Open_Price  >  Stop_Loss  -  BUYSTOP-ордер,
	Open_Price  >  Bid и Open_Price  <  Stop_Loss  -  SELLLIMIT-ордер,
	Open_Price  <  Ask и Open_Price  >  Stop_Loss  -  BUYLIMIT-ордер,
	Open_Price  <  Ask и Open_Price  <  Stop_Loss  -  SELLSTOP-ордер.
 4) Когда всё будет готово, в появившемся окне нажать кнопку "ОК".
 
 
 Для прекращения работы скрипта в любой момент можно воспользоваться кнопкой "Отмена".
 Если Вами будет найдена ошибка в коде, или в логике работы скрипта, просьба сообщить на komposterius@mail.ru
*/
//+------------------------------------------------------------------+
// Все нижеописанные переменные можно будет изменить в окне свойств скрипта,
// которое откроется при прикреплении. Это полезно, например, при необходимости выбрать
// непредставленный в списке "Lots" размер позиции. Для этого, написав нужную цифру в окне свойств (например, 1.5),
// НЕ ДВИГАЙТЕ указатель размера лота ( "````" ).
// Если окно свойств не нужно, надо закомментировать следующую строку (поставить в начало //)
#property show_inputs


// Тип ордера по умолчанию (влияет на начальное расположение линий стоп-лосс и тейк-профит)
extern int _OrderType = 1; //( "1" - BUYSTOP или BUYLIMIT, "-1" - SELLSTOP или SELLLIMIT )

// Обьём сделки по умолчанию (можно менять в процессе работы)
// от 0.1 до 1.0 с шагом 0.1, от 1 до 10 с шагом 1
extern double Lots = 0.1;

// Расстояние между линией Take_Profit/Stop_Loss и линией Open_Price в пунктах по умолчанию.
// Если Take_Profit использоваться не будет, установите 0
extern int Stop_Loss = 50;
extern int Take_Profit = 50;

// Максимальное отклонение от запрошенной цены
extern int Slippage = 5;

// Комментарий к ордеру
extern string _Comment = "Opened by script";

// Order ID
extern int MagicNumber = 0;

// Время истечения ордера, выраженное в свечах
// Для периода графика H4 и Expiration_Shift = 3 время истечения наступит через 12 часов после установки
// Если необходимо стандартное время истечения для всех периодов графика, укажите "0" (без кавычек), и переходите к следующей настройке
// Если время истечения ордера использоваться не будет, установите 0
extern int Expiration_Shift = 0;
// Время истечения ордера, выраженное в часах
// Для того, чтоб использовать эту настройку, необходимо установить Expiration_Shift (см. выше на 2 строки) "0" (без кавычек)
// Если время истечения ордера использоваться не будет, установите 0
extern int Expiration_Shift_H = 0;

extern string Order_Color = "----------------------------------------------------------------------------------------";
// Цвета отображения ордеров на графике
extern color Buy_Color = Lime; //( для ордеров BUYSTOP и BUYLIMIT )
extern color Sell_Color = Red; //( для ордеров SELLLIMIT и SELLSTOP )

extern string Line_Color = "----------------------------------------------------------------------------------------";
// Цвета линий:
extern color Open_Price_Line_Color = White;
extern color Stop_Loss_Line_Color = Red;
extern color Take_Profit_Line_Color = Lime;
extern color Expiration_Line_Color = Yellow;

//+------------------------------------------------------------------+

#include <stdlib.mqh>
int first = 1;
int start()
{
// Установка начальных значений:
double Open_Price_Level, Stop_Loss_Level, Take_Profit_Level;
datetime Expiration_Time;
// ---Open_Price_Level
	Open_Price_Level = PriceOnDropped();
	if ( Open_Price_Level <= 0 )
		{ Open_Price_Level = Bid + MarketInfo( Symbol(), MODE_STOPLEVEL )*Point; }
// ---Stop_Loss_Level
	Stop_Loss_Level = Open_Price_Level - Stop_Loss * Point;
// ---Take_Profit_Level
	if ( Take_Profit > 0 )
	{ Take_Profit_Level = Open_Price_Level + Take_Profit * Point; }

if ( _OrderType == -1 )
{
// ---Open_Price_Level
	Open_Price_Level = PriceOnDropped();
	if ( Open_Price_Level <= 0 )
		{ Open_Price_Level = Ask - MarketInfo( Symbol(), MODE_STOPLEVEL )*Point; }
// ---Stop_Loss_Level
	Stop_Loss_Level = Open_Price_Level + Stop_Loss * Point;
// ---Take_Profit_Level
	if ( Take_Profit > 0 )
	{ Take_Profit_Level = Open_Price_Level - Take_Profit * Point; }
}

// ---Expiration_Time
	if ( Expiration_Shift > 0 )
	{ Expiration_Time = CurTime() + Period()*60*Expiration_Shift; }
	else
	{
		if ( Expiration_Shift_H > 0 )
			{ Expiration_Time = CurTime() + 3600*Expiration_Shift_H; }
	}
// Создание линий:
if ( first == 1 )
{
	ObjectCreate( "Open_Price_Line", OBJ_HLINE, 0, 0, Open_Price_Level, 0, 0, 0, 0 );
	ObjectSet( "Open_Price_Line", OBJPROP_COLOR, Open_Price_Line_Color );
	ObjectSetText( "Open_Price_Line", "Open_Price_Line", 6, "Arial", Open_Price_Line_Color );

	ObjectCreate( "Stop_Loss_Line", OBJ_HLINE, 0, 0, Stop_Loss_Level, 0, 0, 0, 0 );
	ObjectSet( "Stop_Loss_Line", OBJPROP_COLOR, Stop_Loss_Line_Color );
	ObjectSetText( "Stop_Loss_Line", "Stop_Loss_Line", 6, "Arial", Stop_Loss_Line_Color );

	if ( Take_Profit_Level > 0 )
	{
		ObjectCreate( "Take_Profit_Line", OBJ_HLINE, 0, 0, Take_Profit_Level, 0, 0, 0, 0 );
		ObjectSet( "Take_Profit_Line", OBJPROP_COLOR, Take_Profit_Line_Color );
		ObjectSetText( "Take_Profit_Line", "Take_Profit_Line", 6, "Arial", Take_Profit_Line_Color );
	}

	if ( Expiration_Time > 0 )
	{
		ObjectCreate( "Expiration_Line", OBJ_VLINE, 0, Expiration_Time, 0, 0, 0, 0, 0 );
		ObjectSet( "Expiration_Line", OBJPROP_COLOR, Expiration_Line_Color );
		ObjectSetText( "Expiration_Line", "Expiration_Line", 6, "Arial", Expiration_Line_Color );
	}
// создание "Шкалы размера лота" и установка на значение по умолчанию
	int Lots_value_y = 30;
	switch ( Lots )
	{
		case 0.2: Lots_value_y = 45; break;
		case 0.3: Lots_value_y = 60; break;
		case 0.4: Lots_value_y = 75; break;
		case 0.5: Lots_value_y = 90; break;
		case 0.6: Lots_value_y = 105; break;
		case 0.7: Lots_value_y = 120; break;
		case 0.8: Lots_value_y = 135; break;
		case 0.9: Lots_value_y = 150; break;
		case 1.0: Lots_value_y = 165; break;
		case 2.0: Lots_value_y = 180; break;
		case 3.0: Lots_value_y = 195; break;
		case 4.0: Lots_value_y = 210; break;
		case 5.0: Lots_value_y = 225; break;
		case 6.0: Lots_value_y = 240; break;
		case 7.0: Lots_value_y = 255; break;
		case 8.0: Lots_value_y = 270; break;
		case 9.0: Lots_value_y = 285; break;
		case 10.0: Lots_value_y = 300; break;
	}
	if ( Lots > 10.0 ) Lots_value_y = 315;
	int Lots_value_y_start_position = Lots_value_y;
	
	ObjectCreate( "Lots", OBJ_LABEL, 0,0,0,0,0,0,0);
	ObjectSet( "Lots", OBJPROP_CORNER, 1);
	ObjectSet( "Lots", OBJPROP_XDISTANCE, 1);
	ObjectSet( "Lots", OBJPROP_YDISTANCE, 10);
	ObjectSetText(  "Lots", "Lots", 10, "Arial", Open_Price_Line_Color);

	ObjectCreate( "Lots_value", OBJ_LABEL, 0,0,0,0,0,0,0);
	ObjectSet( "Lots_value", OBJPROP_CORNER, 1);
	ObjectSet( "Lots_value", OBJPROP_XDISTANCE, 25);
	ObjectSet( "Lots_value", OBJPROP_YDISTANCE, Lots_value_y);
	ObjectSetText(  "Lots_value", "`````", 10, "Arial", Open_Price_Line_Color);

	int y = 25;
	for ( double z = 0.1; z <= 1; z += 0.1 )
	{
		ObjectCreate( DoubleToStr( z, 1 ), OBJ_LABEL, 0,0,0,0,0,0,0);
		ObjectSet( DoubleToStr( z, 1 ), OBJPROP_CORNER, 1);
		ObjectSet( DoubleToStr( z, 1 ), OBJPROP_XDISTANCE, 1);
		ObjectSet( DoubleToStr( z, 1 ), OBJPROP_YDISTANCE, y);
		ObjectSetText(  DoubleToStr( z, 1 ), DoubleToStr( z, 1 ), 10, "Arial", Open_Price_Line_Color);
		y += 15;
	}
	y = 160;
	for ( z = 1; z <= 10; z ++ )
	{
		ObjectCreate( DoubleToStr( z, 1 ), OBJ_LABEL, 0,0,0,0,0,0,0);
		ObjectSet( DoubleToStr( z, 1 ), OBJPROP_CORNER, 1);
		ObjectSet( DoubleToStr( z, 1 ), OBJPROP_XDISTANCE, 1);
		ObjectSet( DoubleToStr( z, 1 ), OBJPROP_YDISTANCE, y);
		ObjectSetText(  DoubleToStr( z, 1 ), DoubleToStr( z, 1 ), 10, "Arial", Open_Price_Line_Color);
		y += 15;
	}
	ObjectCreate( ">", OBJ_LABEL, 0,0,0,0,0,0,0);
	ObjectSet( ">", OBJPROP_CORNER, 1);
	ObjectSet( ">", OBJPROP_XDISTANCE, 1);
	ObjectSet( ">", OBJPROP_YDISTANCE, 310);
	ObjectSetText(  ">", ">10", 10, "Arial", Open_Price_Line_Color);

// вывод месседжбокса
	string Question = "Для установки ордера переместите линии на необходимые уровни и нажмите \"ОК\".\n" + 
							"Чтоб отказаться от установки, нажмите \"Отмена\".";
	int  Answer = MessageBox( Question, "Установка отложенного ордера", 0x00000001 | 0x00000040 | 0x00040000 );
	first = 0;
	// если нажата любая кроме "ОК" кнопка - выходим
	if ( Answer != 1 ) { deinit(); return(0); }
}

// считываем значения с объектов и нормализуем:

// размер лота
	Lots_value_y = ObjectGet( "Lots_value", OBJPROP_YDISTANCE );
	if ( Lots_value_y_start_position != Lots_value_y )
	{
		Lots = 0.1;
		if ( Lots_value_y >= 35  && Lots_value_y < 50  ) Lots = 0.2;
		if ( Lots_value_y >= 50  && Lots_value_y < 65  ) Lots = 0.3;
		if ( Lots_value_y >= 65  && Lots_value_y < 80  ) Lots = 0.4;
		if ( Lots_value_y >= 80  && Lots_value_y < 95  ) Lots = 0.5;
		if ( Lots_value_y >= 95  && Lots_value_y < 110 ) Lots = 0.6;
		if ( Lots_value_y >= 110 && Lots_value_y < 125 ) Lots = 0.7;
		if ( Lots_value_y >= 125 && Lots_value_y < 140 ) Lots = 0.8;
		if ( Lots_value_y >= 140 && Lots_value_y < 155 ) Lots = 0.9;
		if ( Lots_value_y >= 155 && Lots_value_y < 170 ) Lots = 1.0;
		if ( Lots_value_y >= 170 && Lots_value_y < 185 ) Lots = 2.0;
		if ( Lots_value_y >= 185 && Lots_value_y < 200 ) Lots = 3.0;
		if ( Lots_value_y >= 200 && Lots_value_y < 215 ) Lots = 4.0;
		if ( Lots_value_y >= 215 && Lots_value_y < 230 ) Lots = 5.0;
		if ( Lots_value_y >= 230 && Lots_value_y < 245 ) Lots = 6.0;
		if ( Lots_value_y >= 245 && Lots_value_y < 260 ) Lots = 7.0;
		if ( Lots_value_y >= 260 && Lots_value_y < 275 ) Lots = 8.0;
		if ( Lots_value_y >= 275 && Lots_value_y < 290 ) Lots = 9.0;
		if ( Lots_value_y >= 290 							  ) Lots = 10.0;
	}
	Lots = NormalizeDouble( Lots, 1 );
// Open_Price
	Open_Price_Level = NormalizeDouble( ObjectGet( "Open_Price_Line", OBJPROP_PRICE1 ), MarketInfo( Symbol(), MODE_DIGITS ) );
// Stop_Loss
	Stop_Loss_Level = NormalizeDouble( ObjectGet( "Stop_Loss_Line", OBJPROP_PRICE1 ), MarketInfo( Symbol(), MODE_DIGITS ) );
// Take_Profit
	Take_Profit_Level = NormalizeDouble( ObjectGet( "Take_Profit_Line", OBJPROP_PRICE1 ), MarketInfo( Symbol(), MODE_DIGITS ) );
// Expiration_Time
	Expiration_Time = ObjectGet( "Expiration_Line", OBJPROP_TIME1 );
	
// определяем тип ордера
	if ( Open_Price_Level - Bid >= 0 )
	{
		if ( Open_Price_Level - Stop_Loss_Level > 0 )
		{ _OrderType = OP_BUYSTOP; }
		else
		{ _OrderType = OP_SELLLIMIT; }
	}
	else
	{
		if ( Open_Price_Level - Stop_Loss_Level > 0 )
		{ _OrderType = OP_BUYLIMIT; }
		else
		{ _OrderType = OP_SELLSTOP; }
	}

color _Color;
// проверяем все значения
	if ( _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP )
	{
		_Color = Buy_Color;
		if ( Open_Price_Level - Stop_Loss_Level < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point )
		{
			Answer = MessageBox(  "Неправильно установлена Stop_Loss_Line (красная линия)!\n" + 
					 		 			 "\n" +
					 		 			 "Для BuyLimit и BuyStop - ордеров она должна быть НИЖЕ линии Open_Price_Line.	\n" + 
					 		 			 "Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 "\n\n" +
					 		 			 "Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 "Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
			if ( Answer == 4 ) { ObjectsRedraw(); start(); }
			deinit();
			return(-1);
		}
		if ( Take_Profit_Level - Open_Price_Level < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point && Take_Profit_Level > 0 )
		{
			Answer = MessageBox(  "Неправильно установлена Take_Profit_Line (зелёная линия)!\n" + 
					 		 			 "\n" +
					 		 			 "Для BuyLimit и BuyStop - ордеров она должна быть ВЫШЕ линии Open_Price_Line.	\n" + 
					 		 			 "Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 "\n\n" +
					 		 			 "Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 "Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
			if ( Answer == 4 ) { ObjectsRedraw(); start(); }
			deinit();
			return(-1);
		}
		if ( _OrderType == OP_BUYSTOP )
		{
			if ( Open_Price_Level - Bid < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point )
			{
				Answer = MessageBox( "Неправильно установлена Open_Price_Line (белая линия)!\n" + 
					 		 			 	"\n" +
					 		 			 	"Для BuyStop - ордера она должна быть ВЫШЕ текущей цены.	\n" + 
					 		 			 	"Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 	"\n\n" +
					 		 			 	"Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 	"Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
				if ( Answer == 4 ) { ObjectsRedraw(); start(); }
				deinit();
				return(-1);
			}
		}
		else
		{
			if ( Bid - Open_Price_Level < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point )
			{
				Answer = MessageBox( "Неправильно установлена Open_Price_Line (белая линия)!\n" + 
					 		 			 	"\n" +
					 		 			 	"Для BuyLimit - ордера она должна быть НИЖЕ текущей цены.	\n" + 
					 		 			 	"Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 	"\n\n" +
					 		 			 	"Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 	"Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
				if ( Answer == 4 ) { ObjectsRedraw(); start(); }
				deinit();
				return(-1);
			}
		}
	}
	if ( _OrderType == OP_SELLLIMIT || _OrderType == OP_SELLSTOP )
	{
		_Color = Sell_Color;
		if ( Stop_Loss_Level - Open_Price_Level < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point )
		{
			Answer = MessageBox(  "Неправильно установлена Stop_Loss_Line (красная линия)!\n" + 
					 		 			 "\n" +
					 		 			 "Для SellLimit и SellStop - ордеров она должна быть ВЫШЕ линии Open_Price_Line.	\n" + 
					 		 			 "Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 "\n\n" +
					 		 			 "Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 "Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
			if ( Answer == 4 ) { ObjectsRedraw(); start(); }
			deinit();
			return(-1);
		}
		if ( Open_Price_Level - Take_Profit_Level < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point && Take_Profit_Level > 0 )
		{
			Answer = MessageBox(  "Неправильно установлена Take_Profit_Line (зелёная линия)!\n" + 
					 		 			 "\n" +
					 		 			 "Для SellLimit и SellStop - ордеров она должна быть НИЖЕ линии Open_Price_Line.	\n" + 
					 		 			 "Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 "\n\n" +
					 		 			 "Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 "Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
			if ( Answer == 4 ) { ObjectsRedraw(); start(); }
			deinit();
			return(-1);
		}
		if ( _OrderType == OP_SELLLIMIT )
		{
			if ( Open_Price_Level - Ask < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point )
			{
				Answer = MessageBox( "Неправильно установлена Open_Price_Line (белая линия)!\n" + 
					 		 			 	"\n" +
					 		 			 	"Для SellLimit - ордера она должна быть НИЖЕ текущей цены.	\n" + 
					 		 			 	"Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 	"\n\n" +
					 		 			 	"Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 	"Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
				if ( Answer == 4 ) { ObjectsRedraw(); start(); }
				deinit();
				return(-1);
			}
		}
		else
		{
			if ( Ask - Open_Price_Level < MarketInfo( Symbol(), MODE_STOPLEVEL )*Point )
			{
				Answer = MessageBox( "Неправильно установлена Open_Price_Line (белая линия)!\n" + 
					 		 			 	"\n" +
					 		 			 	"Для SellStop - ордера она должна быть ВЫШЕ текущей цены.	\n" + 
					 		 			 	"Минимальный отступ (" + Symbol() + ") - " + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) + " пунктов.\n" + 
					 		 			 	"\n\n" +
					 		 			 	"Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 	"Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
				if ( Answer == 4 ) { ObjectsRedraw(); start(); }
				deinit();
				return(-1);
			}
		}
	}

	if ( Expiration_Time <= CurTime() && Expiration_Time > 0 )
	{
			Answer = MessageBox(  "Неправильно установлена Expiration_Line (жёлтая линия)!\n" + 
					 		 			 "\n" +
					 		 			 "Срок истечения ордера не может быть в прошедшем времени!		\n" + 
					 		 			 "\n\n" +
					 		 			 "Чтобы начать установку с начала, нажмите \"Повтор\".\n" +
					 		 			 "Чтоб отказаться от установки, нажмите \"Отмена\".", "Установка отложенного ордера", 0x00000005 | 0x00000030 | 0x00040000 );
			if ( Answer == 4 ) { ObjectsRedraw(); start(); }
			deinit();
			return(-1);
	}
	
// выводим инфу о запросе и пытаемся установить ордер
	Print( "Symbol=",Symbol(), ",_OrderType=",_OrderType, ",Lots=",Lots, ",Open_Price_Level=",Open_Price_Level, ",Slippage=", Slippage, ",Stop_Loss_Level=", Stop_Loss_Level, ",Take_Profit_Level=", Take_Profit_Level, ",_Comment=", _Comment, ",MagicNumber=", MagicNumber, ",Expiration_Time=", Expiration_Time, ",_Color=", _Color );
	int ordersend = OrderSend( Symbol(), _OrderType, Lots, Open_Price_Level, Slippage, Stop_Loss_Level, Take_Profit_Level, _Comment, MagicNumber, Expiration_Time, _Color );
	if ( ordersend > 0 )
	{
// если всё ок, выводим лог и выходим
		OrderPrint();
		Print( "Ордер №", ordersend, " установлен успешно!");
		return(0);
	}
// если ошибка - выводим сообщение и выходим
	int error = GetLastError();
	Print("Ошибка при установке! GetLastError = ", error, ", ErrorDescription =  \"", ErrorDescription( error ), "\"" );
	MessageBox( "Ошибка при установке! GetLastError = " + error + ", ErrorDescription = \"" + ErrorDescription( error ) + "\"", 
             	 	"Ошибка установки ордера", 0x00000000 | 0x00000010 | 0x00040000 ); 
return(-1);
}

int deinit()
{
// удаление всех объектов, созданных скриптом
	ObjectDelete( "Open_Price_Line" );
	ObjectDelete( "Stop_Loss_Line" );
	ObjectDelete( "Take_Profit_Line" );
	ObjectDelete( "Expiration_Line" );

	for ( double z = 0.1; z <= 1; z += 0.1 )
	{ ObjectDelete( DoubleToStr( z, 1 )); }
	for ( z = 1; z <= 10; z ++ )
	{ ObjectDelete( DoubleToStr( z, 1 )); }
	ObjectDelete( "Lots" );
	ObjectDelete( "Lots_value" );
	ObjectDelete( ">" );
return(0);
}


Wenn jemand eine Idee hat, lassen Sie es uns wissen und wir werden darüber nachdenken.
Vielleicht können wir selbst eine GUO machen.........;)

 
Ich sehe keine Begeisterung in unseren Reihen =)
Sagen Sie mir wenigstens, was Sie von der Idee halten...




Ich vergaß zu erwähnen, dass die Gewinnmitnahmezeile gelöscht werden kann, wenn sie nicht benötigt wird.
Die Art der Order wird je nach Lage des Eröffners und des Stoploss gewählt...
 
Die Idee eines Methaquoters. Und Ihre Umsetzung ist so-o, roh :)
 
Die Idee, MessageBox für den Indikator zu verwenden, um seine Ausführung zu verlangsamen, ist hervorragend. Das hätte ich wahrscheinlich nie vermutet. Es eröffnet viele Möglichkeiten für die interaktive Auftragsvergabe. Meinen Respekt an dich, Komposter!
Was die Kritiker der Umsetzung betrifft, so weiß ich nicht, warum sie sagen, sie sei "grob".
Ich bin mir sicher, dass viele Leute Ihr Skript sehr praktisch finden werden, um ausstehende Bestellungen aufzugeben.

Für diejenigen, die gerne vom Markt aus handeln, habe ich die Version des Skripts angeboten, die zum aktuellen Marktpreis kauft, mit automatischer Berechnung der Losgröße auf der Grundlage eines im Forex Magazine platzierten Stop-Loss (siehe den Artikel "Bibliotheken von Funktionen und ihre Verwendung in Programmen", Ausgabe 52, 24. Januar 2005). Damals war es nicht möglich, den Preis, zu dem das Skript "abgesenkt" wurde, in MQL4 auf den Chart zu übertragen, so dass der Preis im Skript immer derselbe ist wie auf dem Markt.

Dasselbe Programm kann leicht geändert werden, um z. B. einen Minilot mit einem permanenten Stopp zu öffnen. Und dieser MessageBox-Trick wird es mir auf jeden Fall ermöglichen, meinem Skript weitere Funktionen hinzuzufügen.
 
Hier ist übrigens mein nächster Versuch, ein Skript für Marktkaufaufträge zu erstellen

//+------------------------------------------------------------------+
//|                                                    order_buy.mq4 |
//|                              Copyright c 2004, Alexander Ivanov. |
//|                                        mailto:alexander@indus.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright c 2004, Alexander Ivanov."
#property link      "mailto:alexander@indus.ru"

#include <WinUser32.mqh>
#include <stderror.mqh>

// Далее константа DAYS_TO_CONSIDER будет нам заменять количество
// дней, на которых мы будем искать минимум для выставления Stop loss'а
#define DAYS_TO_CONSIDER 3

//////////////////////////////////////////////////////////////////
//
// Необходимо разрешить импорт функций из библиотек. Для этого
// нужно поставив галочку 'Разрешить импортирование внешних экспертов'
// на закладке 'Советники' окна 'Настройки' вызываемого выбором пункта
// меню 'Сервис'->'Настройки'
//
//////////////////////////////////////////////////////////////////

#include <stdlib.mqh> // содержит нужную нам функцию ErrorDescription(...)

int init()
{     
   return(0);
}

int start()
{
   double DaysLowArray[];
   int nBarWithMinimum = 0;
   double dMyStopLoss = 0;  
   double dMyPrice = 0;
   double dMyTakeProfit = 0;
   double dMyLots = 0;

   if(ArrayCopySeries(DaysLowArray, MODE_LOW, Symbol(),PERIOD_D1) < DAYS_TO_CONSIDER) {
      return(PrintErrorDescription());
   }
   
   dMyPrice = Ask;
   dMyStopLoss = DaysLowArray[Lowest(Symbol(),PERIOD_D1,MODE_LOW,DAYS_TO_CONSIDER)];
   dMyTakeProfit = dMyPrice + 2*MathMax((MathAbs(Ask-Bid)/2),MathAbs(dMyPrice-dMyStopLoss));
   dMyStopLoss -= 10*Point;
   dMyLots = 0.1;

   Print("Цена = ", dMyPrice, " Стоп = ", dMyStopLoss, " Тейк профит = ", dMyTakeProfit, " Лот = ", dMyLots);

   ObjectCreate( "order_buy_Stop_Loss_Line", OBJ_HLINE, 0, 0, dMyStopLoss, 0, 0, 0, 0 );
   ObjectSet( "order_buy_Stop_Loss_Line", OBJPROP_COLOR, Red );
   ObjectSetText( "order_buy_Stop_Loss_Line", "Stop_Loss_Line", 6, "Arial", Red );

   ObjectCreate( "order_buy_Take_Profit_Line", OBJ_HLINE, 0, 0, dMyTakeProfit, 0, 0, 0, 0 );
   ObjectSet( "order_buy_Take_Profit_Line", OBJPROP_COLOR, Lime );
   ObjectSetText( "order_buy_Take_Profit_Line", "Take_Profit_Line", 6, "Arial", Lime );

   int MyError = 0;
   int Answer = MessageBoxA( 0, "\"order_buy\"\nПереместите линии на необходимые уровни, и нажмите ОК",
		     "Установка ордера", MB_OKCANCEL | MB_ICONASTERISK | MB_TOPMOST);
		     
   if ( Answer == IDOK ) {
   
      dMyStopLoss = ObjectGet( "order_buy_Stop_Loss_Line", OBJPROP_PRICE1);
      dMyTakeProfit = ObjectGet( "order_buy_Take_Profit_Line", OBJPROP_PRICE1);

      while(true) {
      
         if(OrderSend(Symbol(),OP_BUY,dMyLots,dMyPrice,3,dMyStopLoss,dMyTakeProfit,
                      "Ordered by \"order_buy\" script" ,255,0,HotPink) <= 0) {

            MyError = PrintErrorDescription();

            if((MyError == ERR_NOT_ENOUGH_MONEY) || (MyError == ERR_TRADE_DISABLED) || (MyError == ERR_INVALID_TRADE_PARAMETERS)) {
                  MessageBoxA(0,ErrorDescription(MyError), "Ошибка", MB_OK | MB_ICONERROR); 
                  break;
            } else if(MyError == ERR_INVALID_STOPS) {
                     dMyStopLoss = ObjectGet( "order_buy_Stop_Loss_Line", OBJPROP_PRICE1);
                     dMyTakeProfit = ObjectGet( "order_buy_Take_Profit_Line", OBJPROP_PRICE1);
                     Print("Цена = ", dMyPrice, " Стоп = ", dMyStopLoss, " Тейк профит = ", dMyTakeProfit, " Лот = ", dMyLots);
            } else if(MyError == ERR_PRICE_CHANGED) {
                  MessageBoxA(0,"Цена успела измениться", "Ошибка", MB_OK | MB_ICONERROR); 
                  RefreshRates();
            } else {
                  // 10 seconds wait
                  Sleep(10000);
            }
            
         } else {
            Answer = MessageBoxA( 0, "Ордер успешно исполнен\nРаспечатать ордер?",
		     "Установка ордера", MB_OKCANCEL | MB_ICONASTERISK | MB_TOPMOST);
            if(Answer == IDOK ) {
               OrderPrint();
            }
            break;
         }
      }
   }

   return(MyError);
}

int PrintErrorDescription()
{
   int error=GetLastError();
   Print("Error = ",ErrorDescription(error));
   
   return(error);         
}

int deinit()
{
   ObjectDelete( "order_buy_Stop_Loss_Line");
   ObjectDelete( "order_buy_Take_Profit_Line");

   return(0);
}
 
By the way, wenn MQL4-Entwickler "sehen" es
Ich habe irgendwie unangemessenes Verhalten von Lowest und ArrayMinimum Funktion auf EURUSD_H1 Chart
Der Punkt ist, dass es scheint, dass Minimum sollte mit dem Wert des letzten Freitag zusammenfallen, aber es passiert nicht und ich gebe zwei Tage Minimum als Minimum.

Bitte überprüfen Sie den obigen Code, bevor sich die Tabelle ändert (d.h. vor Sonntagabend).
Vielleicht mache ich etwas falsch?
 
Angefangen 05.02.05 17:14

die Umsetzung ist wirklich grob :) ich habe dieses Skript für eine Stunde und eine Hälfte geschrieben.....
Ich habe es als Idee vorgeschlagen, wenn es Ihnen gefällt, müssen Sie es verfeinern...


Horn 06.02.05 06:45

Danke für den Respekt ;) und die Gelegenheit ist wirklich meer - man muss sie nur suchen!



rty: Wenn jemand weiß, wie man eine Nachricht "über allen Fenstern" erstellt, sagen Sie es mir, plz.... es ist so unscheinbar.....
 
Ein sehr interessantes Skript, das viele Möglichkeiten der Verwendung von MQL4 zeigt
um Routinevorgänge zu automatisieren.

Hier ist eine stark korrigierte und funktionierende Version des Skripts für die visuelle Auftragserteilung:
//+------------------------------------------------------------------+
//|                                                    order_buy.mq4 |
//|                              Copyright c 2004, Alexander Ivanov. |
//|                                        mailto:alexander@indus.ru |
//+------------------------------------------------------------------+
//| Разрешите импорт функций из библиотек через:                     |
//| "Сервис -> Настройки -> Советники -> Разрешить импорт DLL"       |
//+------------------------------------------------------------------+
#property copyright "Copyright c 2004, Alexander Ivanov."
#property link      "mailto:alexander@indus.ru"

#include <WinUser32.mqh>
#include <stdlib.mqh>
#include <stderror.mqh>
//+------------------------------------------------------------------+
//| Указываем количество последних дней, на которых ищем минимум     |
//| для установки стоплосса                                          |
//+------------------------------------------------------------------+
#define DAYS_TO_CONSIDER 3
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init() { return(0); }
int deinit()
  {  
//---- просто удалим свои линии стопов
   ObjectDelete( "order_buy_Stop_Loss_Line");
   ObjectDelete( "order_buy_Take_Profit_Line");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Основная функция скрипта                                         |
//+------------------------------------------------------------------+
int start()
  {
   double DaysLowArray[];
   double dMyStopLoss = 0;  
   double dMyPrice = 0;
   double dMyTakeProfit = 0;
   double dMyLots = 0;
//---- скопируем массив дневных данных
   if(ArrayCopySeries(DaysLowArray, MODE_LOW, Symbol(),PERIOD_D1) < DAYS_TO_CONSIDER) 
     {
      return(-1);
     }
//---- расчет цен
   dMyPrice      = Ask;
   dMyStopLoss   = DaysLowArray[Lowest(Symbol(),PERIOD_D1,MODE_LOW,DAYS_TO_CONSIDER,0)];
   dMyTakeProfit = dMyPrice + 2*MathMax((MathAbs(Ask-Bid)/2),MathAbs(dMyPrice-dMyStopLoss));
   dMyStopLoss  -= 10*Point;
   dMyLots       = 0.1;
//---- выставим линии для визуального управления стопами
   ObjectCreate( "order_buy_Stop_Loss_Line", OBJ_HLINE, 0, 0, dMyStopLoss, 0, 0, 0, 0 );
   ObjectSet( "order_buy_Stop_Loss_Line", OBJPROP_COLOR, Red );
   ObjectSetText( "order_buy_Stop_Loss_Line", "Stop_Loss_Line", 6, "Arial", Red );

   ObjectCreate( "order_buy_Take_Profit_Line", OBJ_HLINE, 0, 0, dMyTakeProfit, 0, 0, 0, 0 );
   ObjectSet( "order_buy_Take_Profit_Line", OBJPROP_COLOR, Lime );
   ObjectSetText( "order_buy_Take_Profit_Line", "Take_Profit_Line", 6, "Arial", Lime );
//---- запросим подтверждение на отработку
   string quest="Вы хотите купить "+DoubleToStr(dMyLots,2)+" "+Symbol()+" по цене Ask "+
                DoubleToStr(dMyPrice,Digits)+"    \n\n"+
                "Переместите выставленные линии на необходимые уровни и нажмите ОК           \n"+
                "(красная линия - Stop Loss, зеленая - Take Profit)\n\n"+
                "Нажмите Отмена чтобы отказаться от сделки";
   if(MessageBoxA(0,quest,"Визуальная установка ордера на покупку",
                  MB_OKCANCEL | MB_ICONASTERISK | MB_TOPMOST)!=IDOK) return(-2);
//---- трейдер согласился, возьмем новые уровни стопов и обязательно проверим их!
   dMyStopLoss  =NormalizeDouble(ObjectGet( "order_buy_Stop_Loss_Line", OBJPROP_PRICE1),Digits);
   dMyTakeProfit=NormalizeDouble(ObjectGet( "order_buy_Take_Profit_Line",OBJPROP_PRICE1),Digits);
   
   if((dMyStopLoss>0 && dMyStopLoss>Ask) || (dMyTakeProfit>0 && dMyTakeProfit<Ask))
     {
      Print("Неправильно выставлены уровни Stop Loss и Take Profit!");
      MessageBoxA(0,"Неправильно выставлены уровни Stop Loss и Take Profit!         \n"+
                    "Операция отменена\n\n",
                    "Визуальная установка ордера на покупку",MB_OK | MB_ICONSTOP | MB_TOPMOST);
      return(-3);
     }
//---- выведем в лог сообщение об заявке
   Print("buy ",DoubleToStr(dMyLots,2)," ",Symbol()," at ",DoubleToStr(dMyPrice,Digits),
         "sl ",DoubleToStr(dMyStopLoss,Digits)," tp ",DoubleToStr(dMyTakeProfit,Digits));
//---- пробуем послать команду
   int ticket=OrderSend(Symbol(),OP_BUY,dMyLots,dMyPrice,3,dMyStopLoss,dMyTakeProfit,
                        "Ordered by \"order_buy\" script" ,255,0,HotPink);
   if(ticket>0) // все отлично - заявка прошла
     {
      //---- сразу же выведем в лог подтверждение
      Print("#",ticket," buy ",DoubleToStr(dMyLots,2)," ",Symbol()," at ",
            DoubleToStr(dMyPrice,Digits)," is done");
      //---- покажем окно 
      if(MessageBoxA(0,"Ордер успешно исполнен     \nРаспечатать его?",
		     "Визуальная установка ордера на покупку", MB_YESNO | MB_ICONASTERISK | MB_TOPMOST)==IDYES)
		  {
         OrderPrint();
        }
      //---- все ок, выходим
      return(0);
     }
//---- тут все плохо - выведем в лог сообщение
   int err=GetLastError();
   Print("buy ",DoubleToStr(dMyLots,2)," ",Symbol()," at ",
         DoubleToStr(dMyPrice,Digits)," failed [",ErrorDescription(err),"]");
//----покажем окно
   MessageBoxA(0,ErrorDescription(err), 
               "Ошибка визуальной установки ордера", MB_OK | MB_ICONERROR | MB_TOPMOST); 
   return(-4);
  }
//+------------------------------------------------------------------+



Was ist repariert:
1) alle Parameter in Lowest(Symbol(),PERIOD_D1,MODE_LOW,DAYS_TO_CONSIDER,0) sind angegeben,
Es sieht so aus, als ob der Fehler von Horn darin bestand, dass der Standardwert nicht gesetzt wurde. Wir werden prüfen, wie die Funktion Lowest aufgerufen wird und funktioniert
2) NormalizeDouble - dies ist sehr wichtig!
3) Vorabprüfung der Stop-Levels auf Korrektheit, bevor sie an Aufträge gesendet werden
4) der Händler erhält mehr Informationen in den Fenstern (in der ersten Version des Skripts war es sehr schwierig zu verstehen, was das Skript tut, ohne den Code zu lesen)
5) detaillierte und zeitnahe Ausgabe von Protokollen
6) Kommentare hinzugefügt
7) Der zyklische Versuch, eine Anfrage zu senden, wurde entfernt - er ist sehr wichtig.

 
Ich möchte auf die Wiederherstellung nach Fehlern bei der Versendung von Anfragen und Wiederholungen der Versendung eingehen.

Leider ist die Verwendung von Algorithmen mit Schleifen wie :

while(true)
  {
   if(OrderSend(....)<=0)
     {
      // проверимся
      Sleep(10000);
     }
  }


ist absolut kontraindiziert, ja sogar verboten.

Lassen Sie mich versuchen, den Grund dafür grob zu erklären:
Wenn Sie sich einen Fehler einfangen, werden Sie ohnehin nicht in der Lage sein, alle Arten von Fehlern selbst zu behandeln. Es ist zu wahrscheinlich, dass Sie fünf oder so populäre Fehler erkennen und etwas dagegen tun, aber für den Rest immer noch _Wiederholungen_ durchführen. Und Sleep(10000) wird nicht als Ausrede für das Skript dienen, falsche Anfragen zu senden. Die Broker werden das Konto einfach sperren.

Wie sollte ein Autor eines Expert Advisors vorgehen:
1) Eine Order vorbereiten
a) Eingabeparameter des Expert Advisors auf Korrektheit prüfen
b) Selbstständig alle Preise und Volumina normalisieren (ja, auch die!) der Anfrage
c) unabhängig alle Felder der Anfrage auf dumme Fehler überprüfen, zumindest so, dass alle Preise mehr oder weniger korrekt sind
d) vor dem Absenden der Anfrage die Details der Anfrage im Protokoll anzeigen

2) den Zyklus des Absendens der Anfrage organisieren
a) der Zyklus muss endlich sein, zum Beispiel nicht mehr als 3 mal for(i=0;i<3;i++) und auf keinen Fall while(true)
b) wenn die Anfrage durchgeht, dann ist alles einfach Ausgabe in das Protokoll, Benachrichtigung des Händlers und Beendigung
c) ein Fehler aufgetreten ist, dann Punkt 3

3) Umgang mit Fehlern bei der Auftragsübermittlung
a) die Situationen prüfen, in denen eine Wiederherstellung möglich ist, und bei allen anderen Fehlern so schnell wie möglich eine Beendigung mit Benachrichtigung vornehmen
b) so wenige Fälle der Wiederherstellung wie möglich auswählen, nur die wichtigsten und potenziell wiederherstellbaren
c) keine Versuche, Ihre wiederholte Bestellung "durchzudrücken", weil Sie denken, "vielleicht wird sie doch noch angenommen?"
d) obligatorische Schlupfabrechnung, mindestens 1 Punkt (seien Sie ehrlich zu sich selbst, Schlupf ist im realen Handel unvermeidlich)

Einer der wichtigsten Punkte bei der Verwendung der Auftragsausführung von MQL4 - Minimierung der Anzahl der Aufträge.
Dies wirkt sich unmittelbar auf die Qualität Ihrer Dienstleistung aus.

Auch für Experten, die für die Öffentlichkeit schreiben, müssen Sie den narrensichersten Code schreiben.
Und auch für den internen Gebrauch.

 
hhy: wenn jemand weiß, wie man eine Nachricht "über allen Fenstern" anzeigt, bitte.... es ist so unintuitiv.....

Ich habe MB_TOPMOST verwendet, versuchen Sie es, es scheint für mich zu funktionieren.
 
Wo soll ich ihn schreiben?