Заставить работать CExpert <Expert\Expert.mqh> - страница 2

 
Stanislav Korotky:

Выводите в принт Low(1), а не переменную 'a' - сейчас не понятно, как она может выводиться на тиках, если определена, судя по показанному исходнику, локально в конструкторе.

Сейчас принт выводит EMPTY_VALUE - похоже, что переменная один раз заполнилась при создании экземпляра (когда данных еще нет) и так и осталась не обновленной.

На тиках уже другая переменная. Естественно, ей предшествует Рефреш.

В другом классе CiClose, как видите, все идет штатно. 

 

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

В окне  инфа по текущим свечам EURUSD и USDJPY: TVolume - тиковые объемы. Можно и вглубь истории.

Рапечатка каждый тик. 

2016.08.15 20:07:11.899	eBat3.1 (EURUSD,M1)	USDJPY Open= 101.2 Low= 101.198 High= 101.201 Close= 101.198 TVolume= 5 Spread= 17
2016.08.15 20:07:11.899	eBat3.1 (EURUSD,M1)	EURUSD Open= 1.11832 Low= 1.11831 High= 1.11835 Close= 1.11835 TVolume= 8 Spread= 13
2016.08.15 20:07:10.416	eBat3.1 (EURUSD,M1)	USDJPY Open= 101.2 Low= 101.198 High= 101.201 Close= 101.198 TVolume= 5 Spread= 17
2016.08.15 20:07:10.415	eBat3.1 (EURUSD,M1)	EURUSD Open= 1.11832 Low= 1.11831 High= 1.11834 Close= 1.11834 TVolume= 6 Spread= 13
2016.08.15 20:07:10.364	eBat3.1 (EURUSD,M1)	USDJPY Open= 101.2 Low= 101.198 High= 101.201 Close= 101.198 TVolume= 5 Spread= 17
2016.08.15 20:07:10.364	eBat3.1 (EURUSD,M1)	EURUSD Open= 1.11832 Low= 1.11831 High= 1.11833 Close= 1.11833 TVolume= 5 Spread= 13
2016.08.15 20:07:04.576	eBat3.1 (EURUSD,M1)	USDJPY Open= 101.2 Low= 101.2 High= 101.201 Close= 101.201 TVolume= 2 Spread= 17

 И это еще не вся инфа, которую может выдавать класс.

 CExpert послан далеко и надолго. Знакомство с MQ ООП не состоялось.))

 
Yuriy Asaulenko:
 

Похоже на форуме никто этот CExpert вообще не применял. )) Я тоже больше на него время  терять не буду. Идея применения готового шаблона для создания собственной стратегии не м.б. реализована из-за отсутствия шаблона.  Знакомство с MQ ООП не состоялось. )

Придется все с нуля. 

Вы не правы - у меня весь шаблон эксперта пронаследован именно от этого класса, и все нормально работает. Но, я никогда в конструкторе никакие внешние данные никогда не получаю. Не только здесь, но и в С++.

Конструктор - не предназначен для того, чтобы объект активно обменивался данными с "внешним миром". Задача конструктора - только создание самого объекта. В сам конструктор могут быть переданы какие-то данные, но при этом объект из конструктора - на мой взгляд, еще "не имеет права" ничего запрашивать "извне" - объект еще не создан. На месте разработчиков - я бы тоже не предоставлял доступ к памяти объектам, у которых полностью не отработал конструктор. Даже если пошли тики.

Но, и в самом деле, класс CExpert - слишком сложен, и не всегда последователен (например, управление входами по сигналам он делает, а вот трейлинг - полностью "отдан на откуп" другому классу). У меня переписано большинство его виртуальных функций.

 
George Merts:

Вы не правы - у меня весь шаблон эксперта пронаследован именно от этого класса, и все нормально работает. Но, я никогда в конструкторе никакие внешние данные никогда не получаю. Не только здесь, но и в С++.

