class CFoo final { //--- тело класса }; class CBar : public CFoo { //--- тело класса };При попытке наследования от класса с модификатором final, как показано в примере выше, компилятор выдаст ошибку:
class CFoo { void virtual func(int x) const { } };Далее метод переопределяется в наследуемом классе:
class CBar : public CFoo { void func(short x) { } };Но по ошибке тип аргумента изменяется с int на short. Фактически, в этом случае уже происходит не переопределение, а перегрузка метода. Действуя в соответствии с алгоритмом определения перегруженной функции, в определенных ситуациях компилятор может выбрать метод, определенный в базовом классе, вместо переопределенного метода.
class CBar : public CFoo { void func(short x) override { } };Если при переопределении будет изменена сигнатура метода, компилятор не сможет найти в родительском классе метод с точной такой же сигнатурой и выдаст ошибку компиляции:
class CFoo { void virtual func(int x) final { } }; class CBar : public CFoo { void func(int) { } };При попытке переопределения метода с модификатором final, как показано в примере выше, компилятор выдаст ошибку:
class CFoo { }; class CBar { }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { void *vptr[2]; vptr[0]=new CFoo(); vptr[1]=new CBar(); //--- for(int i=0;i<ArraySize(vptr);i++) { if(dynamic_cast<CFoo *>(vptr[i])!=NULL) Print("CFoo * object at index ",i); if(dynamic_cast<CBar *>(vptr[i])!=NULL) Print("CBar * object at index ",i); } CFoo *fptr=vptr[1]; // выдаст ошибку приведения указателей, vptr[1] не является объектом CFoo } //+------------------------------------------------------------------+
string text="Hello"; ushort symb=text[0]; // вернет код символа 'H'
Обновлена документация.
Tester: Исправлен расчет комиссии в годовых процентах при тестировании.
Tester: Исправлен пересчет и отображение баланса на графике, формируемом в процессе тестирования.
После 2 месяцев публичного тестирования состоялся официальный выпуск веб-версии мультирыночной платформы MetaTrader 5. Она позволяет торговать на финансовых рынках в любом браузере и любой операционной системе. При этом не требуется устанавливать программу на компьютер, достаточно доступа в интернет и любого веб-браузера.
Приложение сочетает в себе ключевые преимущества десктопной платформы (скорость, мультирыночность и расширенные торговые функции) с удобством и кроссплатформенностью веб-решения. Важным новшеством релизной версии является стакан, который позволяет видеть глубину рынка, а также выставлять одним кликом рыночные и отложенные ордера.
Веб-платформа позволяет проводить технический анализ и совершать торговые
операции точно так же, как в десктопной версии. В приложении доступны:
Переносить SSL сертификаты из десктопной платформы в мобильную стало удобно. iTunes больше не нужен.
В MetaTrader 5 счета можно дополнительно защищать сертификатом, без которого подключение невозможно. Если сертификат был создан в десктопной версии, то для доступа к счету в мобильной платформе его нужно перенести.
Теперь для этого достаточно открыть десктопную платформу и правой кнопкой на счете в навигаторе выбрать перенос. Задать пароль для защиты сертификата, который будете знать только вы, затем открыть мобильную платформу и подключиться к счету. Вам сразу же предложат импортировать сертификат.
Помимо этого появился диалог миграции для счетов, перенесенных из MetaTrader 4. Если ваш счет перенесли в платформу 5-го поколения, вас горячо поприветствуют, расскажут о фишках и предложат поменять пароль.
Было |
Стало |
|
---|---|---|
Срабатывание | Все виды отложенных ордеров и SL/TP по Bid/Ask |
Лимитные ордера по Bid/Ask Стоп, стоп-лимитные и SL/TP ордера по Last |
Исполнение | Все виды отложенных ордеров и SL/TP по цене, заявленной в ордере |
Все виды отложенных ордеров и SL/TP по рыночным ценам Bid/Ask на момент срабатывания |
Рассмотрим
пример на инструменте Si-6.16. При текущих ценах Bid=72570, Ask=72572,
Last=72552 был выставлен ордер Buy Stop с ценой срабатывания 72580. В
ценовом потоке мы получили новые текущие цены:
На
биржевых инструментах триггером для срабатывания стоп-ордеров является
цена Last. Поэтому, поступление в потоке цены Last=72580 привело к
активации ордера Buy Stop. Ранее именно эта цена 72580 была бы
использована для исполнения данного ордера. Такое поведение было
некорректным, поскольку цены Ask=72580 для исполнения операции на
покупку на рынке нет.
Исправления по крешлогам.
По многочисленным просьбам трейдеров разработана веб-версия торговой платформы MetaTrader 5. Новинка сочетает в себе удобство и кроссплатформенность веб-терминала с преимуществами десктопной "пятерки" — скоростью, мультирыночностью, расширенными торговыми функциями.
Веб-платформа MetaTrader 5 стала доступной на сайте MQL5.community и позволяет торговать на финансовых рынках через любой браузер в любой операционной системе (Windows, Mac, Linux). Для этого не нужно устанавливать никаких программ, достаточно иметь доступ в интернет.
В бета-версии трейдерам сразу же доступны:
Неттинговая система
Эта
система учета подразумевает, что в один момент времени на счете может
быть только одна открытая позиция по одному и тому же символу:
При этом не имеет
значения, в результате какого действия совершается сделка в
противоположном направлении — в результате исполнения рыночного ордера
или срабатывания отложенного.
Ниже приведен пример совершения двух сделок на покупку EURUSD объемом 0.5 лота каждая:
Результатом исполнения этих сделок стала одна общая позиция объемом 1 лот.
Хеджинговая система
Эта
система учета позволяет иметь на счету множество торговых позиций по
одному и тому же инструменту, в том числе — разнонаправленных.
Если
по торговому инструменту есть открытая позиция и трейдер совершает
новую сделку (или срабатывает отложенный ордер), происходит открытие
новой позиции. Существующая позиция не изменяется.
Ниже приведен пример совершения двух сделок на покупку EURUSD объемом 0.5 лота каждая:
Результатом исполнения этих сделок стало открытие двух отдельных позиций.
Новый тип торговой операции Close By
Для
счетов с хеджинговым учетом позиций добавлен новый вид торговых
операций — закрытие позиции встречной. Эта операция позволяет
одновременно закрыть две разнонаправленные позиции по одному и тому же
инструменту. Если встречные позиции имеют разное количество лотов, то
открытым останется только один ордер из двух. Его объем будет равен
разности лотов двух закрытых позиций, а направление позиции и цена
открытия — большей (по объему) из закрываемых позиций.
По сравнению с одиночным закрытием двух позиций, закрытие встречной позволяет сэкономить трейдеру один спред:
При закрытии позиции встречной выставляется ордер типа "close by". В комментарии к нему указываются тикеты закрываемых позиций. Закрытие пары встречных позиций происходит двумя сделками типа "out by". Размер итоговой прибыли/убытка, полученного в результате закрытия обеих позиций, указывается только в одной сделке.
При импорте тикеты ордеров и позиций (в том числе ордеров истории) не
сохраняются, поскольку одной записи в торговой истории MetaTrader 4
может соответствовать до 4 записей в истории MetaTrader 5. Всем торговым
записям проставляются новые тикеты.
Номера счетов могут быть сохранены или заменены новыми в зависимости от того, как брокер произведет импорт.
При тестировании на реальных тиках через MQL5 Cloud Network может передаваться большой объем интернет-трафика. Это может существенно повлиять на итоговую стоимость использования вычислительной сети.
class CAnimal { public: CAnimal(); // конструктор virtual void Sound() = 0; // чисто виртуальная функция private: double m_legs_count; // количество ног животного };Здесь функция Sound() является чисто виртуальной, потому что она объявлена со спецификатором чисто виртуальной функции PURE (=0).
class CAnimal { public: virtual void Sound()=NULL; // PURE method, должен быть переопределен в потомке, сам класс CAnimal стал абстрактным и не может быть создан }; //--- потомок от абстрактного класса class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PURE переопределен, класс CCat не абстрактный и может быть создан }; //--- примеры неправильного использования new CAnimal; // ошибка 'CAnimal' - компилятор выдаст ошибку "cannot instantiate abstract class" CAnimal some_animal; // ошибка 'CAnimal' - компилятор выдаст ошибку "cannot instantiate abstract class" //--- примеры правильного использования new CCat; // ошибки нет - класс CCat не абстрактный CCat cat; // ошибки нет - класс CCat не абстрактныйОграничения на использование абстрактных классов
//+------------------------------------------------------------------+ //| Абстрактный базовый класс | //+------------------------------------------------------------------+ class CAnimal { public: //--- чисто виртуальная функция virtual void Sound(void)=NULL; //--- функция void CallSound(void) { Sound(); } //--- конструктор CAnimal() { //--- явный вызов виртуального метода Sound(); //--- неявный вызов (через третью функцию) CallSound(); //--- в конструкторе и/или деструкторе всегда вызываются свои функции, //--- несмотря на виртуальность и переопределение вызываемой функции в потомке //--- если вызываемая функция чисто виртуальная, то //--- вызов приведет к критической ошибке выполнения: "pure virtual function call" } };Однако конструкторы и деструкторы абстрактных классов могут вызывать другие функции-члены.
typedef int (*TFunc)(int,int);Теперь TFunc является типом и можно объявить переменную-указатель на функцию:
TFunc func_ptr;В переменную func_ptr можно сохранить адрес функции, чтобы в дальнейшем ее вызывать:
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // ошибка: neg не имеет тип int (int,int) Print(func_ptr(10)); // ошибка: должно быть два параметраУказатели на функции можно хранить и передавать в качестве параметра. Нельзя получить указатель на нестатический метод класса.
ulong PositionGetTicket( int index // номер в списке позиций );
bool PositionSelectByTicket(
ulong ticket // тикет позиции
);
Неттинговая система
Эта система учета подразумевает, что в один момент времени на счете может
быть только одна открытая позиция по одному и тому же символу:
При этом не имеет значения, в результате какого действия совершается сделка
в противоположном направлении — в результате исполнения рыночного ордера
или срабатывания отложенного.
Ниже приведен пример совершения двух сделок на покупку EURUSD объемом 0.5
лота каждая:
Результатом исполнения этих сделок стала одна общая позиция объемом 1
лот.
Хеджинговая система
Эта система учета позволяет иметь на счету множество торговых позиций по
одному и тому же инструменту, в том числе — разнонаправленных.
Если по торговому инструменту есть открытая позиция и трейдер совершает
новую сделку (или срабатывает отложенный ордер), происходит открытие новой
позиции. Существующая позиция не изменяется.
Ниже приведен пример совершения двух сделок на покупку EURUSD объемом 0.5
лота каждая:
Результатом исполнения этих сделок стало открытие двух отдельных позиций.
Новый тип торговой операции Close By
Для счетов с хеджинговым учетом позиций добавлен новый вид торговых операций
— закрытие позиции встречной. Эта операция позволяет одновременно закрыть
две разнонаправленные позиции по одному и тому же инструменту. Если встречные
позиции имеют разное количество лотов, то открытым останется только один
ордер из двух. Его объем будет равен разности лотов двух закрытых позиций,
а направление позиции и цена открытия — большей (по объему) из закрываемых
позиций.
По сравнению с одиночным закрытием двух позиций, закрытие встречной позволяет
сэкономить трейдеру один спред:
При закрытии позиции встречной выставляется ордер типа "close by". В комментарии к нему указываются тикеты закрываемых позиций. Закрытие пары встречных позиций происходит двумя сделками типа "out by". Размер итоговой прибыли/убытка, полученного в результате закрытия обеих позиций, указывается только в одной сделке.
class CAnimal { public: CAnimal(); // конструктор virtual void Sound() = 0; // чисто виртуальная функция private: double m_legs_count; // количество ног животного };Здесь функция Sound() является чисто виртуальной, потому что она объявлена со спецификатором чисто виртуальной функции PURE (=0).
class CAnimal { public: virtual void Sound()=NULL; // PURE method, должен быть переопределен в потомке, сам класс CAnimal стал абстрактным и не может быть создан }; //--- потомок от абстрактного класса class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PURE переопределен, класс CCat не абстрактный и может быть создан }; //--- примеры неправильного использования new CAnimal; // ошибка 'CAnimal' - компилятор выдаст ошибку "cannot instantiate abstract class" CAnimal some_animal; // ошибка 'CAnimal' - компилятор выдаст ошибку "cannot instantiate abstract class" //--- примеры правильного использования new CCat; // ошибки нет - класс CCat не абстрактный CCat cat; // ошибки нет - класс CCat не абстрактныйОграничения на использование абстрактных классов
//+------------------------------------------------------------------+ //| Абстрактный базовый класс | //+------------------------------------------------------------------+ class CAnimal { public: //--- чисто виртуальная функция virtual void Sound(void)=NULL; //--- функция void CallSound(void) { Sound(); } //--- конструктор CAnimal() { //--- явный вызов виртуального метода Sound(); //--- неявный вызов (через третью функцию) CallSound(); //--- в конструкторе и/или деструкторе всегда вызываются свои функции, //--- несмотря на виртуальность и переопределение вызываемой функции в потомке //--- если вызываемая функция чисто виртуальная, то //--- вызов приведет к критической ошибке выполнения: "pure virtual function call" } };Однако конструкторы и деструкторы абстрактных классов могут вызывать другие функции-члены.
typedef int (*TFunc)(int,int);Теперь TFunc является типом и можно объявить переменную-указатель на функцию:
TFunc func_ptr;В переменную func_ptr можно сохранить адрес функции, чтобы в дальнейшем ее вызывать:
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // ошибка: neg не имеет тип int (int,int) Print(func_ptr(10)); // ошибка: должно быть два параметраУказатели на функции можно хранить и передавать в качестве параметра. Нельзя получить указатель на нестатический метод класса.
ulong PositionGetTicket( int index // номер в списке позиций );
bool PositionSelectByTicket(
ulong ticket // тикет позиции
);
Новая система учета — как в MetaTrader 4. При этом трейдеры могут использовать все преимущества пятой версии платформы — исполнение ордеров несколькими сделками (в том числе — частичное), стоп-лимитные ордера и многое другое.
Торговлю с хеджированием можно попробовать сразу же после установки обновления. При открытии демо-счета включите опцию "Использовать хеджирование", она будет доступна, если торговый сервер брокера уже обновлен и настроен.
Новая система учета — как в MetaTrader 4. При этом трейдеры могут использовать все преимущества пятой версии платформы — исполнение ордеров несколькими сделками (в том числе — частичное), стоп-лимитные ордера и многое другое.
Торговлю с хеджированием можно попробовать сразу же после установки обновления. При открытии демо-счета включите опцию "Использовать хеджирование", она будет доступна, если торговый сервер брокера уже обновлен и настроен.
MetaEditor: В Мастер MQL5 добавлена ссылка на обучающий видеоролик "Как собрать торгового робота в Мастере MQL5". Посмотрите 3-минутное видео и создайте торгового робота, не написав ни одной строчки кода.