Стандартная библиотека для MetaTrader 5 - страница 2

 
slyusar:

У меня вопрос по методу BuffSize базового класса Cindicator (устанавливает размер буфера индикатора). Ситуация сложилась следующая:

Я попытался получить данные буферов (Jaw, Teeth и Lips) CiAlligator разных индексов, вот код:

 Вопрос состоит в следующем:

при значении параметра BuffSize(1), BuffSize(2), BuffSize(3) и так до (4) значения буферов содержали EMPTY_VALUE..., когда увеличил BuffSize(5) появилось значение буфера Lips.

При BuffSize(7) - появилось значение Teeth..., а Jaw появился при BuffSize(10).

Объясните, пожалуйста, эту ситуацию, как правильно выбрать параметр метода BuffSize и почему так происходит?

Дело в том, что Alligator имеет внутреннее (неявное) смещение буферов. Для того чтобы обеспечить доступ ко всем данным (в том числе и "будущим"), промежуточный буфер индикатора (тот в который копируются данные функцией CopyBuffer(...)) должен быть больше на размер максимального смещения. Текущая реализация стандартной библиотеки не увеличивает буферы автоматически, поэтому нужно это учитывать при задании размера буферов индикатора.

Alligator.BuffSize(size+max_shift);

Это касается всех индикаторов имеющих буферы со смещением (в т.ч. Gator,MA и др.).

 
uncleVic:

Дело в том, что Alligator имеет внутреннее (неявное) смещение буферов. Для того чтобы обеспечить доступ ко всем данным (в том числе и "будущим"), промежуточный буфер индикатора (тот в который копируются данные функцией CopyBuffer(...)) должен быть больше на размер максимального смещения. Текущая реализация стандартной библиотеки не увеличивает буферы автоматически, поэтому нужно это учитывать при задании размера буферов индикатора.

Alligator.BuffSize(size+max_shift);

Это касается всех индикаторов имеющих буферы со смещением (в т.ч. Gator,MA и др.).

Понял, спасибо.
 

К РАЗРАБОТЧКИКАМ

ВЫ ДОЛЖНЫ ПОНИМАТЬ, ЧТО ЛЮБОЕ, ДАЖЕ САМОЕ НЕ ЗНАЧИТЕЛЬНОЕ ИЗМЕНЕНИЕ В ИСХОДНЫХ КОДАХ БАЗОВЫХ КЛАССОВ, ВЛЕЧЕТ ЗА СОБОЙ САМЫЕ СЕРЬЕЗНЫЕ ФУНДАМЕНТАЛЬНЫЕ ПОСЛЕДСТВИЯ.

То что происходит сейчас со стандартной библиотекой нельзя выразить ни какими словами, это какая-то вакханалия!!! Во первых совершенно очевидно, что от класса к классу нарушена унификация методов. Для примера возьмем класс COrderInfo и CHistoryOrderInfo. В CHistoryOrderInfo имеется перегруженный метод  Ticket(). Однако в COrderInfo такого метода нет. Я настойчиво попросил ввести реализацию этого очевидного перегруженного метода и в класс COrderInfo. Вместо этого зачем-то были введены целых два метода, один для выбора ордера Ticket(), второй для установки ордера Select(). Более того, после обновления у меня снова почему-то оказалась старая версия библиотеки классов включая старую COrderInfo. Программа которая работала еще вчера, сегодня уже выдает ошибку компиляции: метод COrderInfo.Ticket() не определен!!!!

Во-вторых, документация к классам, как и ко многим функциям очень плохо конкретизирована. Например не указывается необходимо ли вручную вибирать ордер с помощью таких функций как OrderSelect() или OrderHistorySelect(), либо выбор ордера происходит автоматически внутри реализации методов?

Вот пример абсолютно не рабочего кода:

