Полезные советы для Участников Чемпионата


В правилах Чемпионата объявлены 4 важных ограничения:
  • минимальный объем сделки - 0.1 лота
  • шаг изменения количества лотов - 0.1
  • максимальный объем сделки - 5 лотов
  • максимальное суммарное количество открытых позиций и отложенных ордеров - 3

Эти ограничения обеспечиваются настройками торгового сервера, на котором проводится чемпионат. Торговый сервер не будет пропускать торговые операции, нарушающие ограничения Чемпионата. При этом вся информация о таких нарушениях будет сохраняться в логах сервера. Эксперт, регулярно допускающий нарушения вышеперечисленных ограничений, может быть дисквалифицирован и снят с участия в чемпионате.

Все эти ограничения связаны с функцией OrderSend. Нужно программно отслеживать ограничения и не допускать ошибочного вызова этой функции. При неправильном значении объема (количество лотов меньше минимально допустимого значения, либо больше максимального значения, либо ошибка грануляции) функция вернет ошибку. GetLastError() вернет код 131(ERR_INVALID_TRADE_VOLUME).

В большинстве случаев используется некая функция для расчета объема сделки с учетом стратегии управления средствами (money management). Обычно в расчетах учитываются: баланс, эквити, свободные средства, кредитное плечо(leverage) и процент риска. Эта функция может выглядеть так:

//--- extern variables
extern double ExtMaximumRisk=0.05;             // 5% by default
 
//--- calculate current volume
double CalculateVolume()
  {
   double lot_min =MarketInfo(Symbol(),MODE_MINLOT);
   double lot_max =MarketInfo(Symbol(),MODE_MAXLOT);
   double lot_step=MarketInfo(Symbol(),MODE_LOTSTEP);
   double contract=MarketInfo(Symbol(),MODE_LOTSIZE);
   double vol;
//--- check data
   if(lot_min<0 || lot_max<=0.0 || lot_step<=0.0) 
     {
      Print("CalculateVolume: invalid MarketInfo() results [",lot_min,",",lot_max,",",lot_step,"]");
      return(0);
     }
   if(AccountLeverage()<=0)
     {
      Print("CalculateVolume: invalid AccountLeverage() [",AccountLeverage(),"]");
      return(0);
     }
//--- basic formula
   vol=NormalizeDouble(AccountFreeMargin()*ExtMaximumRisk*AccountLeverage()/contract,2);
//--- additional calculation
//   ...
//--- check min, max and step
   vol=NormalizeDouble(vol/lot_step,0)*lot_step;
   if(vol<lot_min) vol=lot_min;
   if(vol>lot_max) vol=lot_max;
//---
   return(vol);
  }

Не рекомендуется сохранять важные рыночные характеристики в функции init(), а лучше запрашивать рыночные условия по месту использования и обязательно их проверять на пустые/нулевые значения. Иначе, при попытке запуска скрипта на неактивных аккаунтах можно столкнуться с неправильными значениями. Например, в данной функции можно получить фатальный "Zero divide" как при lot_step=0, так и при AccountLeverage()=0.

Теперь обсудим общее количество открытых позиций и отложенных ордеров. Это количество возвращается функцией OrdersTotal(). В случае срабатывания ограничения суммарного количества открытых позиций и отложенных ордеров функция OrderSend() закончится неудачей, и значение, возвращаемое функцией GetLastError(), будет равно 148 (ERR_TRADE_TOO_MANY_ORDERS). Чтобы избежать этой ошибки, достаточно проверять количество открытых позиций перед любой операцией SendOrder():

//--- extern variables
int ExtMaxOrders=3;
 
  ...
//--- check before SendOrder
  if(OrdersTotal() >= ExtMaxOrders) return(...);
//--- send order 
  int ticket=OrderSend(...);
  ...

