Студопедия

КАТЕГОРИИ:


Архитектура-(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)

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




Ошибка 145 может возникнуть в том случае, если отложенный ордер (в общем случае и стоп-приказ рыночного ордера) находится слишком близко к рыночной цене. Эта ошибка не возникает, если торговля ведётся на спокойном рынке в размеренном темпе. Если же на рынке происходят резкие изменения цены, брокер может решить, что некоторый ордер в ближайшее время будет открыт, и не позволит его удалить (или модифицировать). Эта ошибка учитывается в скрипте как непреодолимая и приводит завершению программы (нет смысла лишний раз тревожить брокера торговыми приказами). Если через некоторое время цена изменится, можно повторить попытку удаления ордера, снова запустив скрипт на исполнение.

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

Встречное закрытие рыночных ордеров

 

Встречный ордер - это рыночный ордер, открытый в противоположном направлении по отношению к другому рыночному ордеру по тому же финансовому инструменту.

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

Функция OrderCloseBy()

bool OrderCloseBy(int ticket, int opposite, color Color=CLR_NONE)

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

Параметры:

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

opposite - Уникальный порядковый номер противоположного ордера.

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

Размеры встречных ордеров не обязательно должны совпадать. В случае несовпадения размеров ордеров торговая операция выполняется в размере меньшего объема одного из ордеров.

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


Рис. 95. Результат отдельного закрытия ордеров с помощью функции OrderClose().

Если же в этой ситуации использовать функцию встречного закрытия ордеров OrderCloseBy(), то экономический результат окажется лучше (в сравнении с предыдущим вариантом) на сумму, пропорциональную стоимости спреда одного из ордеров:


Рис. 96. Результат встречного закрытия ордеров с помощью функции OrderCloseBy().

Очевидно, что если в терминале есть встречные ордера, которые необходимо закрыть, то, имея ввиду экономическую выгоду, следует использовать функцию OrderCloseBy(), а не OrderClose().

В связи с экономией одного спреда при встречном закрытии ордеров необходимо дать замечания более общего характера. В сущности, торговая операция открытия ордера (например, на покупку) по смыслу является противоположной торговой операцией по отношению к операции открытия ордера в противоположном направлении (на продажу) в той же мере, как и операция закрытия ордера (на покупку). Иначе говоря, с экономической точки зрения безразлично какой из двух вариантов использовать: то ли просто закрыть рыночный ордер, то ли открыть встречный на такое же количество лотов (а впоследствии оба ордера закрыть встречно). Разница между этими вариантами может состоять лишь в различных методах расчёта денежных средств, отвлекаемых на поддержание рыночных ордеров в различных дилинговых центрах (см. рис. 85 и рис. 88).

Легко заметить также, что в функции OrderCloseBy() для встречного закрытия ордеров не предусмотрено указание цены закрытия. В этом нет необходимости, потому что прибыль и убыток от двух встречных ордеров взаимно гасят друг друга, и общий экономический результат от рыночной цены не зависит. Это правило справедливо, конечно же, только в отношении ордеров одинакового количества лотов. Например, если по одному финансовому инструменту имеются два ордера - Buy размером 1 лот и Sell размером 0.7 лота, то зависимость от цены этой торговой ситуации касается только ордера Buy в размере 0.3 лота. Совпадающая же часть ордеров 0.7 лота от цены финансового инструмента не зависит.

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

Пример простого скрипта, закрывающего все встречные ордера по финансовому инструменту (closeby.mq4).

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

// closeby.mq4

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

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

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

{

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

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

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

while(true) // Цикл обработки..

{ //..встречных ордеров

double Hedg_Buy = -1.0; // Макс. стоимость Buy

double Hedg_Sell= -1.0; // Макс.стоимость Sell

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 --

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

{

case 0: // Ордер Buy

if (OrderLots()>Hedg_Buy)

{

Hedg_Buy=OrderLots(); // Выбираем макс.стоим

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

}

break; // Из switch

case 1: // Ордер Sell

if (OrderLots()>Hedg_Sell)

{

Hedg_Sell=OrderLots(); // Выбираем макс.стоим

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

}

} //Конец switch

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

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

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

if (Hedg_Buy<0 || Hedg_Sell<0) // Если нет ордера..

{ //..какого-то типа

Alert("Все встречные ордера закрыты:)");// Сообщение

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

}

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

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

{

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

Alert("Попытка встречного закрытия. Ожидание ответа..");

bool Ans=OrderCloseBy(Ticket_Buy,Ticket_Sell);// Закрытие

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

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

{

Alert ("Выполнено встречное закрытие.");

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);//Другие варианты

}

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

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

}

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

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

} // Конец start()

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