rezult=trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,0.1,symbol_info.Bid(),0.0,0.0,"test");
   if(trade.ResultRetcode()==TRADE_RETCODE_DONE){
      m_ticket=trade.ResultOrder();  
      history_order_info.Ticket(trade.ResultOrder());
      Print("Comment: ", history_order_info.Comment(), _LastError);
      Print("Комментарий к сделке (CHistoryOrderInfo): ", history_order_info.Comment());
      Print("Тип Сделки (CHistoryOrderInfo): ", history_order_info.TypeDescription());
      Print("Объем сделки: ", history_order_info.VolumeInitial());
   }

Этот код не работает, по той причине, что перед использованием класса не использована функция HistoryOrderSelect(). Примерно это должно быть так:

if(!HistoryOrderSelect(trade.ResultOrder()))Print("last error: ", _LastError);

 Почему в документации ничего этого не указано не ясно! 

4. Нарушена унификация даже между такими функциями как OrderGetInteger() и HistoryOrderGetInteger(). Спрашивается, зачем функции HistoryOrderGetInteger(ulong ticket, ...) первый параметр, если она все равно не работает, если перед этим на вызвать функцию HistoryOrderSelect()? Какая тогда смысловая нагрузка в номере тикета?

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

 
C-4:

К РАЗРАБОТЧКИКАМ

ВЫ ДОЛЖНЫ ПОНИМАТЬ, ЧТО ЛЮБОЕ, ДАЖЕ САМОЕ НЕ ЗНАЧИТЕЛЬНОЕ ИЗМЕНЕНИЕ В ИСХОДНЫХ КОДАХ БАЗОВЫХ КЛАССОВ, ВЛЕЧЕТ ЗА СОБОЙ САМЫЕ СЕРЬЕЗНЫЕ ФУНДАМЕНТАЛЬНЫЕ ПОСЛЕДСТВИЯ.

То что происходит сейчас со стандартной библиотекой нельзя выразить ни какими словами, это какая-то вакханалия!!! Во первых совершенно очевидно, что от класса к классу нарушена унификация методов. Для примера возьмем класс COrderInfo и CHistoryOrderInfo. В CHistoryOrderInfo имеется перегруженный метод  Ticket(). Однако в COrderInfo такого метода нет. Я настойчиво попросил ввести реализацию этого очевидного перегруженного метода и в класс COrderInfo. Вместо этого зачем-то были введены целых два метода, один для выбора ордера Ticket(), второй для установки ордера Select(). Более того, после обновления у меня снова почему-то оказалась старая версия библиотеки классов включая старую COrderInfo. Программа которая работала еще вчера, сегодня уже выдает ошибку компиляции: метод COrderInfo.Ticket() не определен!!!!

Во-вторых, документация к классам, как и ко многим функциям очень плохо конкретизирована. Например не указывается необходимо ли вручную вибирать ордер с помощью таких функций как OrderSelect() или OrderHistorySelect(), либо выбор ордера происходит автоматически внутри реализации методов?

Вот пример абсолютно не рабочего кода:

Этот код не работает, по той причине, что перед использованием класса не использована функция HistoryOrderSelect(). Примерно это должно быть так:

 Почему в документации ничего этого не указано не ясно! 

4. Нарушена унификация даже между такими функциями как OrderGetInteger() и HistoryOrderGetInteger(). Спрашивается, зачем функции HistoryOrderGetInteger(ulong ticket, ...) первый параметр, если она все равно не работает, если перед этим на вызвать функцию HistoryOrderSelect()? Какая тогда смысловая нагрузка в номере тикета?

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

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

Другое дело если требуется использовать именно стандартную библиотеку, но и тут есть варианты (использовать потомков с необходимыми изменениями к примеру)...

PS

А названия и сами методы в классах действительно нужно стандартизировать и унифицировать. Хочется получить самодостаточные и главное нормально работающие классы...

 

Сейчас пытаюсь работать с классом CList, и что-то не могу вкурить почему мне не удается добавить в список потомка потомка CObject?

//+------------------------------------------------------------------+
//|                                                     TestList.mq5 |
//|                            Copyright 2010, Vasily Sokolov (C-4). |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, Vasily Sokolov (C-4)."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
#include <Arrays\List.mqh>

