GUO的粉丝们

 
有一个非常嘈杂的话题,就是图形化的订单管理......
昨天我想起来了,就想--为什么不实施呢?

19.03.2005
使用前请阅读说明书=)

//+------------------------------------------------------------------+
//|                                           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);
}


如果谁有什么想法,请告诉我们,我们会考虑的。
也许我们可以自己做一个GUO.........;)

 
我在我们的队伍中没有看到任何热情=)
至少告诉我你对这个想法的看法...




忘了说:如果不需要的话,可以删除止盈线
订单类型的选择取决于开仓和止损的位置...
 
一个元帅的想法。而你的执行力一般,生搬硬套 :)
 
为指标使用MessageBox 来减慢其执行速度的想法非常好。我可能永远不会猜到这一点。它为交互式订单安排提供了许多可能性。我对你的尊重,Komposter!
至于那些批评实施的人,我不知道他们为什么说它是 "粗糙的"。
我相信很多人都会发现你的脚本在使用时非常方便,可以用来下挂单。

对于那些喜欢从市场上交易的人,我提供了脚本的版本,它以当前的市场价格买入,并根据外汇杂志上的止损点自动计算手数(见文章 "函数库和它们在程序中的使用",第52期,2005年1月24日)。当时,不可能在MQL4中把脚本 "降低 "的价格拿到图表上,所以脚本中的价格总是与市场上的价格相同。

同样的程序可以很容易地被修改,比如说,打开一个带有永久停顿的minilot。这个MessageBox技巧肯定也能让我在我的脚本中添加功能。
 
顺便说一下,这是我对市场买入订单 脚本的下一次尝试

//+------------------------------------------------------------------+
//|                                                    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);
}
 
顺便说一下,如果MQL4开发人员 "看到 "
,我在EURUSD_H1图表 上的Lowest和ArrayMinimum函数的行为多少有些不妥
。重点是,显然最低值应该与上周五的值重合,但它没有发生,我得到一个两天的最低值。

上面的代码,在图表变化之前请检查(即在周日晚上之前)。
也许我做错了什么?
 
开始 05.02.05 17:14

实现起来真的很粗糙:)我写这个脚本已经有一个半小时了.....
我建议它作为一个想法,如果你喜欢它,你需要完善它......


喇叭 06.02.05 06:45

谢谢你的尊重;) 机会真的是海阔天空--你必须寻找它!



rty: 如果有人知道如何使信息 "在所有窗口的顶部",请告诉我,plez....它是如此unubly.....
 
一个非常有趣的脚本,显示了使用MQL4的很多可能性
以实现常规操作的自动化。

这里有一个经过认真修正的工作版本的脚本,用于可视化的订单安排
//+------------------------------------------------------------------+
//|                                                    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);
  }
//+------------------------------------------------------------------+



修复的内容。
1)指定Lowest(Symbol(),PERIOD_D1,MODE_LOW,DAYS_TO_CONSIDER,0)中的所有参数。
看起来Horn的错误是没有设置默认值。我们将检查Lowest函数是如何被调用和工作的。
2) NormalizeDouble - 这是非常重要的!
3) 发送给订单前,预先检查止损位的正确性
4) 交易者在窗口中获得更多的信息(在第一版脚本中,如果不看代码,就很难理解脚本的作用)。
5)详细而及时地输出日志
6)添加评论
7)发送请求的循环尝试已被删除--它是非常重要的

 
我想阐述一下从发送请求和重复发送的错误中恢复的问题。

不幸的是,使用循环的算法,如:

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


是绝对禁忌的,甚至是禁止的。让我试着粗略地解释一下原因: 如果你捕捉到一个错误,无论如何你都不可能自己处理所有的错误类型。太有可能的是,你会抓住五个左右的流行错误,并对其进行处理,但对所有其他的错误仍然_重复操作_。而且Sleep(10000)不会成为脚本发送不正确请求的借口。经纪人会简单地封锁该账户。专家顾问作者应该如何进行: 1) 准备一个订单 a) 检查






专家顾问的输入参数 是否正确 b) 独立地将所有价格和成交量规范化(是的,这些也是!)的请求 c) 独立检查请求的所有字段是否有愚蠢的错误,至少--使所有价格或多或少正确 d) 在发送请求之前,在日志中显示请求的细节 2) 组织请求发送的周期 a) 周期必须是有限的,例如不超过3次





for(i=0;i<3;i++),并且在任何情况下都不超过while(true)
b) 如果请求被通过,那么一切就容易了输出到日志中,通知交易者并退出 c) 抓住一个错误,然后第3点 3) 处理订单发送错误 a) 检查那些我们可以恢复的情况,对于任何其他错误--尽快通知退出 b) 恢复的情况选择尽可能少的,只有最重要和可能恢复的 c) 没有试图 "推过 "你的重复订单,认为 "也许他们终究会接受?" d) 强制性滑点核算,至少1分(对自己诚实,滑点在真实交易中是不可避免的) 使用MQL4的订单执行的要点之一--尽量减少订单数量。 这直接影响到你的服务质量。另外,对于为公众写作的专家来说,你需要写出最万无一失的代码。而且也是为了内部使用。













 
hhy: 如果有人知道如何使信息 "在所有窗口的顶部",请告诉我,....它是如此的不直观.....

我使用了MB_TOPMOST,试试吧,它似乎对我有用。
 
我应该把它写在哪里?