Любые вопросы от ПРОФИ к СУПЕРПРОФИ - 1. - страница 42

 
swanhearts:

Здравствуйте, скинули мне индикатор МА, там сразу все необходимые  для меня уровни. Проблема в том - что при наведении мышки на индикатор (каждый МА) не показывает период данной МА. Как исправить этот момент? Постоянно ошибка синтаксиса при изменении имени IndicatorShortName("MASHKI =)"); Помогите пожалуйста.

имя индикаторного буфера задается с помощью SetIndexLabel

 

1. Какой самый дешевый способ узнать, что вызов функции происходит на том же тике, что и предыдущий вызов?

bool tick_already_processed()
{
   return( ??? );
}

void some_func()
{
   if ( tick_already_processed() ) return;

   // recalculate only once on each tick
}

void OnTick()
{
   if ( A ) some_func();
   if ( B ) some_func();
   if ( C ) some_func();
}

Время (TimeCurrent) может остаться тем же, время в мс из SymbolInfoTick, теоретически, тоже.

Сравнивать бид, аск и время в мс — дороговато.

Вариант с организацией контроля в самом советнике не предлагать, хочется именно универсальную независимую функцию получить.


2. Аналогичный вопрос для торговых операций. Как узнать, что с момента последнего запуска что-то изменилось в списке ордеров/позиций (включая уровни открытия, СЛ и ТП)?

В пятерке напрашивается взвод какого-то флага в ОнТрейд (и сброс после выполнения), дешевле не придумать.

Но, опять же, хотелось бы универсального решения.


У кого какие идеи?

 

Andrey Khatimlianskii: 

Пример https://www.mql5.com/ru/code/16997

Файл Resources.mqh  

Функция IsNewPeriod 


Основная идея - использовать функцию со static внутри. 

Для запоминания и сверки тиков можно хранить в ID = GetMicroSecondsCount 

Для того же с ордерами - проверять magic 

Псевдо-код ниже не проверял :) 

bool IsNewTick(ulong newId) // GetMicrosecondCount() or magic
{
  static ulong id = 0;
  
  if (id != newId) 
  {
    id = newId;
    return true;
  }
  
  return false; 
}
 
Andrey Khatimlianskii:

2. Аналогичный вопрос для торговых операций. Как узнать, что с момента последнего запуска что-то изменилось в списке ордеров/позиций (включая уровни открытия, СЛ и ТП)?

В пятерке напрашивается взвод какого-то флага в ОнТрейд (и сброс после выполнения), дешевле не придумать.

Но, опять же, хотелось бы универсального решения.


У кого какие идеи?

Добавьте свои условия (SL/TP и т.д.) сюда.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Организация цикла перебора ордеров

fxsaber, 2017.10.18 12:29

struct HISTORY_UNIT
{
  long Ticket;
  int Type;
  double Lots; 
    
  HISTORY_UNIT( void ) : Ticket(::OrderTicket()), Type(::OrderType()), Lots(::OrderLots())
  {
  }

  bool operator !=( const HISTORY_UNIT &Unit ) const
  {
    return((this.Ticket != Unit.Ticket) || (this.Type != Unit.Type) || (this.Lots != Unit.Lots));
  }
      
  bool IsChange( void )
  {
    const HISTORY_UNIT Tmp;
    const bool Res = (this != Tmp);
    
    if (Res)
      this = Tmp;
      
    return(Res);
  }
};

// Возвращает true только в случае, если с последнего вызова произошли торговые изменения
bool IsChange( void )
{
  static HISTORY_UNIT History[];  

  const int Total = OrdersTotal();  
  bool Res = (ArraySize(History) != Total);

  for (int i = 0, j = Res ? ArrayResize(History, 0, Total) : 0; i < Total; i++)      
    if (OrderSelect(i, SELECT_BY_POS))
    {
      if (Res || (Res = History[j].IsChange()))
        ArrayResize(History, j + 1, Total);
      
      j++;
    }
  
  return(Res);
}
 
Andrey Khatimlianskii:

1. Какой самый дешевый способ узнать, что вызов функции происходит на том же тике, что и предыдущий вызов?

