Скажите хоть, как вам идея...
Забыл сказать: линию тейк профита можно удалять, если он не нужен.
Тип ордера выбирается в зависимости от расположения опенпрайс и стоплосс..
Что касается личностей ругающих реализацию, то не совсем понятно чем они руководствуются говоря, что реализация "сырая".
Я уверен, что многим будет очень удобно работать с Вашим скриптом для выставления отложенных ордеров.
А для тех, кто любит входить с рынка, я предлагал уже на страницах Forex Magazine (статья "Библиотеки функций и их использование в программах" 52-ой номер за 24 января 2005 года) вариант скрипта, покупающего по текущей рыночной цене с автоматическим посчётом размера лота на основании выставленного стоп лосса. Тогда в MQL4 ещё небыло возможности получить цену, на которой скрипт "опустился" на график, и поэтому цена в нём всегда та, которая на рынке.
Эту же программу можно легко модифицировать, чтобы она открывалась, допустим, одним минилотом с постоянным стопом. А вот этот финт с 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);
}
У меня как-то неадекватно ведёт себя функция Lowest и ArrayMinimum на графике EURUSD_H1
Дело в том, что судя по всему минимум должен совпасть с последним пятничным значением, но этого не происходит и у меня в качестве минимума возвращается двухдневный минимум.
Код выше, пока график не изменился проверте плиз (т.е. до воскресной ночи).
Может быть я что-то делаю не так?
реализация действительно сырая :) я этот скрипт писАл часа полтора.....
я его предложил как идею, если понравится - необходимо дорабатывать...
Horn 06.02.05 06:45
спасибо за респект ;) а возможностей действительно море - надо искать!
зы: если кто знает, как сделать месседж "поверх всех окон", скажите, плз.... а то так неудубно.....
для автоматизации рутинных операций.
Вот серьезно исправленный и рабочий вариант скрипта для визуальной постановки ордеров:
//+------------------------------------------------------------------+
//| 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) этап подготовки заявки
а) проверить входные параметры эксперта на корректность
б) самостоятельно нормализовать все цены и объемы(да, их тоже!) заявки
в) самостоятельно проверить все поля заявки на глупейшие ошибки, как минимум - чтобы все цены были более-менее корректны
г) перед отсылкой заявки вывести детали заявки в лог
2) организация цикла посылки заявки
а) цикл должен быть конечным, например не более 3х раз for(i=0;i<3;i++) и ни в коем случае не while(true)
б) если заявка прошла, то все легко: выводим в лог, уведомляем трейдера и выходим
в) словили ошибку, то пункт 3
3) обработка ошибок отсылки заявок
а) проверяем те ситуации, в которых мы можем восстановиться, а при любой другой ошибке - выходим с уведомлениями как можно скорее
б) случаев восстановления выбираем как можно меньше, только самые главные и потенциально восстановимые
в) никаких попыток "проталкивания" своей повторной заявки с мыслью "может все-таки примут?"
г) обязательный учет слиппажа, как минимум 1 пункт (будьте честны с собой, слиппаж неизбежен в реальной торговле)
Одним из главных моментов в использовании исполнения заявок из MQL4 - минимизируйте количество заявок.
Это напрямую влияет на качество вашего обслуживания.
Также для экспертов, пишущихся на публику, необходимо писать максимально защищенный дуракоустойчивый код.
Да и для внутреннего использования - тоже.
я использовал MB_TOPMOST, попробуй, у меня вроде бы получилось.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Вчера вот вспомнил, подумал - а почему бы не реализовать?
редакция от 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); }Если у кого какие идеи - говорите, будем думать.
Может, своими силами сделаем ГУО.........;)