CList *list;

class CNObject : CObject{
private:
   int i;
};

class YNObject : CNObject{
   long t;
};

int OnInit()
  {
//---
   list = new CList;
   CNObject *n = new CNObject;
   YNObject *y = new YNObject;
   if(list.Add(y))Print("Успех Y");
   else Print("Неудача Y");
   if(list.Add(n))Print("Успех N");
   else Print("Неудача N");
//---
   return(0);
  }
Класс Y ждет неудача, а класс N - успех. Почему, понять не могу, ведь оба в конечном счете имеют общий интерфейс CObject.
 

Ошибка в документации, неправильно указан тип возврата:

Add

Добавляет элемент в конец списка.

bool  Add(
   CObject*  element      // элемент для добавления
   )

Теперь смотрим реализацию Add:

//+------------------------------------------------------------------+
//| Adding a new element to the end of the list.                     |
//| INPUT:  new_node - pointer to a new element to add.              |
//| OUTPUT: index add the element list.                              |
//| REMARK: curr_node -> adding element.                             |
//+------------------------------------------------------------------+
int CList::Add(CObject *new_node)
  {
   CObject *tmp_node;
//--- checking
   if(!CheckPointer(new_node)) return(-1);
//--- add
   if(m_first_node==NULL)
      m_first_node=new_node;
   else
     {
      m_last_node.Next(new_node);
      new_node.Prev(m_last_node);
     }
   m_curr_node=new_node;
   m_curr_idx=m_data_total;
   m_last_node=new_node;
//---
   return(m_data_total++);
  }

 

 

 
C-4:

Ошибка в документации, неправильно указан тип возврата:

Add

Добавляет элемент в конец списка.

Теперь смотрим реализацию Add:

 

 
Поправили. Спасибо.
 
Некорректно работает функция
bool CArrayObj::DeleteRange(int from,int to)

При удалении иногда не освобождаются удаляемые элементы, похоже некорректно реализована функция

int CArrayObj::MemMove(int dest,int src,int count)


Которую использует DeleteRange.

Вот код тестового скрипта, который выявляет ситуацию:

int ID_COUNTER=1;
class TestClass: CObject{
   int id;
   public:
      TestClass(){id=ID_COUNTER;ID_COUNTER++;}
      ~TestClass(){Print("Delete TestClass id=", id);}
};
void testDelRange(){
   Print("------ testDelRange");
   int i, cn=10;
   CArrayObj arr;
   for(i=0; i<cn; i++) {
      arr.Add(new TestClass());
   }
   arr.DeleteRange(cn-6, cn-1);// удаляем последние 5 элементов
   Print("---");
}
//---
void OnStart(){testDelRange();} // после работы пишет, что в памяти осталось 5 не удаленных элементов



 

Нового релиза ждать долго, поэтому поравил функцию, если кому надо

//+------------------------------------------------------------------+
//| Delete range of elements.                                        |
//| INPUT:  from -begining position of the range,                    |
//|         to   -ending position of the range.                      |
//| OUTPUT: true if OK, false if failure.                            |
//| REMARK: does not violate the sorting.                            |
//+------------------------------------------------------------------+
bool CArrayObj::DeleteRange(int from,int to)
  {
//--- checking
   if(from<0 || to<0)                return(false);
   if(from>to || from>=m_data_total) return(false);
//--- "physical" removal of the object (if necessary and possible) // это моя вставка
   if (m_free_mode) {
      if(to>=m_data_total-1) to=m_data_total-1;
      for(int i=from; i<=to; i++) {
         if(m_data[i]!=NULL) { delete m_data[i]; m_data[i]=NULL;}
      }
   }
//--- delete
   if(to>=m_data_total-1) to=m_data_total-1;
   else                   MemMove(from,to+1,m_data_total-to-1);   // в этой строке подправлен вызов MemMove
   m_data_total-=to-from+1;
//---
   return(true);
  }



 
BZSP:
Спасибо за сообщение. Ошибка исправлена.
Причина обращения: