Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Свободные средства 2 страница




Параметры:

ticket - уникальный порядковый номер ордера.

lots - количество лотов для закрытия. Допускается указать значение меньшее, чем имеющееся количество лотов ордера. В этом случае (при успешном исполнении торгового приказа) ордер будет закрыт частично.

price - цена закрытия. Устанавливается в соответствии с требованиями и ограничениями, принятыми для проведения торговых операций (см. Характеристики ордеров и Приложение 3). Если заявленной цены для закрытия рыночного ордера не было в ценовом потоке или она сильно устарела, то такой торговый приказ отклоняется; если же цена устарела, но присутствует в ценовом потоке и при этом отклонение от текущей цены находится в пределах значения slippage, то такой торговый приказ будет принят клиентским терминалом и отправлен на торговый сервер.

slippage - максимально допустимое отклонение заявленной цены закрытия ордера от рыночной цены (пунктов).

Color - цвет стрелки закрытия на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелка на графике не отображается.

 

Если в программе имеются сведения о типе ордера, который необходимо закрыть, о его уникальном номере, а также известно количество лотов, предназначенных для закрытия, то закрыть рыночный ордер очень просто. Для этого в коде программы необходимо использовать обращение к функции OrderClose() с заданными параметрами. Например, если уникальный номер ордера Buy 12345 и необходимо закрыть 0.5 лотов, то обращение к функции закрытия ордера может выглядеть так:

OrderClose(12345, 0.5, Bid, 2);

Чтобы принять решение о том, какие ордера и в какой последовательности необходимо закрывать, требуется иметь сведения обо всех ордерах, открытых на текущий момент. В MQL4 имеется ряд функций, с помощью которых можно получить различные сведения, характеризующие любой ордер. Например, функция OrderOpenPrice() возвращает значение цены открытия ордера (или заявленной цены для отложенных ордеров), функция OrderLots() возвращает количество лотов, функция OrderType() возвращает тип ордера и т.д. Все функции, возвращающие значение какой-либо характеристики ордера, при исполнении обращаются к тому ордеру, который был выбран с помощью функции OrderSelect().

Функция OrderSelect()

 

Чтобы получить параметры любого из ордеров (рыночных или отложенных, закрытых или удалённых) его необходимо предварительно выбрать с помощью функции OrderSelect().

bool OrderSelect(int index, int select, int pool=MODE_TRADES)

OrderSelect -функция выбирает ордер для дальнейшей работы с ним. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции.

Параметры:

index - позиция ордера или номер ордера в зависимости от второго параметра.

select - флаг способа выбора. Параметр select может принимать одно из двух значений:

SELECT_BY_POS - в параметре index передается порядковый номер ордера в списке (нумерация начинается с 0),

SELECT_BY_TICKET - в параметре index передается номер тикета (уникальный номер ордера).

pool - источник данных для выбора. Параметр pool используется, когда параметр select равен SELECT_BY_POS. Параметр pool игнорируется, если ордер выбирается по номеру тикета (SELECT_BY_TICKET). Параметр pool может принимать одно из двух значений:

MODE_TRADES (по умолчанию) - ордер выбирается среди открытых и отложенных ордеров, т.е. среди ордеров, отображаемых в Терминале на закладке Торговля;

MODE_HISTORY - ордер выбирается среди закрытых и удаленных ордеров, т.е. среди тех, которые указаны в Терминале на закладке История счёта. При этом имеет значение глубина истории, заданная пользователем в терминале для показа закрытых и удаленных ордеров.

 

Для того чтобы продемонстрировать порядок использования торговых функций при закрытии рыночных ордеров, решим задачу:

Задача 28. Составить скрипт, закрывающий один из имеющихся рыночных ордеров. В результате исполнения скрипта должен быть закрыт тот ордер, который находится ближе других к месту прикрепления скрипта мышью в окно финансового инструмента.

Предположим, что в терминале имеется три рыночных ордера, открытых по финансовому инструменту Eur/Usd и один отложенный ордер, открытый по Usd/Chf:


Рис. 90. Отражение в окне Терминала нескольких ордеров, открытых по разным финансовым инструментам.

Нам необходимо написать такой скрипт, чтобы можно было перетянуть его мышкой из Навигатора в окно финансового инструмента, в результате чего был бы закрыт один из рыночных ордеров, а именно тот, к которому оказался ближе курсор (в момент, когда пользователь отпустил кнопку мыши). На рис. 91 показан вариант, при котором курсор находится ближе всего к ордеру Sell 4372889, - он и должен быть закрыт в результате исполнения скрипта.