Алгоритм представленного скрипта несколько отличается от последних рассмотренных. Это отличие состоит в том, что для успешного закрытия нескольких ордеров (количество закрываемых ордеров не ограничено) необходимо многократно исполнить один и тот же код. Скрипт опробовался на случайном наборе рыночных ордеров. На рис. 97 представлено 5 ордеров различной стоимости.


Рис. 97. Рыночные ордера, открытые по одному финансовому инструменту.

Для того чтобы встречно закрыть имеющиеся ордера, необходимо для начала задаться критериями отбора ордеров. Таким критерием в данном алгоритме является размер ордера - сначала закрываются ордера большего объема, а затем меньшего. После встречного закрытия ордеров различного объема остаются ордера на разницу разутых ордеров. Например, в результате встречного закрытия ордера Buy в размере 1 лот и ордера Sell в размере 0.8 лотов останется ордер Buy объемом 0.2 лота. Поэтому после каждого успешного закрытия необходимо снова обратиться к (теперь уже обновлённому) набору ордеров, с тем, чтобы в этом наборе ордеров выявить два встречных ордера максимального объема.

Указанные вычисления реализованы в (условно) бесконечном цикле while в блоках 2-10. В начале этого цикла на каждой итерации делается предположение, что ордеров какого-либо типа уже не осталось. Для этого переменным Hedg_Buy и Hedg_Sell присваивается значение -1. Алгоритм блока обработки ордеров в целом сохранён (см. код closeby.mq4). В цикле перебора ордеров for, а именно в блоке 3-4, так же, как и в предыдущих программах, производится отсев "не наших" ордеров, в данном случае - открытых по другому финансовому инструменту, а также отложенных ордеров.

В блоке 4-5 для каждого из ордеров, прошедших проверку в блоке 3-4, вычисляется его объем. Если в процессе вычислений оказывается, что текущий обрабатываемый ордер имеет больший размер из всех обрабатываемых, то запоминается его тикет. Это значит, что на данной стадии вычислений ордер с этим номером является претендентом на участие в операции встречного закрытия. К моменту окончания последней итерации цикла for известны номера ордеров с максимальным количеством лотов, открытых в разных направлениях. Эти ордера и являются выбранными. Если же к этому моменту ордеров какого-либо типа уже нет, то в блоке 5-6 осуществляется выход из программы.

Блок 6-10 представляет обработку ошибок, он полностью аналогичен рассмотренным ранее (в этом и предыдущем параграфах). Формирование торгового приказа для встречного закрытия ордеров осуществляется в блоке 7-8 с помощью функции OrderCloseBy(). В случае неудачи, в зависимости от кода ошибки, управление передаётся либо на повторение попытки исполнения торговой операции (для тех же тикетов) либо оператору return, в результате чего скрипт заканчивает работу.

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

При исполнении скрипта closeby.mq4 для закрытия рыночных ордеров, показанных на рис. 97, были получены такие сообщения:


Рис. 98. Сообщения, полученные при исполнении скрипта closeby.mq4.

На закладке История Счёта в Терминале видно, что некоторые ордера закрыты с нулевой прибылью. Это и есть экономия, получаемая при встречном закрытии ордеров. Сравните экономические показатели на рис. 97 и рис. 99:


Рис. 99. История Счёта после исполнения скрипта closeby.mq4.

На закладке Журнал в Терминале можно проследить историю закрытия ордеров (последние события сверху):


Рис. 100. События, произошедшие при исполнении скрипта closeby.mq4.

При исполнении скрипта в соответствии с алгоритмом закрываются ордера максимального размера, имеющиеся на текущий момент. Несмотря на то, что ордера были открыты в случайной последовательности (рис. 97), первыми в закрытии участвовали ордера Buy 778594 и Sell 778595, соответственно размером 1 лот и 0.8 лота (нижние строки на рис. 100). Объемы этих ордеров разные, поэтому в результате встречного закрытия образовался новый ордер Buy 778597 остаточного размера 0.2 лота. В дальнейшем программа выбрала для закрытия ордера Buy 778592 и Sell 778593, по 0.5 лотов каждый. Эти ордера были закрыты без остатка.

К моменту начала третьей итерации во внешнем цикле обработки в окне финансового инструмента остались два ордера: исходный ордер Sell 778596 стоимостью 0.3 лота и тот, который образовался в процессе исполнения скрипта - Buy 778597 стоимостью 0.2 лота. В верхних строках рис. 100 видно, что эти ордера тоже были закрыты встречно. Объемы этих ордеров разные, поэтому в результате исполнения последней торговой операции в окне финансового инструмента остался один рыночный ордер размером 0.1 лота (обратите внимание на экономические показатели):