Конструктор - не предназначен для того, чтобы объект активно обменивался данными с "внешним миром". Задача конструктора - только создание самого объекта. В сам конструктор могут быть переданы какие-то данные, но при этом объект из конструктора - на мой взгляд, еще "не имеет права" ничего запрашивать "извне" - объект еще не создан. На месте разработчиков - я бы тоже не предоставлял доступ к памяти объектам, у которых полностью не отработал конструктор. Даже если пошли тики.

Но, и в самом деле, класс CExpert - слишком сложен, и не всегда последователен (например, управление входами по сигналам он делает, а вот трейлинг - полностью "отдан на откуп" другому классу). У меня переписано большинство его виртуальных функций.

Рад встретить человека, кот применяет CExpert.

В части наследования и конструкторов неправы именно Вы. Базовый класс уже создан первым, своим конструктором по умолчанию, и именно этому вы обязаны, что можете что-то исполнять в своем конструкторе. К этому времени в базовом виде все классы-предки полностью готовы к употреблению. В своем конструкторе класса-потомка вы можете (при необходимости) конфигурировать баз. класс и проверять любые его параметры. Скажем функция Init(..), класса CExpert может вызываться откуда угодно, как и любая другая функция баз.классов.

Второе. К тикам конструктор отношения не имеет. Low() (CExpert) по тикам вызывалась уже из OnTick производного класса  с пред. вызовом (или без вызова) public функции Refresh() (CExpert). Сама функ-я public OnTick CExpert ничего кроме public Refresh() и Proceccing() не содержит. Пробовал разные варианты - картинки выше.

В доках написано, что CExpert сразу готов к употреблению. Флаг передачи данных OHLC стоит по умолчанию. Проверял биты - стоит. 

Ладно, позднее сгенерю простой советник из генератора и попробую без всяких изменений подставить туда Open, Low и пр.

Надеюсь не пропадете из поля зрения.)

 

Сгенерил советник в Cоздать. Результат не изменился.

2016.08.16 14:14:20.968 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:18.887 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:17.071 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:15.415 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:13.609 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:10.003 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:08.307 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:06.507 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:04.858 aaa (EURUSD,M1) Close=1.797693134862316e+308
2016.08.16 14:14:04.832 aaa (EURUSD,M1) Close=1.797693134862316e+308

 Код вызова из OnTick

void OnTick()
  {
   ExtExpert.OnTick();
   Print("Close=",ExtExpert.Close(1));//Моя только эта строчка!!! Во всем советнике))
  }
PS Флаги не проверял.
Файлы:
aaa.mq5  7 kb
 
Yuriy Asaulenko:

Рад встретить человека, кот применяет CExpert.

В части наследования и конструкторов неправы именно Вы. Базовый класс уже создан первым, своим конструктором по умолчанию, и именно этому вы обязаны, что можете что-то исполнять в своем конструкторе. К этому времени в базовом виде все классы-предки полностью готовы к употреблению. В своем конструкторе класса-потомка вы можете (при необходимости) конфигурировать баз. класс и проверять любые его параметры. Скажем функция Init(..), класса CExpert может вызываться откуда угодно, как и любая другая функция баз.классов.

Второе. К тикам конструктор отношения не имеет. Low() (CExpert) по тикам вызывалась уже из OnTick производного класса  с пред. вызовом (или без вызова) public функции Refresh() (CExpert). Сама функ-я public OnTick CExpert ничего кроме public Refresh() и Proceccing() не содержит. Пробовал разные варианты - картинки выше.

В доках написано, что CExpert сразу готов к употреблению. Флаг передачи данных OHLC стоит по умолчанию. Проверял биты - стоит. 

Ладно, позднее сгенерю простой советник из генератора и попробую без всяких изменений подставить туда Open, Low и пр.

Надеюсь не пропадете из поля зрения.)

Не, базовый-то класс создан первым. Просто, на мой взгляд, пока полностью не отработает конструктор - объект не должен обращаться ни к каким внешним данным. И, вполне возможно, что ему и не дают таких прав на уровне компилятора.