Рис. 91. Использование скрипта closeorder.mq4 для закрытия выбранного ордера.

Для решения задачи из всех ордеров необходимо выбрать ордера, открытые по финансовому инструменту (используя функцию OrderSymbol()), в окно которого брошен скрипт. Затем нужно определить цены открытия всех выбранных рыночных ордеров (т.е. необходимо исполнить функцию OrderOpenPrice() последовательно для каждого ордера). Зная цены открытия ордеров, легко выбрать из них один, соответствующий условию задачи. Чтобы указать правильные значения параметров в функции OrderClose(), понадобятся ещё и другие сведения о выбранном ордере: количество лотов (определяется функцией OrderLots()) и уникальный номер ордера (определяется функцией OrderTicket()). Кроме того, чтобы правильно определить ту или иную цену двухсторонней котировки, понадобится знать тип ордера (определяется с помощью функции OrderType()).

Рассмотрим, какие параметры требуется указать в функции OrderSelect() для того, чтобы получить указанные выше характеристики рыночных ордеров.

Прежде всего, необходимо определиться со способом выбора ордеров. В данной задаче выбор способа диктуется самой постановкой задачи: полагается, что в момент запуска скрипта на исполнение в программе нет сведений о номерах ордеров, т.е. программа должна содержать блок, в котором номера ордеров определяются. Это значит, что необходимо последовательно по порядку опросить все ордера, отражённые в Терминале (рис. 64.1), поэтому требуется использование параметра SELECT_BY_POS.

Источник для выбора ордеров также очевиден. Для решения задачи нет необходимости анализировать закрытые и удалённые ордера. В данном случае нас интересуют только рыночные ордера, поэтому будем искать их, используя в функции OrderSelect() параметр MODE_TRADES. Для параметра pool в заголовке функции указано умолчательное значение MODE_TRADES, поэтому его можно опустить.

Вот так может быть построен блок, в котором анализируются рыночные и отложенные ордера:

for (int i=1; i<=OrdersTotal(); i++) //Цикл по всем ордерам,..

{ //отражённым в терминале

if(OrderSelect(i-1,SELECT_BY_POS)==true)//Если есть следующий

{

// Здесь должен выполняться..

//..анализ характеристик ордеров

}

} //Конец тела цикла

В заголовке оператора цикла указано начальное значение i=1, а условием окончания цикла - выражение i<=OrdersTotal(). Функция OrdersTotal() возвращает общее количество рыночных и отложенных ордеров, т.е. тех ордеров, которые отражаются в Терминале на закладке Торговля. Поэтому в цикле будет столько итераций, сколько ордеров присутствует в торговле.

На каждой итерации, при вычислении условия в операторе if, будет исполнена функция OrderSelect(i-1,SELECT_BY_POS). Здесь необходимо обратить внимание на следующий важный момент:

Исчисление позиций ордеров в списке рыночных и отложенных ордеров начинается с нуля.

Это значит, что первый по порядку ордер (рис. 90) располагается в нулевой позиции, позиция второго ордера имеет значение 1, третьего ордера - значение 2 и т.д. Поэтому в вызове функции OrderSelect() указано значение индекса i-1. Таким образом, для всех выбираемых ордеров этот индекс будет на 1 меньше, чем значение переменной i (совпадающее с номером очередной итерации).

Функция OrderSelect() возвращает true в случае, если выбор ордера выполнен удачно. Под этим понимается, что возможен вариант, при котором выбор ордера может закончиться неудачей. Это может произойти в случае, если за время обработки ордеров количество ордеров изменилось. При программировании на MQL4 нужно хорошо помнить, что прикладная программа будет работать в режиме реального времени, и пока в ней выполняется обработка каких-то параметров, значение этих параметров может измениться. Например, может измениться количество рыночных ордеров, причём это может произойти как в результате открытия/закрытия ордеров, так и в результате преобразования отложенных ордеров в рыночные. Поэтому при программировании обработки ордеров необходимо придерживаться правила: обработка ордеров должна быть выполнена как можно быстрее, а программный блок, ответственный за эту обработку, по возможности не должен содержать лишних программных строк.