Рис. 101. Ордер Sell остаточной стоимостью 0.1 лота.

Скрипт closeby.mq4 удобно использовать при ручной торговле, особенно в случаях, когда в окне финансового инструмента имеется множество разнонаправленных рыночных ордеров.

Модификация ордеров

 

Язык MQL4 предоставляет возможность модификации рыночных и отложенных ордеров. Модификация ордеров производится в соответствии с правилами, описанными в разделе Характеристики ордеров и Приложении 3.

Функция OrderModify()

 

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

bool OrderModify(int ticket, double price, double stoploss, double takeprofit, datetime expiration, color arrow_color=CLR_NONE)

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

Параметры:

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

price - новая заявленная цена для отложенного ордера или цена открытия рыночного ордера.

stoploss - новое значение StopLoss.

takeprofit - новое значение TakeProfit.

expiration - время истечения отложенного ордера.

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

Замечания: цену открытия и время истечения можно изменять только для отложенных ордеров.

Если в качестве параметров функции передать неизмененные значения, то в этом случае будет сгенерирована ошибка 1 (ERR_NO_RESULT). На некоторых торговых серверах может быть установлен запрет на применение срока истечения отложенных ордеров. В этом случае при попытке задать ненулевое значение в параметре expiration будет сгенерирована ошибка 147 (ERR_TRADE_EXPIRATION_DENIED).

 

Модификация рыночных ордеров

 

Обычный рыночный ордер содержит два стоп-приказа - StopLoss и TakeProfit, - предписывающих закрытие ордера по заявленным ценам с целью ограничения убытков и фиксации прибыли. Модификация рыночных ордеров бывает полезна для изменения заявленных цен стоп-приказов либо в результате получения в программе новых расчётных значений, либо по инициативе трейдера. Клиентский терминал имеет собственное средство для модификации ордера StopLoss - Трейлинг-стоп. Этот инструмент позволяет модифицировать StopLoss, продвигая его вслед за курсом на определённом фиксированном расстоянии (см. Руководство клиентского терминала).

Функция модификации ордеров OrderModify() значительно расширяет возможности модификации: допускается изменение заявленных цен обоих стоп-приказов как в сторону приближения их к рыночной цене, так и удаление. Ограничением при модификации рыночного ордера является минимально допустимая дистанция между стоп-приказом и рыночной ценой, устанавливаемая дилинговым центром (см. Характеристики ордеров и Требования и ограничения торговых операций). В случае, если программа пытается изменить положение стоп-приказа так, что он оказывается ближе к рынку, чем на минимально допустимую дистанцию, то такой торговый приказ будет отклонён клиентским терминалом, и исполнение функции OrderModify() закончится неудачей (ошибка 130). Поэтому в программе обязательно должен быть предусмотрен блок вычислений, учитывающий это ограничение.

 

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

 

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

// modifystoploss.mq4

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

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

extern int Tral_Stop=10; // Дист. преследования

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

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

{

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

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

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

{

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

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

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

if(OrderSymbol()!=Symb||Tip>1)continue;// Не наш ордер

double SL=OrderStopLoss(); // SL выбранного орд.

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

while(true) // Цикл модификации

{

double TS=Tral_Stop; // Исходное значение

int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);//Миним. дист

if (TS < Min_Dist) // Если меньше допуст.

TS=Min_Dist; // Новое значение TS

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

bool Modify=false; // Не назначен к модифи

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

{

case 0: // Ордер Buy

if (NormalizeDouble(SL,Digits)< // Если ниже желаем.

NormalizeDouble(Bid-TS*Point,Digits))

{

SL=Bid-TS*Point; // то модифицируем его

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

Modify=true; // Назначен к модифи.

}

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

case 1: // Ордер Sell

if (NormalizeDouble(SL,Digits)> // Если выше желаем.

NormalizeDouble(Ask+TS*Point,Digits)

|| NormalizeDouble(SL,Digits)==0)//или равно нулю

{

SL=Ask+TS*Point; // то модифицируем его

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

Modify=true; // Назначен к модифи.

}

} // Конец switch

if (Modify==false) // Если его не модифи

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

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

double TP =OrderTakeProfit(); // TP выбранного орд.

double Price =OrderOpenPrice(); // Цена выбранн. орд.

int Ticket=OrderTicket(); // Номер выбранн. орд.

 

Alert ("Модификация ",Text,Ticket,". Ждём ответ..");

bool Ans=OrderModify(Ticket,Price,SL,TP,0);//Модифи его!

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

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

{

Alert ("Ордер ",Text,Ticket," модифицирован:)");

break; // Из цикла модифи.

}

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

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

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

{

case 130:Alert("Неправильные стопы. Пробуем ещё раз.");

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

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

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

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

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

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

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

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

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

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

// Критические ошибки

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

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

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

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

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

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

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

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

default: Alert("Возникла ошибка ",Error);//Др. ошибки

}

break; // Из цикла модифи.

} // Конец цикла модифи.

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

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

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

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

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

}

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

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

