« Предыдущий пост | На главную страницу | Следующий пост »

Пример использования функции WaitUntilTradingIsAllowed()

Напомню, что для решения проблемы занятости торгового потока другим экспертом (в MetaTrader 4 в каждый конкретный момент только один эксперт может торговать) я написал функцию WaitUntilTradingIsAllowed(). Ее код был приведен в выпуске "Как избежать ошибок, если несколько экспертов торгуют одновременно".

В этом выпуске я расскажу о примере использования этой функции в экспертах.

Модифицируем код нашего первого эксперта:

 
//+------------------------------------------------------------------+
//|                                     My First Expert.mq4 |
//|               Copyright (c) 2006, Andrey Vedikhin |
//|                                http://www.vedikhin.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright (c) 2006, Andrey Vedikhin"
#property link      "http://www.vedikhin.blog-forex.org"
#define STATE_SQUARE 0 #define STATE_LONG 1 #define STATE_SHORT 2
//---- input parameters extern int MAPeriod=13; extern double LotsNumber=1.0;
//---- глобальные переменные int CurrentState; int MyOrderTicket;
//+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- if (iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0) > Close[0]) CurrentState = STATE_SHORT; else CurrentState = STATE_LONG;
MyOrderTicket = 0; //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //----
//---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- int err;
double MA; MA = iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);
if ( CurrentState == STATE_LONG) { if (MA > Close[1]) //скользящая средняя выше цены закрытия { CurrentState = STATE_SHORT;
//переворачиваемся в продажу
//---закрыть позицию, если была открыта if ( MyOrderTicket != 0) { // подождем, пока освободиться торговый поток if (WaitUntilTradingIsAllowed()==0) { if (!OrderClose(MyOrderTicket, LotsNumber, Bid, 3, CLR_NONE)) { err = GetLastError(); Print("Ошибка при закрытии позиции: ", err); return(0); } MyOrderTicket = 0; } // если WaitUntilTradingIsAllowed() вернула не ноль, то торговать // невозможно, поэтому выйдем else return(0); } RefreshRates();
//--- длинная позиция была закрыта успешно
//--- теперь откроем позицию в продажу
//--- проверим на наличие свободных средств if (!CheckForEnoughMargin()) return(0);
// подождем, пока освободиться торговый поток if (WaitUntilTradingIsAllowed()==0) { MyOrderTicket = OrderSend(Symbol(), OP_SELL, LotsNumber, Bid, 3, 0, 0, NULL, 0, 0, CLR_NONE); if (MyOrderTicket<0) { err = GetLastError(); Print("Ошибка при открытии позиции: ", err); MyOrderTicket = 0; } } // если WaitUntilTradingIsAllowed() вернула не ноль, то торговать // невозможно, поэтому выйдем else return(0); } } else { if (MA < Close[1]) //скользящая средняя ниже цены закрытия { CurrentState = STATE_LONG;
//переворачиваемся в покупку
// подождем, пока освободиться торговый поток if (WaitUntilTradingIsAllowed()==0) { //---закрыть позицию, если была открыта if ( MyOrderTicket != 0) { if (!OrderClose(MyOrderTicket, LotsNumber, Ask, 3, CLR_NONE)) { err = GetLastError(); Print("Ошибка при закрытии позиции: ", err); return(0); } MyOrderTicket = 0; } } // если WaitUntilTradingIsAllowed() вернула не ноль, то торговать // невозможно, поэтому выйдем else return(0);
RefreshRates();
//--- короткая позиция была закрыта успешно
//--- теперь откроем позицию в покупку
//--- проверим на наличие свободных средств if (!CheckForEnoughMargin()) return(0);
// подождем, пока освободиться торговый поток if (WaitUntilTradingIsAllowed()==0) { MyOrderTicket = OrderSend(Symbol(), OP_BUY, LotsNumber, Ask, 3, 0, 0, NULL, 0, 0, CLR_NONE); if (MyOrderTicket<0) { err = GetLastError(); Print("Ошибка при открытии позиции: ", err); MyOrderTicket = 0; } } // если WaitUntilTradingIsAllowed() вернула не ноль, то торговать // невозможно, поэтому выйдем else return(0); } } //---- return(0); } //+------------------------------------------------------------------+ //| Проверка наличия свободной маржи | //+------------------------------------------------------------------+ bool CheckForEnoughMargin() { if (GetOneLotMargin(Symbol())*LotsNumber<AccountFreeMargin()) return(true); else return(false); } //+-------------------------------------------------------------------+ //| Вычисление необходимой маржи на один лот| //+-------------------------------------------------------------------+ double GetOneLotMargin(string s) { double p; if ((StringSubstr(s, 0, 3) == "EUR")||(StringSubstr(s, 0, 3) == "GBP")|| (StringSubstr(s, 0, 3) == "AUD")||(StringSubstr(s, 0, 3) == "NZD")) { if (!IsTesting()) return(MarketInfo(s, MODE_LOTSIZE)*MarketInfo(StringSubstr(s, 0, 3)+"USD", MODE_BID)/AccountLeverage()); else { p = iClose(StringSubstr(s, 0, 3)+"USD", Period(), iBarShift(StringSubstr(s, 0, 3)+"USD", Period(), CurTime(), true)); return(MarketInfo(s, MODE_LOTSIZE)*p/AccountLeverage()); } }
if (StringSubstr(s, 0, 3) == "USD") return(MarketInfo(s, MODE_LOTSIZE)/AccountLeverage());
if (s == "CHFJPY") { p = iClose("USDCHF", Period(), iBarShift("USDCHF", Period(), CurTime(), true)); return(MarketInfo(s, MODE_LOTSIZE)/(AccountLeverage()*p)); }
return(77777777777777777777777777.0); } //+-------------------------------------------------------------------+ //| Функция WaitUntilTradingIsAllowed возвращает:| //| 0 - если торговый поток свободен | //| 1 - если работа эксперта была остановлена | //| 2 - если торговля экспертов запрещена на | //| уровне настроекклиентского терминала | //+-------------------------------------------------------------------+ int WaitUntilTradingIsAllowed() { // Если торговля разрешена, то вернем 0 и выйдем if (IsTradeAllowed()) return(0);
// В цикле проверяем, как изменилась ситуация while (!IsStopped()) { // Если торговля экспертов запрещена на уровне настроек // клиентского терминала, то выйдем и вернем 2 if (!IsExpertEnabled()) { Print("Ошибка: торговля запрещена на уровне настроек терминала"); return(2); }
// Если торговый поток освободился, то обновим данные // о текущих курсах и вернем 0 if (!IsTradeContextBusy()) { RefreshRates(); return(0); }
// Если дошли до момента, то ситуация не изменилась // Поэтому делаем паузу в 0.1 секунду Sleep(100); }
// Т.к. вышли из цикла, то работа эксперта была остановлена // Вернем 1 Print("Ошибка: работа эксперта была остановлена"); return(1); } //+------------------------------------------------------------------+

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

   // подождем, пока освободиться торговый поток   
   if (WaitUntilTradingIsAllowed()==0)
      {
        торговая операция
      }
   // если WaitUntilTradingIsAllowed() вернула не ноль, то торговать
   // невозможно, поэтому выйдем
   else return(0);

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