Согласно коду, представленному на рис. 64.3, в заголовке оператора if анализируется факт наличия следующего ордера в списке ордеров на момент его выбора. Если следующий ордер есть, то управление передаётся внутрь тела оператора if для обработки параметров ордера. Нужно заметить, что такая конструкция тоже не спасает от возможного конфликта, т.к. ордер может пропасть (быть закрытым) в процессе обработки его параметров. Однако такое решение оказывается наиболее эффективным в случае, если на момент выбора ордера его уже нет. В теле оператора if выполняется анализ параметров выбранного ордера. При исполнении, например, функций OrderOpenPrice(), OrderTicket(), OrderType() и других подобных каждая из них будет возвращать значение некоторой характеристики ордера, выбранного в результате исполнения функции OrderSelect().

Все предыдущие рассуждения использовались при составлении программы для решения Задачи 28.

Пример простого скрипта, предназначенного для закрытия рыночного ордера, цена открытия которого находится ближе к месту прикрепления скрипта, чем цены открытия других ордеров (closeorder.mq4).

 

//--------------------------------------------------------------------

// closeorder.mq4

// Предназначен для использования в качестве примера в учебнике MQL4.

//--------------------------------------------------------------- 1 --

int start() // Спец.функция start

{

string Symb=Symbol(); // Финанс. инструмент

double Dist=1000000.0; // Предустановка

int Real_Order=-1; // Пока рыночных нет

double Win_Price=WindowPriceOnDropped(); // Здесь брошен скрипт

//--------------------------------------------------------------- 2 --

for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер

{

if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий

{ // Анализ ордеров:

//------------------------------------------------------ 3 --

if (OrderSymbol()!= Symb) continue; // Не наш фин.инструм.

int Tip=OrderType(); // Тип ордера

if (Tip>1) continue; // Отложенный ордер

//------------------------------------------------------ 4 --

double Price=OrderOpenPrice(); // Цена ордера

if (NormalizeDouble(MathAbs(Price-Win_Price),Digits)< //Выбор

NormalizeDouble(Dist,Digits)) // самого близкого орд

{

Dist=MathAbs(Price-Win_Price); // Новое значение

Real_Order=Tip; // Есть рыночный ордер

int Ticket=OrderTicket(); // Номер ордера

double Lot=OrderLots(); // Количество лотов

}

//------------------------------------------------------ 5 --

} //Конец анализа ордера

} //Конец перебора орд.

//--------------------------------------------------------------- 6 --

while(true) // Цикл закрытия орд.

{

if (Real_Order==-1) // Если рыночных нет

{

Alert("По ",Symb," рыночных ордеров нет");

break; // Выход из цикла закр

}

//--------------------------------------------------------- 7 --

switch(Real_Order) // По типу ордера

{

case 0: double Price_Cls=Bid; // Ордер Buy

string Text="Buy "; // Текст для Buy

break; // Из switch

case 1: Price_Cls=Ask; // Ордер Sell

Text="Sell "; // Текст для Sell

}

Alert("Попытка закрыть ",Text," ",Ticket,". Ожидание ответа..");

bool Ans=OrderClose(Ticket,Lot,Price_Cls,2);// Закрытие ордера

//--------------------------------------------------------- 8 --

if (Ans==true) // Получилось:)

{

Alert ("Закрыт ордер ",Text," ",Ticket);

break; // Выход из цикла закр

}

//--------------------------------------------------------- 9 --

int Error=GetLastError(); // Не получилось:(

switch(Error) // Преодолимые ошибки

{

case 135:Alert("Цена изменилась. Пробуем ещё раз..");

RefreshRates(); // Обновим данные

continue; // На след. итерацию

case 136:Alert("Нет цен. Ждём новый тик..");

while(RefreshRates()==false) // До нового тика

Sleep(1); // Задержка в цикле

continue; // На след. итерацию

case 146:Alert("Подсистема торговли занята. Пробуем ещё..");

Sleep(500); // Простое решение

RefreshRates(); // Обновим данные

continue; // На след. итерацию

}

switch(Error) // Критические ошибки

{

case 2: Alert("Общая ошибка.");

break; // Выход из switch

case 5: Alert("Старая версия клиентского терминала.");

break; // Выход из switch

case 64: Alert("Счет заблокирован.");

break; // Выход из switch

case 133:Alert("Торговля запрещена");

break; // Выход из switch

default: Alert("Возникла ошибка ",Error);//Другие варианты

}

break; // Выход из цикла закр

}

//-------------------------------------------------------------- 10 --

Alert ("Скрипт закончил работу -----------------------------");

return; // Выход из start()

}

//-------------------------------------------------------------- 11 --

