Обсуждение статьи "Разрабатываем мультивалютный советник (Часть 1): Совместная работа нескольких торговых стратегий"
class CStrategy : public CObject { protected: ulong m_magic; // Magic string m_symbol; // Символ (торговый инструмент) ENUM_TIMEFRAMES m_timeframe; // Период графика (таймфрейм) double m_fixedLot; // Размер открываемых позиций (фиксированный) public: // Конструктор CStrategy(ulong p_magic, string p_symbol, ENUM_TIMEFRAMES p_timeframe, double p_fixedLot); virtual int Init() = 0; // Инициализация стратегии - обработка событий OnInit virtual void Tick() = 0; // Основной метод - обработка событий OnTick };
Зачем нужен Init-метод, если есть конструктор?
По какой-то причине сразу ограничили класс ТС одним символов и таймфреймом.
Вроде, так логичнее.
class SYSTEM { public: virtual void OnTick() {} };
Зачем нужен Init-метод, если есть конструктор?
По какой-то причине сразу ограничили класс ТС одним символов и таймфреймом.
А мне понравился подход автора. Есть в статье такой пассаж:
Тогда класс будет абстрактным, насколько понимаю...
Будет. При этом он зачем-то используется сразу в наследнике. Если не делается Deinit (есть деструктор), логично не делать и Init (есть конструктор).
//+------------------------------------------------------------------+ //| Конструктор | //+------------------------------------------------------------------+ CSimpleVolumeStrategy::CSimpleVolumeStrategy( ulong p_magic, string p_symbol, ENUM_TIMEFRAMES p_timeframe, double p_fixedLot, int p_signalPeriod, double p_signalDeviation, double p_signaAddlDeviation, int p_openDistance, double p_stopLevel, double p_takeLevel, int p_ordersExpiration, int p_maxCountOfOrders) : // Список инициализации CStrategy(p_magic, p_symbol, p_timeframe, p_fixedLot), // Вызов конструктора базового класса signalPeriod_(p_signalPeriod), signalDeviation_(p_signalDeviation), signaAddlDeviation_(p_signaAddlDeviation), openDistance_(p_openDistance), stopLevel_(p_stopLevel), takeLevel_(p_takeLevel), ordersExpiration_(p_ordersExpiration), maxCountOfOrders_(p_maxCountOfOrders) {} //+------------------------------------------------------------------+ //| Initialization function of the expert | //+------------------------------------------------------------------+ int CSimpleVolumeStrategy::Init() { // Загружаем индикатор для получения тиковых объемов iVolumesHandle = iVolumes(m_symbol, m_timeframe, VOLUME_TICK); // Устанавливаем размер массива-приемника тиковых объемов и нужную адресацию ArrayResize(volumes, signalPeriod_); ArraySetAsSeries(volumes, true); // Установим Magic Number для выставления ордеров через trade trade.SetExpertMagicNumber(m_magic); return(INIT_SUCCEEDED); }
Ну и искусственное сильное сужение возможных ТС - странное решение.
Также хорошо видна громоздкость со входными из-за ООП. Хорошо бы убрать ее.
Init() оставлен пока по той причине, что из конструктора нельзя вернуть результат. Но, возможно, что нам никогда не понадобится возвращать в результате инициализации стратегии что-то кроме INIT_SUCCESS. Так что, вполне, возможно, этот метод уберется в дальнейшем.
Выделение обязательных свойств стратегии в виде символа и таймфрейма является преднамеренным ограничением. По задумке, торговля на нескольких символах будет осуществляться за счет работы многих экземпляров наследников этого класса, но каждый конкретный экземпляр работает с одним символом. Мне пока не встретились стратегии, которым бы мешало подобное ограничение. Наоборот, эти параметры встречались в каждой рассмотренной стратегии, поэтому и было решено их поместить сразу в базовый класс.
Но в дальнейшем планирую рассмотреть и какие-нибудь стратегии, работающие по нескольким символам, которые нельзя разделить на несколько независимых односимвольных стратегий (если найдутся). Не думаю, что наличие свойств символа и таймфрейма в базовом классе сильно помешает реализовать дочерний класс, в котором будут использованы и несколько символов, и несколько таймфреймов.
Но в дальнейшем планирую рассмотреть и какие-нибудь стратегии, работающие по нескольким символам, которые нельзя разделить на несколько независимых односимвольных стратегий (если найдутся). Не думаю, что наличие свойств символа и таймфрейма в базовом классе сильно помешает реализовать дочерний класс, в котором будут использованы и несколько символов, и несколько таймфреймов.
Не помешает - 100%. Просто лишняя сущность получилась. В ООП же архитектурно идет принцип от общего к частному. Вы общий (базовый класс) сделали "частным". Хотя все, что там вызывается - CStrategy::Tick().
А мне понравился подход автора. Есть в статье такой пассаж:
Тогда класс будет абстрактным, насколько понимаю...
Так и есть, он будет использоваться только для получения дочерних классов. Создавать объекты базового класса CStrategy не понадобится. Зато любой объект дочернего класса может быть передан в объект эксперта для добавления в метод CAdvisor::AddStrategy(CStrategy &strategy).
Init() оставлен пока по той причине, что из конструктора нельзя вернуть результат. Но, возможно, что нам никогда не понадобится возвращать в результате инициализации стратегии что-то кроме INIT_SUCCESS. Так что, вполне, возможно, этот метод уберется в дальнейшем.
static int CStrategy::InitFlag = INIT_FAILED;
любой объект дочернего класса может быть передан в объект эксперта для добавления в метод CAdvisor::AddStrategy(CStrategy &strategy).
Похоже, ошибка компилятора, что не ругается на эту сигнатуру метода при таком вызове.
expert.AddStrategy(new CSimpleVolumeStrategy( magic_ + 1, "EURGBP", PERIOD_H1, NormalizeDouble(0.34 * depoPart_, 2), 130, 0.9, 1.4, 231, 3750, 50, 600, 3)
Должно быть так.
CAdvisor::AddStrategy(CStrategy* strategy)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Опубликована статья Разрабатываем мультивалютный советник (Часть 1): Совместная работа нескольких торговых стратегий:
Различных торговых стратегий существует довольно много. С точки зрения диверсификации рисков и повышения устойчивости торговых результатов может оказаться полезным использовать несколько параллельно работающих стратегий. Но если каждая стратегия будет реализована в виде отдельного советника, то управлять их совместной работой на одном торговом счёте становится гораздо сложнее. Для решения этой проблемы желательно реализовать работу разных торговых стратегий в одном советнике.
Надо определиться, что мы хотим и что у нас есть.
У нас есть (ну или почти есть):
Мы хотим:
Будем использовать объектно-ориентированный подход, MQL5, штатный тестер в MetaTrader 5.
Поставленная задача достаточно большая, поэтому будем решать ее поэтапно.
Автор: Yuriy Bykov