home

В клиентском терминале MetaTrader 4, в отличии от MetaTrader 3, нет жесткого ограничения на паузу между торговыми операциями, совершаемых советниками. Поэтому теоретически можно совершать хоть десятки сделок в секунду. Однако чрезмерное злоупотребление этим приведет к тому, что Ваш счет будет заблокирован для торговли.

Это произойдет или потому, что сервер подумает, что такое количество запросов в секунду может осуществлять только злоумышленник, который ставит перед собой лишь цель «завалить» торговый сервер. Или потому, что сотнями запросами в минуту Вы разъярите дилера — сотрудника дилингового центра, которому приходится обрабатывать Ваши запросы.

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

Старайтесь выдерживать паузу минимум в 5 секунд. В этом Вам поможет моя функция WaitBeforeTransaction()

 

//+-------------------------------------------------------------------+
//| Фунцкия WaitBeforeTransaction выдерживает паузу Secs секунд
//| между торговыми операциями эксперта (по умолчанию 5 секунд)
//|
//| Возвращает:
//| 1 - если пауза выдержена без ошибок
//| 0 - если эксперт был остановлен
//| -1 - если произошла какая-то ошибка
//+--------------------------------------------------------------------+
int WaitBeforeTransaction(int Secs = 5)
{
// если режим тестирования, то ждать необязательно
if (IsTesting()) return(1);

// если глобальная переменная LastTradeTime не существует,
// то создать ее
if (!GlobalVariableCheck("LastTradeTime"))
{
// Если произошла какя-то ошибка при вызове функции
// GlobalVariableCheck(), выйдем с ошибкой
if (GetLastError()!=0)
{
Print("WaitBeforeTransaction(): ошибка ",GetLastError(),
" при проверке глобальной переменной LastTradeTime");
return(-1);
}

// глобальная переменная не существует, создадим ее
if (GlobalVariableSet("LastTradeTime", 1)==0)
{
// произошла ошибка при создании глобальной переменной
Print("WaitBeforeTransaction(): ошибка ",GetLastError(),
" при создании глобальной переменной LastTradeTime");
return(-1);
}

// глобальная переменная успешно создана
Print("WaitBeforeTransaction(): глобальная переменная ",
"LastTradeTime создана");
}

// получим время последней операции
datetime LastTradeTime;
LastTradeTime = GlobalVariableGet("LastTradeTime");

// если произошла ошибка (равна нулю), то выходим с ошибкой
if (LastTradeTime==0)
{
Print("WaitBeforeTransaction(): ошибка ",GetLastError(),
" при чтении глобальной переменной LastTradeTime");
return(-1);
}

// ждем Secs секунд
while(true)
{
// если эксперт остановлен, выйдем со значением 0
if (IsStopped())
{
Print("WaitBeforeTransaction(): эксперт остановлен. Выходим...");
return(0);
}

// если прошло меньше Secs секунд, то ждем
if ((LocalTime()-LastTradeTime)

// т.к. прошло больше Secs секунд, то попробуем изменить значение
// глобальной переменной LastTradeTime на текущее время

// используем функцию GlobalVariableSetOnCondition(), чтобы выявить
// ошибку, если уже за время ожидания другой эксперт успел совершить
// сделку и изменил значение глобальной переменной
if (GlobalVariableSetOnCondition("LastTradeTime", LocalTime(), LastTradeTime))
{
// за время ожидания глобальная переменная не изменилась, поэтому
// удалось установить ее новое значение
// пауза выдержена, обновим котировки и выйдем без ошибки
RefreshRates();
return(1);
}
else
{
// не удалось изменить значение глобальной переменной, т.к. другой
// эксперт успел совершить сделку раньше и установил новое
// значение переменной поэтому получим текущее значение глобальное
// переменной и продолжим ожидание
LastTradeTime = GlobalVariableGet("LastTradeTime");

// если произошла ошибка (равна нулю), то выходим с ошибкой
if (LastTradeTime==0)
{
Print("WaitBeforeTransaction(): ошибка ",GetLastError(),
" при чтении глобальной переменной LastTradeTime");
return(-1);
}
}
}
}



 

Определение режима тестирования на истории с помощью функции IsTesting()

Сам исходный код функции обладает достаточным количеством комментариев, и я уверен, что логика реализации этой функции Вам станет абсолютно понятна после изучения следующих функций:

 

  • IsTesting()
  • GlobalVariableCheck()
  • GlobalVariableSet()
  • GlobalVariableGet()
  • LocalTime()

 

Начнем с рассмотрения функции IsTesting().

 

 bool IsTesting()


 

Функция IsTesting() возвращает true, если эксперт работает в режиме тестирования на исторических данных, и false — если работа ведется на демо- или реальном счете.

Дело в том, что необязательно сразу заставлять эксперта торговать на демо- или реальном счете. Гораздо эффективнее вначале оттестировать эксперта на исторических данных, которые есть в клиентском терминале. После этого с определенной точностью станет понятно, на что способен этот эксперт.

Основное преимущество тестов на истории — быстрота. Вам не надо ждать месяцы или годы, чтобы оттестировать своего эксперта на реальных котировках. Вы просто «прогоняете» советника по истории. На это у Вас уходит лишь несколько минут. Однако если Вы будете каждый раз ждать 10 секунд между торговыми операциями, то Вы потеряете это преимущество. Именно поэтому в коде нашей функции присутствует строка:

 

 if (IsTesting()) return(1);


 

Т.е. мы выходим из функции, если эксперт находится в режиме тестирования на историчексих данных.