Весь код программы closeorder.mq4 сосредоточен в специальной функции start(). В блоке 1-2 инициализируются некоторые переменные. Переменная Dist - дистанция от места, где был брошен скрипт, до ближайшего ордера. Переменная Real_Order - флаг, отражающий факт наличия в терминале хотя бы одного рыночного ордера (неотрицательное значение). Переменная Win_Price - цена, на которой пользователь прикрепил скрипт в окно финансового инструмента. В блоке 2-6 выполняется анализ ордеров: один из имеющихся ордеров назначается к закрытию. Блок 6-10 представляет блок закрытия ордера и обработку ошибок, которые могут возникнуть при исполнении торговой операции.

С момента, когда пользователь присоединил скрипт в окно финансового инструмента, вычисляются значения переменных в блоке 1-2, в том числе переменная Win_Price получает значение цены, на уровне которой пользователь прикрепил скрипт. Теперь необходимо найти ордер (и определить его характеристики), который расположен ближе других к этому месту.

В цикле for (блок 2-6) выполняется перебор ордеров. В блоке 2-3 программа определяет, есть ли в очередной строке Терминала ордер, и если он есть, то управление передаётся в тело оператора if для получения и анализа характеристик этого ордера. В блоке 3-4 отсортировываются ордера, открытые не по тому финансовому инструменту, где исполняется программа. В нашем случае - это ордер 4372930, открытый по Usd/Chf. Функция OrderSymbol() возвращает название финансового инструмента выбранного ордера. Если это название не совпадает с названием финансового инструмента, в котором исполняется программа, то текущая итерация прерывается, тем самым предотвращая обработку ордера, открытого по другому финансовому инструменту. Если же исследуемый ордер оказался открытым по "нашему" финансовому инструменту, то выполняется ещё одна проверка. С помощью функции OrderType() определяется тип ордера (см. Типы торговых операций). Если тип ордера оказывается больше 1, это означает, что исследуемый ордер является отложенным. В этом случае также прерывается текущая итерация - отложенные ордера в данном случае нас не интересуют. В нашем примере такой ордер есть, но он к тому же открыт по другому финансовому инструменту, поэтому ранее уже отсортирован. Все ордера, которые благополучно проходят проверку в блоке 3-4, являются рыночными.

Блок 4-5 предназначен для того, чтобы из всех (ранее прошедших проверку) рыночных ордеров выбрать один, а именно тот, который находится ближе всего к ранее определённой цене (значению переменной Win_Price). От пользователя не требуется точного попадания курсором мыши в линию ордера. Выбор производится в пользу того ордера, который оказался ближе других к курсору в момент запуска скрипта на исполнение. С помощью функции OrderOpenPrice() определяется цена открытия обрабатываемого ордера. Если абсолютное значение дистанции между ценой ордера и ценой курсора меньше, чем эта же дистанция для предыдущего ордера, то выбор производится в пользу текущего (абсолютная величина дистанции нужна для того, чтобы исключить влияние положения курсора - выше или ниже линии ордера). В этом случае на текущей итерации цикла for этот ордер запоминается как первый претендент на закрытие. Для такого ордера в конце блока 4-5 вычисляется номер тикета (индивидуальный номер ордера) и количество лотов. В данном примере (рис. 90) общее количество ордеров - четыре (три рыночных и один отложенный), поэтому в цикле for будет выполнено четыре итерации, в результате чего будет определена вся необходимая информация для закрытия одного выбранного ордера.

Далее управление в исполняемой программе будет передано оператору цикла while (блок 6-10). В блоке 6-7 выполняется проверка наличия найденных рыночных ордеров. Если в блоке 2-4 не было обнаружено ни одного рыночного ордера (а это в общем случае вполне возможно), то значение флага Real_Order остаётся равным -1, что означает отсутствие рыночных ордеров. Если при проверке в блоке 6-7 выявлено отсутствие рыночных ордеров, то выполнение цикла while прерывается и программа заканчивает работу. Если же значение переменной Real_Order оказывается равным 0 или 1, то это значит, что рыночный ордер к закрытию ранее определён и его надо закрыть.

В блоке 7-8, в зависимости от типа ордера вычисляется цена закрытия - для ордеров Buy это значение Bid, а для ордеров Sell - Ask (см. Требования и ограничения торговых операций).

В блоке 7-8 также вычисляется значения вспомогательной переменной Text. Собственно торговый приказ на закрытие ордера формируется в функции OrderClose () в следующей строке:

bool Ans=OrderClose(Ticket,Lot,Price_Cls,2);// Закрытие ордера