Насколько я помню, CExpert сперва должен инициализироваться, вызвать функцию СExpert::Init(), в ней инициализируются необходимые таймсерии и индикаторы. И, кроме того, ряд дополнительных объектов типа CSymbolInfo, CTrade, CSignal, CTrailing (в смысле, их наследников).

Далее - вызывается функция CExpert::InitIndicators() - именно тут и инициализируются объекты таймсерий и индикаторов, которые складываются в коллекцию.

Потом - проводится рефреш, и из коллекции достается нужная таймсерия, данные которой и нужны.

А вы, получается, вызываете данные из несуществующих таймсерий.

 

В коде, который вы мне привели, вы вызываете функцию CExpert::Close(), смотрите, что в ней:

bool CExpert::Close(void)
{
return(m_trade.PositionClose(m_symbol.Name()));
}.

Вы вызвали закрытие позиции по текущему символу. Причем, передаете туда единицу, хотя в прототипе стоит void.

У вас не было позиции - возврат был совершенно естественнен.

Что вы еще хотели получить, вызывая эту функцию ?

И, я рад, что у вас есть желание разобраться в Стандартной Библиотеке и в ООП. Штука эта весьма полезная и нужная, но, разработчики, по-моему, перестарались с возможностями гибкости. Лично у меня такое ощущение, что главный программер Стандартной Библиотеки преследовал цель соперничать с библиотеками типа MS MFC или MS ATL, сделать что-то "не менее крутое". И его не сильно заботило, что большинство пользователей не будут являться серьезными программерами.

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

 
George Merts:

Насколько я помню, CExpert сперва должен инициализироваться, вызвать функцию СExpert::Init(), в ней инициализируются необходимые таймсерии и индикаторы. И, кроме того, ряд дополнительных объектов типа CSymbolInfo, CTrade, CSignal, CTrailing (в смысле, их наследников).

Далее - вызывается функция CExpert::InitIndicators() - именно тут и инициализируются объекты таймсерий и индикаторов, которые складываются в коллекцию.

Потом - проводится рефреш, и из коллекции достается нужная таймсерия, данные которой и нужны.

А вы, получается, вызываете данные из несуществующих таймсерий.

То, что я приложил уже готовый сов из Создать. Можно запускать сразу и в работу. Там все уже есть, включая тайм-серии. Данных нет.)

Init() в своем вызывал (картинка на 1-2 стр), вроде ее д.б. достаточно для инициализации серий. Хотя, в принципе, уже инициализирован по умолчанию символом и периодом графика. Что только не делал и не проверял - указатели на серии пихал, хотя, вообще, нужны только если мультивалютник. Даж не знаю куда еще смотреть.

Эти - CSymbolInfo, CTrade, CSignal, CTrailing к тайм-сериям (для их появления) ну никаким боком, вроде. Вначале тайм-серии, а потом уж они. 

 

Насколько я помню, таймсерий изначально там нет. Надо указать, какие нам нужны таймсерии.

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

 
George Merts:

В коде, который вы мне привели, вы вызываете функцию CExpert::Close(), смотрите, что в ней:

bool CExpert::Close(void)
{
return(m_trade.PositionClose(m_symbol.Name()));
}.

Вы вызвали закрытие позиции по текущему символу. Причем, передаете туда единицу, хотя в прототипе стоит void.

У вас не было позиции - возврат был совершенно естественнен.

Что вы еще хотели получить, вызывая эту функцию ?

И, я рад, что у вас есть желание разобраться в Стандартной Библиотеке и в ООП. Штука эта весьма полезная и нужная, но, разработчики, по-моему, перестарались с возможностями гибкости. Лично у меня такое ощущение, что главный программер Стандартной Библиотеки преследовал цель соперничать с библиотеками типа MS MFC или MS ATL, сделать что-то "не менее крутое". И его не сильно заботило, что большинство пользователей не будут являться серьезными программерами.

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

Это другая Close(void) - знаю такую. По сериям - Close(int ), Open(int) и т.д. А как не смотреть, конечно смотрю.

Разбираться приходится не в ООП, а в MQ ООП.)