Очень серьезную опасность как для самого трейдера, так и для торгового сервера составляют "скрипты-убийцы", которые без осознанного контроля посылают множество торговых транзакций на сервер. Особенно часто это бывает в виде зацикленных попыток раз за разом протолкнуть свою некорректную заявку на сервер. Рассмотрим несколько случаев:

  • Грубое пренебрежение контролем над ошибками с зацикливанием

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

    while(OrderSend(...)<1) RefreshRates();
  • Отсутствие контроля за OrderSelect - асинхронность процессов в действии

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

  • Пропуск функции обновления рыночного окружения через RefreshRates()

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

    //--- close all positions
    for(int i=OrdersTotal()-1; i >= 0; i--)
      {
       if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
       switch(OrderType())
         {
          case OP_BUY:  OrderClose(...); break;
          case OP_SELL: OrderClose(...); break;
         }
      }
     
    if(SendOrder(...) < 1)
      {
       if(GetLastError()!=ERR_REQUOTE) return(false);
       //--- lets try again!
       if(SendOrder(...) < 1) return(false);
      }
  • Гридеры: массовые отложенные ордеры с массовыми отменами

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

В разделе документации "Справочник MQL4 - Торговые функции - Ошибки исполнения" приведены рекомендации по обработке торговых ошибок.

Создана: 10.08.2006  Автор: MetaQuotes
Одна неделя и сотня Участников

Регистрация Участников чемпионата Automated Trading Championship 2006 идет полным ходом. Уже более ста разработчиков механических торговых систем заявили о своем участии в чемпионате.

Интервью с Сергеем Ковалевым

Сергей Ковалев о трейдинге, механических торговых системах, Чемпионате Automated Trading Championship и о своей книге.

Предыдущая Следующая
Страницы: 
2
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
И ещё один вопрос :
проясните пожалуйста пока не поздно (ещё не 25 сентября :)) эту фразу :
-ШАГ ИЗМЕНЕНИЯ КОЛИЧЕСТВО ЛОТОВ 0,1 ???????

Это что я не смогу 3 ордера иметь ? в 1 лот 0,5 лота и 2 лота если рынок удачно поворачивается ? :)) а должен буду с шагом 0,1 лот ползти к 5 лотам ???? Подробнее можно пожалуйста.

С уважением
Роман
117
23.08.2006 23:53
Вопрос организаторам :
У меня торговая система построена из 3-х частей :
1. сам советник (основные рассчёты, выставление, закрытие и ведение ордеров)
2. индикатор (свой), который ведает частью рассчётов и передаёт результаты эксперту
3. скрипт, который выводит необходимую информацию для трейдера
для принятия решения

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

Так вот вопрос в следующем : Если Вы организовали этот замечательный конкурс, не считаете ли Вы, что на нём должны присутствовать торговые системы, а не только эксперты. Поэтому у меня будет просьба к организаторам, чтобы мне не переписывать и не утежелять советник рассчётами дать возможность работать и индикатору и скрипту, ведь только в целом это торговая система.

С уважением
Роман
117
23.08.2006 23:44
Пожалуйста, хотя бы комментарии в коде пишите по-русски. :-)
100
19.08.2006 22:31
На самом деле страшно - 3 ошибки:
  1. код не вставлен через кнопку MQL
  2. у OrderSelect не проверяется код возврата - об этом явно написано в "полезных советах"
  3. Point используется от текущего символа для расчетов чужих символов (это фатально)
17.08.2006 16:46

Что-то мне уже страшно =) , такой код будет работать корректно?

double getTotalProfit()
{
int A=0;
for (int i=0;i<OrdersTotal();i++)
{
OrderSelect(i,SELECT_BY_POS);
if (OrderType()==OP_BUY) A=A+((Bid-OrderOpenPrice())*(OrderLots()/Lots))/Point;
else if (OrderType()==OP_SELL) A=A+((OrderOpenPrice()-Ask)*(OrderLots()/Lots))/Point;
}
return (A);
}

201
16.08.2006 11:37
Itso писал(а):

Ошибка:

Код не будеть работать. Вскорее сего имелось в виду:

Да, верно. Спасибо за поправку!
14.08.2006 15:34

Ошибка:

for(int i=0; i < OrdersTotal()-1; i--)


Код не будеть работать. Вскорее сего имелось в виду:

for(int i=OrdersTotal()-1; i >=0 ; i--)


92
14.08.2006 10:33