Торговая функция OrderClose() возвращает true при успешном исполнении торговой операции и false при неудачном. Если торговый приказ успешно исполнен на сервере, то переменной Ans (ответ) будет присвоено значение true. В этом случае, исполняя блок 8-9, программа сообщит пользователю об успешном закрытии ордера, после чего исполнение оператора цикла while будет прекращено, и программа закончит работу. В противном случае управление будет передано в блок 9-10 для анализа ошибки, возвращённой в программу клиентским терминалом.

В начале блока 9-10 вычисляется код ошибки. В дальнейшем, в зависимости от кода ошибки, выполняется либо выход из программы либо повторное исполнение торговой операции. В первом операторе switch обрабатываются ошибки, которые по смыслу являются преодолимыми, т.е, если можно считать, что при выполнении торговой операции возникли временные затруднения. Для каждой из таких ошибок выполняются необходимые действия, после чего текущая итерация прерывается, и исполнение цикла while начинается снова. (Обратите внимание, в данном примере при обработке преодолимых ошибок используется оператор switch, выход из которого осуществляется в результате исполнения оператора continue, который сам по себе не предназначен для передачи управления за пределы switch. Такая конструкция оказывается рабочей только благодаря тому, что оператор switch является содержимым внешнего оператора цикла while, а оператор continue прерывает текущую итерацию, передавая управление в заголовок while).

Если код ошибки не обрабатывается в первом операторе switch, то эта ошибка считается непреодолимой. В этом случае управление передаётся второму оператору switch, смысл исполнения которого сводится к информированию пользователя о возникновении той или иной критической ошибки. В дальнейшем исполняется оператор break, прерывающий исполнение цикла while. Выход из цикла while по любой причине приводит к передаче управления в блок 9-10, в котором выдаётся сообщение о завершении работы программы. Оператор return прекращает исполнение специальной функции start() и программа завершает работу.

Практический результат, полученный после запуска скрипта в заданных условиях (см. рис. 90 и 91), представлен ниже. Торговая операция была успешно выполнена на сервере.


Рис. 92. Сообщения, полученные в результате успешного исполнения скрипта closeorder.mq4.

В результате закрытия одного из ордеров в окне финансового инструмента Eur/Usd осталось два ордера.


Рис. 93. Исполнение скрипта closeorder.mq4 привело к закрытию одного из ордеров

Закрытие ордера также нашло своё отражение и в окне Терминала:


Рис. 94. После исполнение скрипта closeorder.mq4 в Терминале отражаются два рыночных ордера.

В последующих событиях с помощью представленного скрипта были закрыты и два других рыночных ордера.

 

Удаление отложенных ордеров

 

Торговые приказы для удаления отложенных ордеров формируются с помощью функции OrderDelete().

Функция OrderDelete()

bool OrderDelete(int ticket, color arrow_color=CLR_NONE)

Функция удаляет ранее установленный отложенный ордер. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции.

Параметры:

ticket - уникальный порядковый номер ордера.

arrow_color - цвет стрелки на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелка на графике не отображаются.

Легко заметить, что в функции OrderDelete() нет указания на количество лотов в удаляемом ордере и цену закрытия.

Удаление ордера происходит независимо от рыночных цен. Невозможно также частичное удаление ордера. Уменьшение количества лотов отложенного ордера можно осуществить в два этапа - сначала удалить имеющийся ордер, а потом выставить новый отложенный ордер на уменьшенное (любое) количество лотов.

Алгоритм построения программы для удаления отложенного ордера может быть полностью аналогичен алгоритму программы закрытия рыночного ордера. Небольшая разница состоит лишь в том, что для удаления отложенного ордера не требуется цена закрытия, поэтому в следующей программе отсутствует блок, в котором обновляются рыночные цены.

Пример простого скрипта, предназначенного для удаления одного отложенного ордера, заявленная цена которого находится ближе к месту прикрепления скрипта, чем цены других отложенных ордеров (deleteorder.mq4).

 

//--------------------------------------------------------------------

// deleteorder.mq4

// Предназначен для использования в качестве примера в учебнике MQL4.

//--------------------------------------------------------------- 1 --

int start() // Спец.функция start

