Скачать MetaTrader 5

Использование CExpert vs свой велосипед

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Sergey Sypalo
370
Sergey Sypalo  

Привет всем,

 

Решил таки еще раз взяться за МТ5, только теперь уже за написание/переписывание советника под MQL5. Первое что сделал, это сравнил исходный код примеров советников и автоматически сгенерированного советника.

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

В принципе мне понравился подход используемый при генерации советника, но остались некоторые вопросы:

1) При поступлении сигнала на покупку/продаже советник не учитывает открыта ли позиция в противоположном направлении и открывает сделку в том направлении куда указывает сигнал, при этом если текущая позиция ушла в минус она закрывается с минусом. Можно ли как-то ограничить советник, чтобы он открывал сделку только если нет открытых сделок?

2) Если я хочу "долиться" (открыть еще одну сделку в том же направлении что уже есть), то где это лучше всего сделать в событии OnTick? Идея проанализировать насколько далеко рынок ушел и долиться в убыточную сделку, тем самым приблизив ее цены к рыночной цене (чтобы быстрее ее закрыть, как только она будет в плюсе). Я понимаю что это похоже на мартингейл, но понятие мани-менеджмента мне не чуждо, объемы будут рассчитаны исходя из размера депозита

George Merts
4864
George Merts  

1) При поступлении сигнала на покупку/продаже советник не учитывает открыта ли позиция в противоположном направлении и открывает сделку в том направлении куда указывает сигнал, при этом если текущая позиция ушла в минус она закрывается с минусом. Можно ли как-то ограничить советник, чтобы он открывал сделку только если нет открытых сделок?

Я так понимаю, необходимо дополнить функцию bool CExpert::CheckReverse(void).

Сейчас в этой функции проверяется только тип позиции, и далее - управление передается функциям реверса в лонг или в шорт.

А вам необходимо в вашем классе CMyExpert, пронаследованном от CExpert перегрузить эту функцию - сперва проверить, если текущая позиция в просаде - сразу вернуть управление с fals'ом, не вызывая реверса в шорт или лонг.

2) Если я хочу "долиться" (открыть еще одну сделку в том же направлении что уже есть), то где это лучше всего сделать в событии OnTick? Идея проанализировать насколько далеко рынок ушел и долиться в убыточную сделку, тем самым приблизив ее цены к рыночной цене (чтобы быстрее ее закрыть, как только она будет в плюсе). Я понимаю что это похоже на мартингейл, но понятие мани-менеджмента мне не чуждо, объемы будут рассчитаны исходя из размера депозита

Это в любом случае будет сделано в событии OnTick(). Если вы используете классы СБ, то величиной лота управляют класс, пронаследованные от CExpertMoney, вам нужно объявить своего наследника, и написать функцию, которая будет определять лот.
Sergey Sypalo
370
Sergey Sypalo  

А можно для тех кто в танке, поподробнее как перегрузить функцию, документацию нашел - https://www.mql5.com/ru/docs/standardlibrary/expertclasses/expertbaseclasses/cexpert/cexpertcheckreverse

Но что-то воедино в голове все не укладывается, где именно перегружать (в коде). Обычно при создании класса это делал, а тут класс объявляется как переменная типа CExpert, это меня сбивает с толку (исходный код прилагается).

Как в OnTick доливку сделать буду позже ковырять, после того как  решу проблему с первым вопросом

Документация по MQL5: Стандартная библиотека / Классы торговых стратегий / Базовые классы экспертов / CExpert / CheckReverse
Документация по MQL5: Стандартная библиотека / Классы торговых стратегий / Базовые классы экспертов / CExpert / CheckReverse
  • www.mql5.com
Стандартная библиотека / Классы торговых стратегий / Базовые классы экспертов / CExpert / CheckReverse - Документация по MQL5
Файлы:
SOMA.mq5 9 kb
George Merts
4864
George Merts  
ITeXPert:
 

Но что-то воедино в голове все не укладывается, где именно перегружать (в коде). Обычно при создании класса это делал, а тут класс объявляется как переменная типа CExpert, это меня сбивает с толку (исходный код прилагается).

У вас в коде объявляется переменная типа CExpert. Это значит, что все функции будут взяты именно из этого класса.

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

То есть, вы должны объявить свой класс, наследни от CExpert. В нем вы объявляется необходимую функцию (В данном случае CheckReverse), и пишете код, работающий так, как вам требуется.

После этого, в основной функции вы будете использовать не переменную типа CExpert, а переменную вашего, только что описанного типа. И при вызове у нее функции CheckReverse(), будет вызвана не функция предка из СБ, а ваша функция.

Лично я обычно все классы, используемые в коде, описываю в отдельных файлах. А потом - в основном файле просто включаю их в листинг директивой #include

Имейте ввиду, советники, сегенерированные автоматически с помощью классов Стандартной Библиотеки, имеют довольно сложную структуру, и требуют довольно длительного изучения.

YAndrey
77
YAndrey  
Laryx:

У вас в коде объявляется переменная типа CExpert. Это значит, что все функции будут взяты именно из этого класса.

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

То есть, вы должны объявить свой класс, наследни от CExpert. В нем вы объявляется необходимую функцию (В данном случае CheckReverse), и пишете код, работающий так, как вам требуется.

После этого, в основной функции вы будете использовать не переменную типа CExpert, а переменную вашего, только что описанного типа. И при вызове у нее функции CheckReverse(), будет вызвана не функция предка из СБ, а ваша функция.

Лично я обычно все классы, используемые в коде, описываю в отдельных файлах. А потом - в основном файле просто включаю их в листинг директивой #include

Имейте ввиду, советники, сегенерированные автоматически с помощью классов Стандартной Библиотеки, имеют довольно сложную структуру, и требуют довольно длительного изучения.

Не пугайте человека. Примитивные классы с примитивной логикой. Кстати - а неплохо бы создать действительно сложную систему классов сообща, а? Заведу новую тему, может разработчики нас поддержат, а?
George Merts
4864
George Merts  
YAndrey:
Не пугайте человека. Примитивные классы с примитивной логикой. Кстати - а неплохо бы создать действительно сложную систему классов сообща, а? Заведу новую тему, может разработчики нас поддержат, а?
В Стандартной Библиотеке МТ5 - вполне серьезная и достаточно сложная система классов. Она достаточно документирована, также имеется много статей с примерами кода. На мой взгляд, сейчас работа должна быть направлена на то, чтобы сделать СБ для МТ4, где полностью бы поддерживалась старая идеология. Увы, сейчас в СБ МТ4 нет торговых классов.
Sergey Sypalo
370
Sergey Sypalo  

Написал свой класс 

class MyExpert : public CExpert
{
  bool CheckReverse()
  {
    if (PositionSelect(Symbol()))
      return false;
    else return true;
  } }; 

Вынес в отдельный файл

В советнике подключил его через include

Тип переменной CExpert заменил на MyExpert

Скомпилировал, запустил, тот же эффект, при поступлении сигнала в противоположном направлении советник открывает новую сделку, закрывая имеющуюся (даже если в минус).

Грешил на

input int  Signal_Expiration = 4;           // Expiration of pnding orders (in bars) 

Но установка значения в 1000 то не решила всю проблему, но сейчас хотя бы не закрываются сделки старше 4х баров

Sergey Sypalo
370
Sergey Sypalo  

Сижу изучаю исходный код стандартной библиотеки классов, потихоньку приходит понимание. В общем нужно еще переопределить CheckOpenLong и CheckOpenShort. Еще довольно странно реализован трейлинг на фиксированном расстоянии. По умолчанию он трейлит только при формировании нового бара (а то я сразу не понял зачем в трейлинге понятие тейкпрофита).

По поводу классов для МТ4, да это было бы очень классно иметь такие же классы как и в МТ5. Конечно логика торговли отличается, но возможность использования классов дает абстраигироваться от имен предопределенных функций. Т.е. если не использовать хеджирование, можно было бы один и тот же код скомпилировать под МТ4 и МТ5 (конечно еще кучу ньюансов по поводу того же трейлинг стопа, или доливки в имеющуюся позицию). Эх городить еще можно кучу всего

George Merts
4864
George Merts  
ITeXPert:

Написал свой класс 

Все вроде верно. Я бы попробовал указать спецификацию virtual, а потом - поставил бы внутри функции точку останова (для прохождения в деббагере), или хотя бы Print, чтобы видеть, что управление вошло в ВАШУ функцию. Потому, что похоже на то, что управление по-прежнему вызывает функцию предка.
George Merts
4864
George Merts  
ITeXPert:

В общем нужно еще переопределить CheckOpenLong и CheckOpenShort.

Эти функции вызываются из ChekcOpen(), а если у вас открыта позиция - эта функция вызываться, вроде как не должна.

Sergey Sypalo
370
Sergey Sypalo  

Странно то что если я в своем классе переопределяю функцию CheckOpenLong() и CheckOpenLong()

bool CheckOpenLong()
{
   if(PositionSelect(Symbol())) //если удалось выбрать позицию, возвращаем false, чтобы не доливаться и не открываться в противоположном направлении
      if (PositionGetDouble(POSITION_PROFIT) > 50) return (true);
   return (false);
};

bool CheckOpenShort()
{
   if(PositionSelect(Symbol())) //если удалось выбрать позицию, возвращаем false, чтобы не доливаться и не открываться в противоположном направлении
      if (PositionGetDouble(POSITION_PROFIT) > 50) return (true);
   return (false);
};

 то советник вообще не входит в рынок, притом второй if можно не указывать, т.е. вся логика ломается об первое условие

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий