Обсуждение статьи "Кроссплатформенный торговый советник: Стоп-уровни"
Какой метод следует использовать для установки SL/TP на определенное значение, но не как расстояние от цены открытия?
Я попытался использовать несколько стопов в своем советнике. Добавил вашу функцию manage_trades() и вот что я получил после активации последнего стопа (позиция закрыта):
2017.09.10 09:48:25.706 2017.01.03 17:50:23 failed market buy 0.00 EURUSD [Invalid volume] 2017.09.10 09:48:25.706 2017.01.03 17:50:23 CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume] 2017.09.10 09:48:25.706 2017.01.03 17:50:23 position #2 is already closed, closing object.. 2017.09.10 09:48:25.706 2017.01.03 17:50:23 failed market buy 0.00 EURUSD [Invalid volume] 2017.09.10 09:48:25.706 2017.01.03 17:50:23 CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume] 2017.09.10 09:48:25.707 2017.01.03 17:50:23 position #2 is already closed, closing object.. 2017.09.10 09:48:25.707 2017.01.03 17:50:23 failed market buy 0.00 EURUSD [Invalid volume] 2017.09.10 09:48:25.707 2017.01.03 17:50:23 CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume]
Использую 3 стопа, все они виртуальные.
Это что-то с лотом. Я использую фиксированный лот 0.1. После первого закрытия оставшийся объем 0,06. После последнего закрытия (основной стоп без указанного объема) я получаю вышеуказанную ошибку.
Когда лот выше, все нормально. То же самое с вашими примерами советников.
Я попытался использовать несколько стопов в своем советнике. Добавил вашу функцию manage_trades() и вот что я получил после активации последнего стопа (позиция закрыта):
Использую 3 стопа, все они виртуальные.
Это что-то с лотом. Я использую фиксированный лот 0.1. После первого закрытия оставшийся объем 0,06. После последнего закрытия (основной стоп без указанного объема) я получаю вышеуказанную ошибку.
Когда лот выше, все нормально. То же самое и с вашими примерами советников.
Убедитесь, что вы используете последнюю версию библиотеки (ту, что прикреплена в этой статье). Также, если вы можете прикрепить исходный код вашего советника, это очень поможет.
Убедитесь, что вы используете последнюю версию библиотеки (та, что прикреплена в этой статье). Также, если вы можете прикрепить исходный код вашего советника, это очень поможет.
Да, я обновил все файлы, прикрепленные к этой статье. Но я не знаю, может быть, вы обновили их еще раз.
Не могли бы вы попробовать с вашим образцом stop_ha_ma2, изменив ММ на фиксированный лот и изменив размер лота на какое-то небольшое значение?
Да, я обновил все файлы, прикрепленные к этой статье. Но я не знаю, может быть, вы обновили их еще раз.
Не могли бы вы попробовать с вашим образцом stop_ha_ma2, изменив ММ на фиксированный лот и изменив размер лота на какое-то небольшое значение?
Не могли бы вы опубликовать здесь исходный код советника, в котором возникла эта проблема? Наш разговор публичный, и ошибка, которую вы опубликовали выше, является серьезной проблемой для советника. Я хотел бы, чтобы другие читатели тоже извлекли пользу из этого разговора, предоставив им возможность протестировать ваш код.
Это не связано с моим советником, так как я получил ту же ошибку с вашим советником. В любом случае, я установил его на другую копию терминала, и теперь он выглядит хорошо. Ошибки больше нет. Может быть, что-то не так со стандартной библиотекой или что-то еще...
Спасибо.
Это не связано с моим советником, так как я получил ту же ошибку с вашим советником. В любом случае, я установил его на другую копию терминала, и теперь он выглядит хорошо. Ошибки больше нет. Возможно, что-то не так с моей стандартной библиотекой или что-то еще...
Привет, Энрико,
Хотел обратить внимание, что нашел пару ошибок в вашем коде. в ExpertAdvisorBase функция Time имеет вид;
datetime CExpertAdvisorBase::Time(const int index=0) { if(index>=0) { double time[]; if(CopyTime(m_symbol_name,m_period,index,1,time)>0) return(time[0]); } return(-1); }
когда она должна быть такой, как показано ниже. Тип времени выше - double вместо datetime.
datetime CExpertAdvisorBase::Time(const int index=0) { if(index>=0) { datetime time[]; if(CopyTime(m_symbol_name,m_period,index,1,time)>0) return(time[0]); } return(-1); }
Кроме того, функция Evaluate в TimesBase не передает значение по умолчанию;
bool CTimesBase::Evaluate(datetime current) const
Если изменить на нижеприведенное, то так и должно быть;
bool CTimesBase::Evaluate(datetime current) const
При компиляции папки Base\Order файлы выдают множество ошибок.
Например, функция CreateStops в OrderBase, см. ниже;
void COrderBase::CreateStops(CStops *stops) { if(!CheckPointer(stops)) return; if(stops.Total()>0) { for(int i=0;i<stops.Total();i++) { CStop *stop=stops.At(i); if(CheckPointer(stop)==POINTER_INVALID) continue; m_order_stops.NewOrderStop(GetPointer(this),stop); } } }
Выбрасывает 'operator=' - ни одна из перегрузок не может быть применена к вызову функции OrderBase.mqh
'At' - ожидается указатель объекта OrderBase.mqh
Base\Stop также имеет те же проблемы с выбросом ряда ошибок, связанных со стопами, типами и т.д.
Спасибо за хорошую работу, Shep
Привет Энрико,
Хотел обратить внимание, что я нашел пару ошибок в вашем коде. В ExpertAdvisorBase функция Time имеет вид;
когда она должна быть такой, как показано ниже. Тип времени выше - double вместо datetime.
Привет, Энрико,
Кроме того, функция Evaluate в TimesBase не передает значение по умолчанию;
Если изменить ее на приведенную ниже, то она должна передавать;
Спасибо, что указали на это. Я не замечал этого до сих пор. Я обновлю код.
При компиляции папки Base\Order файлы выдают много ошибок.
Например, функция CreateStops в OrderBase, ниже;
Выбрасывает 'operator=' - ни одна из перегрузок не может быть применена к вызову функции OrderBase.mqh
'At' - ожидается указатель объекта OrderBase.mqh
Base\Stop также имеет те же проблемы с выбросом ряда ошибок, связанных со стопами, типами и т.д.
Спасибо за хорошую работу, Шеп.
Да, я знаю об этом. Это все еще связано с прямыми объявлениями. CStop требует в своих методах экземпляры COrder и COrderStop. То же самое происходит и при попытке скомпилировать CStop. Все эти классы, которые требуют друг друга, должны быть скомпилированы вместе. При компиляции каждого из них по отдельности будут возникать ошибки. Например:
class Object1 { public: Object2 *m_object2; Object1(){} ~Object1(){} }; class Object2 { public: Object1 *m_object1; Object2(){} ~Object2(){} };
This не скомпилируется. Вы должны объявить прямое объявление, чтобы компилятор распознал член класса m_object2 внутри класса Object1:
class Object2; class Object1 { public: Object2 *m_object2; Object1(){} ~Object1(){} }; class Object2 { public: Object1 *m_object1; Object2(){} ~Object2(){} };
Это нормально, если Object1 и Object2 находятся в одном файле. Если же они находятся в двух разных файлах, то вам нужно сделать прямое объявление для Object2 в файле класса Object1, а для Object1 - в файле класса Object 2. Тогда компилятор не выдаст ошибок, если вы скомпилируете любой из файлов. Это так, пока вы не добавите методы в один из двух классов.
Текущая версия компилятора распознает прямые объявления, но не перечисленные методы класса, объявленного прямо. Именно поэтому вы не получаете сообщений об ошибках типа "CStop - объявление без типа", но получаете сообщения об ошибках компилятора для методов, подобных тому, что вы опубликовали выше. Компилятор распознает класс, но не методы класса, который был объявлен прямо.
Опубликована статья Кроссплатформенный торговый советник: Стоп-уровни:
В этой статье рассматривается реализация стоп-уровней в торговом советнике, совместимая с платформами MetaTrader 4 и MetaTrader 5.
Операция по созданию стоп-уровней в общем виде показана на следующей картинке:

Как показано на двух предыдущих блок-схемах, новый экземпляр COrder создается сразу же после успешного открытия сделки. После этого для каждого установленного уровня стоп-лосса и тейк-профита создаются экземпляры COrderStop. Если при инициализации советника не объявлен экземпляр СStop, этот этап процесса пропускается. И наоборот, если созданы экземпляры COrderStop, указатели на них будут сохранены в ранее созданном экземпляре COrder.Автор: Enrico Lambino