Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Выводите в принт Low(1), а не переменную 'a' - сейчас не понятно, как она может выводиться на тиках, если определена, судя по показанному исходнику, локально в конструкторе.
Сейчас принт выводит EMPTY_VALUE - похоже, что переменная один раз заполнилась при создании экземпляра (когда данных еще нет) и так и осталась не обновленной.
На тиках уже другая переменная. Естественно, ей предшествует Рефреш.
В другом классе CiClose, как видите, все идет штатно.
Закончилось тем, что написал свой базовый класс для эксперта, который уже в исходной конфигурации выдает данные по заданному инструменту. На его базе можно мультивалютник делать.
В окне инфа по текущим свечам EURUSD и USDJPY: TVolume - тиковые объемы. Можно и вглубь истории.
Рапечатка каждый тик.
И это еще не вся инфа, которую может выдавать класс.
CExpert послан далеко и надолго. Знакомство с MQ ООП не состоялось.))
Похоже на форуме никто этот CExpert вообще не применял. )) Я тоже больше на него время терять не буду. Идея применения готового шаблона для создания собственной стратегии не м.б. реализована из-за отсутствия шаблона. Знакомство с MQ ООП не состоялось. )
Придется все с нуля.
Вы не правы - у меня весь шаблон эксперта пронаследован именно от этого класса, и все нормально работает. Но, я никогда в конструкторе никакие внешние данные никогда не получаю. Не только здесь, но и в С++.
Конструктор - не предназначен для того, чтобы объект активно обменивался данными с "внешним миром". Задача конструктора - только создание самого объекта. В сам конструктор могут быть переданы какие-то данные, но при этом объект из конструктора - на мой взгляд, еще "не имеет права" ничего запрашивать "извне" - объект еще не создан. На месте разработчиков - я бы тоже не предоставлял доступ к памяти объектам, у которых полностью не отработал конструктор. Даже если пошли тики.
Но, и в самом деле, класс CExpert - слишком сложен, и не всегда последователен (например, управление входами по сигналам он делает, а вот трейлинг - полностью "отдан на откуп" другому классу). У меня переписано большинство его виртуальных функций.
Вы не правы - у меня весь шаблон эксперта пронаследован именно от этого класса, и все нормально работает. Но, я никогда в конструкторе никакие внешние данные никогда не получаю. Не только здесь, но и в С++.
Конструктор - не предназначен для того, чтобы объект активно обменивался данными с "внешним миром". Задача конструктора - только создание самого объекта. В сам конструктор могут быть переданы какие-то данные, но при этом объект из конструктора - на мой взгляд, еще "не имеет права" ничего запрашивать "извне" - объект еще не создан. На месте разработчиков - я бы тоже не предоставлял доступ к памяти объектам, у которых полностью не отработал конструктор. Даже если пошли тики.
Но, и в самом деле, класс CExpert - слишком сложен, и не всегда последователен (например, управление входами по сигналам он делает, а вот трейлинг - полностью "отдан на откуп" другому классу). У меня переписано большинство его виртуальных функций.
Рад встретить человека, кот применяет CExpert.
В части наследования и конструкторов неправы именно Вы. Базовый класс уже создан первым, своим конструктором по умолчанию, и именно этому вы обязаны, что можете что-то исполнять в своем конструкторе. К этому времени в базовом виде все классы-предки полностью готовы к употреблению. В своем конструкторе класса-потомка вы можете (при необходимости) конфигурировать баз. класс и проверять любые его параметры. Скажем функция Init(..), класса CExpert может вызываться откуда угодно, как и любая другая функция баз.классов.
Второе. К тикам конструктор отношения не имеет. Low() (CExpert) по тикам вызывалась уже из OnTick производного класса с пред. вызовом (или без вызова) public функции Refresh() (CExpert). Сама функ-я public OnTick CExpert ничего кроме public Refresh() и Proceccing() не содержит. Пробовал разные варианты - картинки выше.
В доках написано, что CExpert сразу готов к употреблению. Флаг передачи данных OHLC стоит по умолчанию. Проверял биты - стоит.
Ладно, позднее сгенерю простой советник из генератора и попробую без всяких изменений подставить туда Open, Low и пр.
Надеюсь не пропадете из поля зрения.)
Сгенерил советник в Cоздать. Результат не изменился.
Код вызова из OnTick
PS Флаги не проверял.Рад встретить человека, кот применяет 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, сделать что-то "не менее крутое". И его не сильно заботило, что большинство пользователей не будут являться серьезными программерами.
Но, просматривать код, проходиться по нему в дебаггере - очень и очень полезно.
Насколько я помню, CExpert сперва должен инициализироваться, вызвать функцию СExpert::Init(), в ней инициализируются необходимые таймсерии и индикаторы. И, кроме того, ряд дополнительных объектов типа CSymbolInfo, CTrade, CSignal, CTrailing (в смысле, их наследников).
Далее - вызывается функция CExpert::InitIndicators() - именно тут и инициализируются объекты таймсерий и индикаторов, которые складываются в коллекцию.
Потом - проводится рефреш, и из коллекции достается нужная таймсерия, данные которой и нужны.
А вы, получается, вызываете данные из несуществующих таймсерий.
То, что я приложил уже готовый сов из Создать. Можно запускать сразу и в работу. Там все уже есть, включая тайм-серии. Данных нет.)
Init() в своем вызывал (картинка на 1-2 стр), вроде ее д.б. достаточно для инициализации серий. Хотя, в принципе, уже инициализирован по умолчанию символом и периодом графика. Что только не делал и не проверял - указатели на серии пихал, хотя, вообще, нужны только если мультивалютник. Даж не знаю куда еще смотреть.
Эти - CSymbolInfo, CTrade, CSignal, CTrailing к тайм-сериям (для их появления) ну никаким боком, вроде. Вначале тайм-серии, а потом уж они.
Насколько я помню, таймсерий изначально там нет. Надо указать, какие нам нужны таймсерии.
Опять же - сейчас я уже не помню, как там это точно делается, но таймсерии инициализируются внутри InitIndicators(), когда есть указание, какие именно вам нужны. Если вы ничего не указываете - таймсерий никаких не создается.
В коде, который вы мне привели, вы вызываете функцию 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 ООП.)