Время (TimeCurrent) может остаться тем же, время в мс из SymbolInfoTick, теоретически, тоже.

Сравнивать бид, аск и время в мс — дороговато.

Вариант с организацией контроля в самом советнике не предлагать, хочется именно универсальную независимую функцию получить.

Здесь проблема не в дешевизне, а в надежности нумерации тиков. В боевом советнике делаю так.

#ifdef __MQL5__
#else // __MQL5__
  // В false-режиме если засекли изменения, то последующие вызовы не делают проверку.  
  static bool IsNotChange( const bool bInit = false )
  {
    static bool IsChange = false;
     
    if (bInit)
      IsChange = false;
      
  #ifdef HISTORYTICKS_ISCHANGE
    if (bInit)
      HISTORYTICKS::IsChange();
    else if (!IsChange)
      IsChange = HISTORYTICKS::IsChange();
  #endif // HISTORYTICKS_ISCHANGE
    
    return(!IsChange);
  }
#endif // __MQL5__

это версия функции под MT4. Нумерация через индикатор-шпион.


Версию этой же функции под MT5 не привожу, т.к. лишнее нужно удалять. Но основывается на этой функции.

  // Свежие тики с последнего вызова
  static int GetFreshTicks( MqlTick &Ticks[], const datetime dFrom = 0 )
  {
    static long LastTime = 0;
    static int LastAmount = 0;

    if (dFrom)
    {
     ::Comment("Waiting Ticks from " + ::TimeToString(dFrom, TIME_DATE) + "...");

      LastAmount = 0;
    }
    
    ::ArrayFree(Ticks);
  
    int Size = (dFrom || LastTime) ? ::CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, dFrom ? (long)dFrom * 1000 : LastTime) : 0;
    
    if (Size > LastAmount)
    {
      LastTime = Ticks[Size - 1].time_msc;
      int NewLastAmount = 1;
      
      for (int i = Size - 2; (i >= LastAmount) && (Ticks[i].time_msc == LastTime); i--)
        NewLastAmount++;
        
      if (::ArrayRemove(Ticks, 0, LastAmount))
        Size -= LastAmount;
        
      LastAmount = NewLastAmount;
    }
    else
      Size = ::ArrayResize(Ticks, 0);
    
    return(Size);
  }


Если вернула не ноль - новый тик.

 
...:

Основная идея - использовать функцию со static внутри. 

Для запоминания и сверки тиков можно хранить в ID = GetMicroSecondsCount 

Спасибо!

Весь вопрос как раз в этом уникальном ID (номере тика), которого нет.

GetMicroSecondsCount не поможет, потому что изменится между вызовами (для этого и предназначен), а GetTickCount, теоретически, может не измениться на 2-х соседних тиках.

 
fxsaber:

Здесь проблема не в дешевизне, а в надежности нумерации тиков. В боевом советнике делаю так.

Нет, это точно будет медленнее сравнения бид/аск/мс.

Какая проблема с надежностью? Важен же только факт изменения чего либо.

 
fxsaber:

Добавьте свои условия (SL/TP и т.д.) сюда.

Сразу вспомнил этот код.

Но задача как раз в том, чтобы избежать ненужного перебора всех ордеров.

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

 
Andrey Khatimlianskii:

Нет, это точно будет медленнее сравнения бид/аск/мс.

Какая проблема с надежностью? Важен же только факт изменения чего либо.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Любые вопросы от ПРОФИ к СУПЕРПРОФИ - 1.

Andrey Khatimlianskii, 2020.03.05 23:46

Время (TimeCurrent) может остаться тем же, время в мс из SymbolInfoTick, теоретически, тоже.

Сравнивать бид, аск и время в мс — дороговато.

Особенно актуально для MT4, где шаг изменение time_msc равен 1000 мс.

 
Andrey Khatimlianskii:

Но задача как раз в том, чтобы избежать ненужного перебора всех ордеров.

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

Не понял. Если в БД что-то изменилось, то единственный способ узнать это - сравнить с предыдущим состоянием БД.

Можно сравнивать каждый соответствующий элемент БД. Либо вычислить из них хэш и сравнить хэши.

Причина обращения: