1) При поступлении сигнала на покупку/продаже советник не учитывает открыта ли позиция в противоположном направлении и открывает сделку в том направлении куда указывает сигнал, при этом если текущая позиция ушла в минус она закрывается с минусом. Можно ли как-то ограничить советник, чтобы он открывал сделку только если нет открытых сделок?
Я так понимаю, необходимо дополнить функцию bool CExpert::CheckReverse(void).
Сейчас в этой функции проверяется только тип позиции, и далее - управление передается функциям реверса в лонг или в шорт.
А вам необходимо в вашем классе CMyExpert, пронаследованном от CExpert перегрузить эту функцию - сперва проверить, если текущая позиция в просаде - сразу вернуть управление с fals'ом, не вызывая реверса в шорт или лонг.
2) Если я хочу "долиться" (открыть еще одну сделку в том же направлении что уже есть), то где это лучше всего сделать в событии OnTick? Идея проанализировать насколько далеко рынок ушел и долиться в убыточную сделку, тем самым приблизив ее цены к рыночной цене (чтобы быстрее ее закрыть, как только она будет в плюсе). Я понимаю что это похоже на мартингейл, но понятие мани-менеджмента мне не чуждо, объемы будут рассчитаны исходя из размера депозита
А можно для тех кто в танке, поподробнее как перегрузить функцию, документацию нашел - https://www.mql5.com/ru/docs/standardlibrary/expertclasses/expertbaseclasses/cexpert/cexpertcheckreverse
Но что-то воедино в голове все не укладывается, где именно перегружать (в коде). Обычно при создании класса это делал, а тут класс объявляется как переменная типа CExpert, это меня сбивает с толку (исходный код прилагается).
Как в OnTick доливку сделать буду позже ковырять, после того как решу проблему с первым вопросом
- www.mql5.com
Но что-то воедино в голове все не укладывается, где именно перегружать (в коде). Обычно при создании класса это делал, а тут класс объявляется как переменная типа CExpert, это меня сбивает с толку (исходный код прилагается).
У вас в коде объявляется переменная типа CExpert. Это значит, что все функции будут взяты именно из этого класса.
Перегрузка функций - это ситуация, когда одна и та же функция в классах-наследниках выполняет разные действия.
То есть, вы должны объявить свой класс, наследни от CExpert. В нем вы объявляется необходимую функцию (В данном случае CheckReverse), и пишете код, работающий так, как вам требуется.
После этого, в основной функции вы будете использовать не переменную типа CExpert, а переменную вашего, только что описанного типа. И при вызове у нее функции CheckReverse(), будет вызвана не функция предка из СБ, а ваша функция.
Лично я обычно все классы, используемые в коде, описываю в отдельных файлах. А потом - в основном файле просто включаю их в листинг директивой #include
Имейте ввиду, советники, сегенерированные автоматически с помощью классов Стандартной Библиотеки, имеют довольно сложную структуру, и требуют довольно длительного изучения.
У вас в коде объявляется переменная типа CExpert. Это значит, что все функции будут взяты именно из этого класса.
Перегрузка функций - это ситуация, когда одна и та же функция в классах-наследниках выполняет разные действия.
То есть, вы должны объявить свой класс, наследни от CExpert. В нем вы объявляется необходимую функцию (В данном случае CheckReverse), и пишете код, работающий так, как вам требуется.
После этого, в основной функции вы будете использовать не переменную типа CExpert, а переменную вашего, только что описанного типа. И при вызове у нее функции CheckReverse(), будет вызвана не функция предка из СБ, а ваша функция.
Лично я обычно все классы, используемые в коде, описываю в отдельных файлах. А потом - в основном файле просто включаю их в листинг директивой #include
Имейте ввиду, советники, сегенерированные автоматически с помощью классов Стандартной Библиотеки, имеют довольно сложную структуру, и требуют довольно длительного изучения.
Не пугайте человека. Примитивные классы с примитивной логикой. Кстати - а неплохо бы создать действительно сложную систему классов сообща, а? Заведу новую тему, может разработчики нас поддержат, а?
Написал свой класс
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х баров
Сижу изучаю исходный код стандартной библиотеки классов, потихоньку приходит понимание. В общем нужно еще переопределить CheckOpenLong и CheckOpenShort. Еще довольно странно реализован трейлинг на фиксированном расстоянии. По умолчанию он трейлит только при формировании нового бара (а то я сразу не понял зачем в трейлинге понятие тейкпрофита).
По поводу классов для МТ4, да это было бы очень классно иметь такие же классы как и в МТ5. Конечно логика торговли отличается, но возможность использования классов дает абстраигироваться от имен предопределенных функций. Т.е. если не использовать хеджирование, можно было бы один и тот же код скомпилировать под МТ4 и МТ5 (конечно еще кучу ньюансов по поводу того же трейлинг стопа, или доливки в имеющуюся позицию). Эх городить еще можно кучу всего
Написал свой класс
В общем нужно еще переопределить CheckOpenLong и CheckOpenShort.
Эти функции вызываются из ChekcOpen(), а если у вас открыта позиция - эта функция вызываться, вроде как не должна.
Странно то что если я в своем классе переопределяю функцию 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 можно не указывать, т.е. вся логика ломается об первое условие
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Привет всем,
Решил таки еще раз взяться за МТ5, только теперь уже за написание/переписывание советника под MQL5. Первое что сделал, это сравнил исходный код примеров советников и автоматически сгенерированного советника.
Разница в том, что в примере советника многие вещи типа трейлинг стопа и еще кучу всего делаются вручную, в автоматически сгенерированном советнике объявляется объект унаследованный от CEXpert, добавляются фильтры и собственно все.
В принципе мне понравился подход используемый при генерации советника, но остались некоторые вопросы:
1) При поступлении сигнала на покупку/продаже советник не учитывает открыта ли позиция в противоположном направлении и открывает сделку в том направлении куда указывает сигнал, при этом если текущая позиция ушла в минус она закрывается с минусом. Можно ли как-то ограничить советник, чтобы он открывал сделку только если нет открытых сделок?
2) Если я хочу "долиться" (открыть еще одну сделку в том же направлении что уже есть), то где это лучше всего сделать в событии OnTick? Идея проанализировать насколько далеко рынок ушел и долиться в убыточную сделку, тем самым приблизив ее цены к рыночной цене (чтобы быстрее ее закрыть, как только она будет в плюсе). Я понимаю что это похоже на мартингейл, но понятие мани-менеджмента мне не чуждо, объемы будут рассчитаны исходя из размера депозита