Обсуждение статьи "Прототип торгового робота" - страница 2

 

Рекомендую уйти вот от такой конструкции

//------------------------------------------------------------------ CheckNewBar
bool CExpertAdvisor::CheckNewBar()          // функция проверки появления нового бара
  {
   MqlRates rt[2];
   if(CopyRates(m_smb,m_tf,0,2,rt)!=2)      // копируем бары
     { Print("CopyRates of ",m_smb," failed, no history"); return(false); }
   if(rt[1].tick_volume>1) return(false);   // проверяем объем 
   return(true);
  }

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

соответственно возможно пропустить открытие.

Лучше привязываться к времени открытия бара, но для этого нужно где то сохранять предыдущее время  к примеру нулевого бара чтобы потом сравнивать его с текущем временем нулевого бара

Если одинаковое - нового бара нет

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

Такая конструкция более надежная.

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций - Документация по MQL5
 

Об этом мы расскажем в одной из следующих статей:

  • *надежные* (в смысле, серверные) разноуровневые стоп-лосс и тейк-профит ордера на каждую сделку; они *обязательны*, чтобы избежать проблем, связанных с перебоями в работе сети и клиентской программы (длительное отключение сети, проскальзывание (и реквоты), выход из строя клиентской программы или операционной системы, перезапуск, крах (длительное отсутствие клиентского ПО) и т.д.); так называемые "виртуальные" ордера просто не подходят, как и их заменители, не относящиеся к OCO (нет, это *не* обсуждается, если надежность является требованием, стоп-лосс и тейк-профит ордера *должны* быть на стороне сервера, и если один из них сбит, другой *должен* быть удален *сервером* в то же время)
  • *надежное* восстановление состояния каждой сделки в случае сбоя; другими словами, если клиент/ОС падает (и автоматически перезапускается), я хочу, чтобы советник точно знал, что произошло с невыполненными отдельными сделками и ордерами за это время: заполнены, закрыты, все еще активны, какие связанные с ними s/l и t/p ордера принадлежат какой сделке/ордеру и т.д. (нет, запись состояния на диск *не* подходит, потому что существует условие гонки между открытием сделки и записью состояния на диск, и клиентская программа может упасть в самый неподходящий момент; комментарии ордеров на стороне сервера могли бы подойти, *если* бы они были модифицируемыми).

Насколько я могу судить, MT5 поддерживает только *1* (один) серверный s/l и t/p ордер *на инструмент* (не на сделку) и никаких OCO ордеров (OCO ордера могут быть использованы для симуляции s/l и t/p ордеров на сделку, но там тоже есть условие гонки). Пока не будет решена эта проблема, я бы не стал тратить больше $100 на торговлю через MT5 (упрощенные советники типа MA cross с одним ордером на одном таймфрейме). И я даже не уверен насчет 100 долларов.

 
olyakish:

Рекомендую уйти вот от такой конструкции

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

соответственно возможно пропустить открытие.

Лучше привязываться к времени открытия бара, но для этого нужно где то сохранять предыдущее время  к примеру нулевого бара чтобы потом сравнивать его с текущем временем нулевого бара

Если одинаковое - нового бара нет

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

Такая конструкция более надежная.

Я у себя так делал:

bool CUniexp::checkNewBar(void)
{
   static datetime prevTime[1];
   datetime currentTime[0];
   CopyTime(_Symbol,_Period,0,1,currentTime);
   if (currentTime[0]==prevTime[0])
   {return (false);}
   else
   {
      prevTime[0] = currentTime[0];
      return (true);
   }
}
 
isNewBar
isNewBar
  • голосов: 7
  • 2010.05.07
  • Prival
  • www.mql5.com
Функция анализа появления нового бара на заданном таймфрейме.
 

Компилируется, но отладчик не работает.

загрузка C:\Program Files\MetaTrader 5\MQL5\Experts\Examples\eMyEA.ex5 не удалась

 
Rosh:

Опубликована новая статья Прототип торгового робота:

Автор: Алексей Сергеев


Спасибо за отличную статью! Я новичок, но у меня есть вопрос по коду.


В функции void CExpertAdvisor::TrailingPosition(long dir,int TS) есть одна строка:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // рассчитываем Stop Loss


Должны ли мы использовать apr и для второго, и для третьего аргумента при вызове NormalSL? Я думал, что должно быть так:

sl=NormalSL(dir,op,apr,TS,StopLvl);

так как вторым аргументом должна быть цена покупки/продажи для "указанного" направления (т.е. переменная op), а не для "обратного" (т.е. переменная apr).


Спасибо!

 
echostate:


В функции void CExpertAdvisor::TrailingPosition(long dir,int TS) есть одна строка:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // вычисляем Stop Loss


Должны ли мы использовать apr и для второго, и для третьего аргумента при вызове NormalSL? Я думал, что должно быть так:

sl=NormalSL(dir,op,apr,TS,StopLvl);

Нет.
Второй и третий аргумент должны быть apr.

потому что расчет tral происходит от цены, по которой позиция будет закрыта. Bid для покупки и Ask для продажи. функция корректна.

поскольку вторым аргументом должна быть цена покупки/продажи для "заданного" направления (т.е. переменная op), а не для "обратного" (т.е. переменная apr).

должна рассчитываться по "обратному" направлению. В этом случае apr.
 
sergeev:

нет.
второй и третий аргументы должны быть апр.

так как расчет tral происходит от цены, по которой будет закрыта позиция. Бид для покупки и Аск для продажи. функция верна.

должна рассчитываться от "обратного" направления. В данном случае apr.


Спасибо за быстрый ответ! Я думал, что, наверное, ошибаюсь.


Могу ли я также спросить в функции

double CExpertAdvisor::CountLotByRisk(int dist,double risk,double lot) // рассчитать лот по размеру риска
  {
   if(dist==0 || risk==0) return(lot);
   m_smbinf.Refresh();
   return(NormalLot(AccountInfoDouble(ACCOUNT_BALANCE)*risk/(dist*10*m_smbinf.TickValue())));
  }

почему в возвращаемом значении между "dist" и "m_smbinf.TickValue()" стоит "10"? Я полагаю, что "dist" - это стоп-лосс (в пунктах), а "m_smbinf.TickValue()" - это стоимость доллара США за пункт в лоте для валютной пары. Поэтому я не совсем понимаю, зачем мы умножаем еще "10" между ними.

Спасибо!

 
Спасибо большое.
 

Очень полезная статья. Спасибо большое!