Ошибки, баги, вопросы - страница 3155

 

Ошибки в Generic/Queue.

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

[ВОЗМОЖНАЯ ОШИБКА] Класс контейнера CQueue

Лорис Де Марчи , 2022.02.14 13:00

Всем привет!

Я подозреваю, что по крайней мере в методах CQueue::Contains(T item) и CQueue::Remove(T item) есть ошибка.

Очередь управляется с помощью классической круговой системы «голова-хвост», поэтому этот код должен быть неправильным:

 //+------------------------------------------------------------------+
//| Removes all values from the CQueue<T>.                           |
//+------------------------------------------------------------------+
template < typename T>
bool CQueue::Contains(T item)
  {
   int count=m_size;
//--- try to find item in array
   while (count--> 0 )
     {
       //--- use default equality function
       if (::Equals(m_array[count],item))
         return ( true );
     }
   return ( false );
  }

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


Метод Remove явно терпит неудачу при запуске этого простого кода, например:

   CQueue< ulong > foo;
   foo.Enqueue( 1 );
   foo.Remove( 1 );
   foo.Enqueue( 2 );
   printf (foo.Contains( 2 ));

Он печатает «false», когда элемент явно находится в очереди...


Дайте мне знать, исправлен ли этот класс или мне следует использовать один из моих.

Спасибо!


 

Здравствуйте. Известно, что в MQL массивы могут быть как с прямой, так и с обратной индексацией (серия). Поэтому, у меня возник вопрос, как лучше всего работать с массивами в MQL, если нужна серия или, обратная индексация? Первый вариант получения значения по индексу для серии может выглядеть так.

double arrayValue(const double array[], conct int shift) {
  int len = (int)array.Size();
  if (shift < 0 || shift >= len)
    return WRONG_VALUE;
  return array[len - shift - 1];
}

Второй вариант с использованием ArraySetAsSeries.

double arrayValue(double &array[], conct int shift) {
  int len = (int)array.Size();
  double ret;
  if (shift < 0 || shift >= len)
    return WRONG_VALUE;
  if (!ArraySetAsSeries(array, true))
    return WRONG_VALUE;
  ret = array[shift];
  ArraySetAsSeries(array, false);
  return ret;
}

Я конечно ничего не утверждаю, но, думаю, что, поскольку, массив это объект (что видно даже из кода приведенных примеров), то  ArraySetAsSeries просто включает массиву флаг серии и при обращении к значению по индексу происходит как в первом примере.

double arrayValue(const double array[], conct int shift) {
  int len = (int)array.Size();
  if (shift < 0 || shift >= len)
    return WRONG_VALUE;
  return array[len - shift - 1];
}

И вот так, примерно, идет обряжение к значению по индексу.

Имеет ли смысл каждый раз включать серию для массивов в обработчике OnCalculate индикаторов или лучше обращаться к младшему бару используя длину массивов rates_total?

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[]) 
{
  Print(price[rates_total-1]); // получение цены на младшем баре без использования серии
  return(rates_total);
}

Одинаковы ли по скорости эти два представленных способа или я где-то ошибаюсь в своих размышлениях? 

 

Терминал не возвращает накопленный профит закрытых позиций. Подскажите где может быть проблема? 

double GetClosedPositionsInstrumentProfit(string symbol, datetime from) 
{
   HistorySelect(from, TimeCurrent());

   double profitSum = 0;

      for (int i = HistoryDealsTotal()-1; i >= 0; i--) 
    {   
      ulong ticket = HistoryDealGetTicket(i);
      if (ticket < 0) continue; 
      long magic = HistoryDealGetInteger(ticket, DEAL_MAGIC);
      if (magic != EXPERT_MAGIC) continue; 
      string positionSymbol = HistoryDealGetString(ticket, DEAL_SYMBOL);
      if (symbol != positionSymbol) continue; 
      
      double profit = HistoryDealGetDouble(ticket, DEAL_PROFIT) + HistoryDealGetDouble(ticket, DEAL_SWAP)+ HistoryDealGetDouble(ticket, DEAL_COMMISSION);
      profitSum += profit; 
         
      Print ("Profit " + DoubleToString(profitSum,2));              
    }         
   return profitSum;
}
 

Добрый день!

Помогите пожалуйста разобраться с небольшим кодом:

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{

//-- начальные установки --
 if(rates_total<3) return(0);
   
 int Start;
 
 if(prev_calculated<5)
  {
   Start=2;
   ArrayInitialize(Max1,EMPTY_VALUE);
   ArrayInitialize(Min1,EMPTY_VALUE);
  }
 
 else Start=rates_total-2;
   
//-- 1-й главный цикл --
  for(int i=Start;i<rates_total-1 && !IsStopped();i++)
    {
     if(high[i]>high[i+1] && low[i]>low[i+1])
      { 
       Max1[i]=high[i];
       Min1[i]=low[i];
      }
else if (high[i]<high[i+1] && low[i]<low[i+1])
      { 
       Max1[i]=high[i];
       Min1[i]=low[i];
      }
      else 
         {
          Max1[i]=EMPTY_VALUE;
          Min1[i]=EMPTY_VALUE;
         }

    }
 return(rates_total);
}

Требуется чтобы данный бар сравнивался с предыдущим, а он наоборот сравнивается с нулевым.

 
Sergey Gubar #:

Добрый день!

Помогите пожалуйста разобраться с небольшим кодом:

Требуется чтобы данный бар сравнивался с предыдущим, а он наоборот сравнивается с нулевым.

Приложите скриншот графика (очень желательно НА ЬЕЛОМ ФОНЕ) и покажите КТО такой у Вас "данный бар" и кто "предыдущий". Это важно.

 
Прикрепил скриншот
 
Sergey Gubar #:
Прикрепил скриншот

А вот тут ошибочка.

Массивы в OnCalculate Вы не переворачивали, а значит индексация у них такая, что самый правый бар на графике имеет индекс [rates_total-1], соответственно бар слева от него будет иметь индекс [rates_total-1-1]

 
Vladimir Karputov #:

А вот тут ошибочка.

Массивы в OnCalculate Вы не переворачивали, а значит индексация у них такая, что самый правый бар на графике имеет индекс [rates_total-1], соответственно бар слева от него будет иметь индекс [rates_total-1-1]

Большое спасибо за вразумление, теперь все стало на свои места.
 
Vladimir Karputov #:

А вот тут ошибочка.

Массивы в OnCalculate Вы не переворачивали, а значит индексация у них такая, что самый правый бар на графике имеет индекс [rates_total-1], соответственно бар слева от него будет иметь индекс [rates_total-1-1]

Я смотрел на эту картинку (картинка в прикрепленном файле).

Как вы вставляете картинку? У меня не получается.

 
Sergey Gubar #:

Я смотрел на эту картинку (картинка в прикрепленном файле).

Как вы вставляете картинку? У меня не получается.

Если нет такой кнопки - значит рейтинг ещё маловат. Сейчас он 11 у Вас.