Все статьи по теме "Пишем советников для MetaTrader 4".

« Предыдущий пост | На главную страницу | Следующий пост »

Подписаться на мою рассылку



Размещение статьи "Пример использования функции WaitUntilTradingIsAllowed()" на Вашем сайте

Размещение статьи "Пример использования функции WaitUntilTradingIsAllowed()" на Вашем сайте возможно при условии выполнениия следующих условий:

  • Запрещается изменение оригинального текста без согласия автора - Андрея Ведихина.
  • Должен быть указан первоисточник. В случае публикации в интернете Вы должны разместить следующий код гиперссылки без изменений:
  • Запрещается коммерческое использование материалов, взятых с блога "Интернет-трейдинг на форекс / forex". Доступ к ним должен быть свободным, без взимания какой-либо платы, без обязательной регистрации и/или заполнения опросного листа (анкеты) и т.д.

В случае выполнения данных условий не требуется согласия автора блога "Интернет-трейдинг на форекс / forex" на размещение статьи "Пример использования функции WaitUntilTradingIsAllowed()" на Вашем сайте.

Журнал FOREX MAGAZINE:



Архив номеров FOREX MAGAZINE
Котировки Forex:

Счетчики:

Авторские права © 2005-2006 Андрей Ведихин

Условия использования материалов блога "Интернет-трейдинг на форекс / forex"

Контакты с автором:


Движок сайта:
Movable Type 5.04