{

string Symb=Symbol(); // Финанс. инструмент

double Dist=1000000.0; // Предустановка

int Limit_Stop=-1; // Пока отложенных нет

double Win_Price=WindowPriceOnDropped(); // Здесь брошен скрипт

//--------------------------------------------------------------- 2 --

for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер

{

if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий

{ // Анализ ордеров:

//------------------------------------------------------ 3 --

if (OrderSymbol()!= Symb) continue; // Не наш фин.инструм.

int Tip=OrderType(); // Тип ордера

if (Tip<2) continue; // Рыночный ордер

//------------------------------------------------------ 4 --

double Price=OrderOpenPrice(); // Цена ордера

if (NormalizeDouble(MathAbs(Price-Win_Price),Digits)< //Выбор

NormalizeDouble(Dist,Digits)) // самого близкого орд

{

Dist=MathAbs(Price-Win_Price); // Новое значение

Limit_Stop=Tip; // Есть отложен. ордер

int Ticket=OrderTicket(); // Номер ордера

} // Конец if

} //Конец анализа ордера

} // Конец перебора орд.

//--------------------------------------------------------------- 5 --

switch(Limit_Stop) // По типу ордера

{

case 2: string Text= "BuyLimit "; // Текст для BuyLimit

break; // Выход из switch

case 3: Text= "SellLimit "; // Текст для SellLimit

break; // Выход из switch

case 4: Text= "BuyStopt "; // Текст для BuyStopt

break; // Выход из switch

case 5: Text= "SellStop "; // Текст для SellStop

break; // Выход из switch

}

//--------------------------------------------------------------- 6 --

while(true) // Цикл закрытия орд.

{

if (Limit_Stop==-1) // Если отложенных нет

{

Alert("По ",Symb," отложенных ордеров нет");

break; // Выход из цикла закр

}

//--------------------------------------------------------- 7 --

Alert("Попытка удалить ",Text," ",Ticket,". Ожидание ответа..");

bool Ans=OrderDelete(Ticket); // Удаление ордера

//--------------------------------------------------------- 8 --

if (Ans==true) // Получилось:)

{

Alert ("Удалён ордер ",Text," ",Ticket);

break; // Выход из цикла закр

}

//--------------------------------------------------------- 9 --

int Error=GetLastError(); // Не получилось:(

switch(Error) // Преодолимые ошибки

{

case 4: Alert("Торговый сервер занят. Пробуем ещё раз..");

Sleep(3000); // Простое решение

continue; // На след. итерацию

case 137:Alert("Брокер занят. Пробуем ещё раз..");

Sleep(3000); // Простое решение

continue; // На след. итерацию

case 146:Alert("Подсистема торговли занята. Пробуем ещё..");

Sleep(500); // Простое решение

continue; // На след. итерацию

}

switch(Error) // Критические ошибки

{

case 2: Alert("Общая ошибка.");

break; // Выход из switch

case 64: Alert("Счет заблокирован.");

break; // Выход из switch

case 133:Alert("Торговля запрещена");

break; // Выход из switch

case 139:Alert("Ордер заблокирован и уже обрабатывается");

break; // Выход из switch

case 145:Alert("Модификация запрещена. ",

"Ордер слишком близок к рынку");

break; // Выход из switch

default: Alert("Возникла ошибка ",Error);//Другие варианты

}

break; // Выход из цикла закр

}

//-------------------------------------------------------------- 10 --

Alert ("Скрипт закончил работу -----------------------------");

return; // Выход из start()

}

//-------------------------------------------------------------- 11 --

Блок обработки ошибок также претерпел некоторые изменения. Если при закрытии рыночных ордеров необходимо учитывать возможность возникновения ошибок, связанных с изменением цен (ошибки 135 и 136), то при удалении отложенных ордеров подобные ошибки не возникают. По этой же причине нигде в программе не используется функция RefreshRates() с целью обновления текущих цен.

Некоторую сложность вызывает обработка таких ошибок, как 4 и 137 (см. Коды ошибок). Например, при получении ошибки 137 программа может принять к сведению информацию о том, что "брокер занят". Но возникает естественный вопрос: когда он освободится, чтобы пользователь мог продолжить торговлю? Ошибка 137 не содержит такой информации. Поэтому вопрос о том, как правильно составить программу обработки подобных ошибок, программист должен решить сам. В простом случае можно повторить торговый приказ после некоторой паузы (в данном примере - 3 секунды). С другой стороны, в результате серии неудачных попыток удаления (или в общем случае закрытия, открытия или модификации) ордера сервер может вернуть ошибку 141 - слишком много запросов. В результате этой ошибки скрипт deleteorder.mq4 прекратит работу. В целом, подобные конфликты не являются вопросами программирования. В подобных случаях следует связаться со службой поддержки дилингового центра и выяснить причины отказа в исполнении торгового приказа.




Поделиться с друзьями:


Дата добавления: 2014-12-29; Просмотров: 374; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.154 сек.