Особенности языка mql5, тонкости и приёмы работы - страница 61

 
Vladislav Andruschenko:

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

Без кода можно только гадать.

 

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

Особенности языка mql5, тонкости и приёмы работы

Alexey Navoykov, 2017.07.21 17:04

Отсутствие множественного наследования в MQL конечно удручает. Однако можно выкрутиться подручными способами: шаблонами и макросами - куда ж без них )

Вот такой вариант сваял.  Все исходные классы должны объявляться в виде шаблонов, задающих родительский класс.

class CBase { };  // базовый класс

// Макросы, задающие список наследования:

#define INHERIT1(T)  T<CBase>

#define INHERIT2(T1, T2)  T2<INHERIT1(T1)>

#define INHERIT3(T1, T2, T3)  T3<INHERIT2(T1,T2)>

#define INHERIT4(T1, T2, T3, T4)  T4<INHERIT3(T1,T2,T3)>


// Различные пользовательские классы:

template<typename TParent>
class A : public TParent { public: void a() { Print("A"); } };

template<typename TParent>
class B : public TParent { public: void b() { Print("B"); } };

template<typename TParent>
class C : public TParent { public: void c() { Print("C"); } };


class X : public INHERIT3(A, B, C)  {  };   // Объявляем класс, наследуемый от A, B, C


template<typename T>
void SomeFunc(B<T>& obj)  { obj.b(); }   // Проверочная функция, принимающая класс B


void OnInit()
{
  X x;
  x.a();
  x.b();
  x.c();
  
  SomeFunc(x);
}

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

А если без объявления в виде шаблонов?

Например, имеем две готовых самодостаточных библиотеки:

class CLib1 : public CClass1 { };и
class CLib2 : public CClass2 { };

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

CLib1--> CLib2 --> CProgram так, чтобы в классе CProgram были доступны обе библиотеки. И, соответственно, в CLib2 была доступна библиотека CLib1

При этом как-то изменять код обеих библиотек нельзя.

Возможно такое?

При множественном наследовании это было бы так наверное:
class CProgram : public CLib1,CLib2 { };

 
Artyom Trishkin:

А если без объявления в виде шаблонов?

Например, имеем две готовых самодостаточных библиотеки:

class CLib1 : public CClass1 { };и
class CLib2 : public CClass2 { };

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

CLib1--> CLib2 --> CProgram так, чтобы в классе CProgram были доступны обе библиотеки. И, соответственно, в CLib2 была доступна библиотека CLib1

При этом как-то изменять код обеих библиотек нельзя.

Возможно такое?

При множественном наследовании это было бы так наверное:
class CProgram : public CLib1,CLib2 { };


Вы ничего не потеряете, если сделаете так:

class CProgram
{
  CLib1 lib1;
  CLib2 lib2;
};
 
Koldun Zloy:

Вы ничего не потеряете, если сделаете так:

Да. Я так и сделал. Просто хотел без лишних объектов обойтись.
 

Наверное, лучший способ получить данные от асинхронных Copy-функций (CopyRates, CopyTicks и т.д.) - через EventChartCustom.

Особенно актуально для индикаторов.

 

Есть возможность узнать, что произошла смена торгового сервера, а не просто счета - AccountInfoString(ACCOUNT_SERVER) в OnDeinit (советника, не индикатора) вернет новый торговый сервер.

 

Памятка

Действие/тип программыСмена ТФ или символаСмена счета
ИндикаторЗапуск OnDeinit и OnInit, объект глобального класса меняется (полная перезагрузка).Ничего не происходит, кроме обнуления prev_calculated.
СоветникЗапуск OnDeinit и OnInit, объект глобального класса не меняется.Запуск OnDeinit и OnInit, объект глобального класса меняется (полная перезагрузка).
 
Сжатие файла и универсальный замер времени выполнения

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

Моё недовольство к тестеру стратегий. к разрабочикам MQL

fxsaber, 2017.12.04 09:11

#define BENCH(A)                                                              \
{                                                                             \
  const ulong StartTime = GetMicrosecondCount();                              \
  A;                                                                          \
  Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \
} 

void OnStart()
{
  uchar Data[];
  uchar Key[1];
  uchar Result[];
  
  FileLoad("thousands_rubies_galaxy.bmp", Data);  
  BENCH(Print(CryptEncode(CRYPT_ARCH_ZIP, Data, Key, Result)))
  
  ArrayFree(Data);
  
  FileLoad("space_wind.wav", Data);  
  BENCH(Print(CryptEncode(CRYPT_ARCH_ZIP, Data, Key, Result)))
}

Результат

826534
Time[Print(CryptEncode(CRYPT_ARCH_ZIP,Data,Key,Result))] = 53334
306648
Time[Print(CryptEncode(CRYPT_ARCH_ZIP,Data,Key,Result))] = 29029
 

Есть целый класс индикаторов, которые накладывают на график цены графики цен других символов. Сделаны они единообразно - через индикаторные буферы.

Однако, в MT5 имеется замечательный OBJ_CHART, который позволяет реализовать эту задачу гораздо красивее и без индикаторных буферов.

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

Схема рабы - несколько чартов отображаются в виде фона основного чарта.

 
fxsaber:

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

Схема рабы - несколько чартов отображаются в виде фона основного чарта.

А есть картинка, как это будет выглядеть? А то не совсем понятно, OBJ_CHART еще не использовал