Алгоритм представленного эксперта modifystoploss.mq4 очень прост. Основные вычисления выполняются в цикле перебора ордеров (блок 2-9). Выбор ордера ведётся среди рыночных и отложенных ордеров (параметр pool в вызове функции OrderSelect() не указан явно). В блоке 2-3 отсортировываются отложенные ордера, а также ордера, открытые по другому финансовому инструменту; для ордеров, прошедших отбор, определяется значение StopLoss.

Блок 3-9 представляет цикл модификации выбранного ордера. В блоке 3-4 определяется новое текущее значение ограничивающей дистанции (брокер может изменить это значение в любой момент). В блоке 4-5 вычисляется необходимость модификации отобранного ордера (текущего обрабатываемого в цикле for), а также новое значение StopLoss. Если текущий ордер не требует модификации, то в конце блока 4-5 осуществляется выход из цикла while, и модификация этого ордера (в блоке 5-6) не осуществляется. Если же ордер требует модификации, то управление передаётся в блок 5-6, в котором вычисляются необходимые параметры и выполняется обращение к функции OrderModify(), которая и формирует торговый приказ.

Если торговая операция завершилась успешно, то оператор break в блоке 6-7 заканчивает исполнение цикла while, что приводит к окончанию текущей итерации цикла перебора ордеров for (и на следующей итерации начинается обработка очередного ордера). Если же торговая операция закончилась неудачей, то производится обработка ошибок. В случае, когда ошибка оказывается не критической, попытка повторить торговую операцию повторяется. Если же ошибка оценивается как критическая, то управление передаётся за пределы цикла модификации для обработки следующего ордера (в цикле for).

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

Например, имеется рыночный ордер Buy, открытый по цене 1.295467, со стоп-приказами StopLoss = 1.2958 и TakeProfit = 1.2960. Минимальная дистанция, установленная брокером, равна 5 пунктов. При рыночной цене Bid = 1.2959 возникают условия для модификации ордера, а именно для установки StopLoss = 1.2949 (Bid - 10 пунктов). Для исполнения функции OrderModify() требуется указать и новое значение TakeProfit. Наш советник не изменяет положение TakeProfit, поэтому в функции задаётся текущее значение TakeProfit = 1.2960.

Несмотря на то, что новое заявленное значение TakeProfit = 1.2960 находится близко к рыночной цене Bid (всего 1 пункт, т.е меньше допустимой дистанции 5 пунктов), это значение не отличается от текущего значения TakeProfit = 1.2960, поэтому торговый приказ будет признан корректным и исполнен на сервере (в общем случае торговый приказ может быть отклонён, но по другим причинам). На рис. 102 и 103 представлены результаты успешной модификации ордера в этой ситуации.


Рис. 102. Вид окна сообщений и окна финансового инструмента при модификации ордера экспертом modifystoploss.mq4 в момент, когда рыночный курс находится вблизи от заявленного значения TakeProfit.

 


Рис. 103. Модифицированный ордер в окне Терминала.

На Рис. 103 видно, что в результате модификации новое значение StopLoss = 1.2949, а текущая цена Bid = 1.2959 находится на расстоянии 1 пункта от значения TakeProfit.

Отдельно нужно заметить, что сама по себе модификация (и рыночных и отложенных) ордеров в отрыве от анализа рыночной ситуации производиться не должна. Подобная модификация может быть полезна только в случае резкого и однонаправленного движения рыночного курса, которое случается в результате выхода важных новостей. Если же торговля ведётся на "обычном" рынке, то решение о необходимости модификации ордеров должно приниматься на основе рыночных критериев. В эксперте modifystoploss.mq4 тоже используется критерий (StopLoss от рыночной цены дальше желаемого), по которому принимается решение о модификации, однако он слишком простой и жёсткий, поэтому не может рассматриваться как критерий, характеризующий рыночную ситуацию.




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


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


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



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




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