Библиотека для простого и быстрого создания программ для MetaTrader (Часть XVIII): Интерактивность объекта-аккаунт и любых других объектов библиотеки
Содержание
- Доработка базового объекта и объекта-символа
- Ставим объект-аккаунт на новые рельсы
- Тестирование установки параметров отслеживания и получения событий объектов
- Что дальше
Мы создали базовый объект, от которого будем наследовать все остальные объекты библиотеки, которым необходим событийный функционал. Теперь задавать параметры отслеживаемых событий и получать их от объектов стало очень просто — всё делается в базовом классе и для всех его объектов-наследников необходимо провести одинаковые действия по установке отслеживаемых свойств и значений, которые хотим отслеживать в свойствах объекта.
Сегодня немного доработаем базовый объект и подключим к нему объект-аккаунт. Также мы протестируем возможность задания нужных для
отслеживания свойств разных объектов и их значений на примере тестового советника.
В прошлой статье при создании методов базового объекта CBaseObj и методов
его наследника — объекта-символа — я, скажем так, немного увлёкся и сделал набор методов в двух классах, которые фактически дублируют друг
друга. Исправим данное недоразумение — просто удалим методы установки и получения свойств из класса объекта-наследника CSymbol, и
упорядочим методы базового объекта CBaseObj.
Доработка базового объекта и объекта-символа
Откроем файл \MQL5\Include\DoEasy\Objects\BaseObj.mqh и внесём в него некоторые правки.
Метод CheckEvents() из класса CSymbol перенесём в базовый класс CBaseObj, так как этот метод
абсолютно идентичен для любых объектов-наследников базового класса, а значит — ему самое место в базовом классе.
Впишем его определение в защищённую секцию класса
CBaseObj:
protected: CArrayObj m_list_events_base; // Список базовых событий объекта CArrayObj m_list_events; // Список событий объекта MqlTick m_tick; // Структура тика для получения котировочных данных double m_hash_sum; // Хэш-сумма данных объекта double m_hash_sum_prev; // Хэш-сумма данных объекта на прошлой проверке int m_digits_currency; // Число знаков после запятой валюты счёта int m_global_error; // Код глобальной ошибки long m_chart_id; // Идентификатор графика управляющей программы bool m_is_event; // Флаг события объекта int m_event_code; // Код события объекта int m_event_id; // Идентификатор события (равен значению свойства объекта) string m_name; // Наименование объекта string m_folder_name; // Имя папки хранения объектов-наследников CBaseObj bool m_first_start; // Флаг первого запуска int m_type; // Тип объекта (соответствует идентификаторам коллекций) //--- Данные для хранения, контроля и возврата отслеживаемых свойств: //--- [Индекс свойства][0] Контролируемая величина прироста значения свойства //--- [Индекс свойства][1] Контролируемая величина уменьшения значения свойства //--- [Индекс свойства][2] Контрольный уровень значения свойства //--- [Индекс свойства][3] Значение свойства //--- [Индекс свойства][4] Величина изменения значения свойства //--- [Индекс свойства][5] Флаг изменения значения свойства больше, чем на величину прироста //--- [Индекс свойства][6] Флаг изменения значения свойства больше, чем на величину уменьшения //--- [Индекс свойства][7] Флаг увеличения значения свойства больше контрольного уровня //--- [Индекс свойства][8] Флаг уменьшения значения свойства меньше контрольного уровня //--- [Индекс свойства][9] Флаг равенства значения свойства контрольному уровню long m_long_prop_event[][CONTROLS_TOTAL]; // Массив для хранения величин целочисленных свойств объекта и контролируемых значений изменения свойств double m_double_prop_event[][CONTROLS_TOTAL]; // Массив для хранения величин вещественных свойств объекта и контролируемых значений изменения свойств long m_long_prop_event_prev[][CONTROLS_TOTAL]; // Массив для хранения величин контролируемых целочисленных свойств объекта на прошлой проверке double m_double_prop_event_prev[][CONTROLS_TOTAL]; // Массив для хранения величин контролируемых вещественных свойств объекта на прошлой проверке //--- Возвращает (1) время в милисекундах, (2) милисекунды из значения времени из MqlTick long TickTime(void) const { return #ifdef __MQL5__ this.m_tick.time_msc #else this.m_tick.time*1000 #endif ; } ushort MSCfromTime(const long time_msc) const { return #ifdef __MQL5__ ushort(this.TickTime()%1000) #else 0 #endif ; } //--- возвращает факт наличия кода события в событии объекта bool IsPresentEventFlag(const int change_code) const { return (this.m_event_code & change_code)==change_code; } //--- Возвращает число знаков после запятой валюты счёта int DigitsCurrency(void) const { return this.m_digits_currency; } //--- Возвращает количество знаков после запятой в double-значении int GetDigits(const double value) const; //--- Устанавливает размер массива (1) целочисленных, (2) вещественных контролируемых свойств объекта bool SetControlDataArraySizeLong(const int size); bool SetControlDataArraySizeDouble(const int size); //--- Проверяет размер массива свойств объекта bool CheckControlDataArraySize(bool check_long=true); //--- Проверяет список изменений свойств символа и создаёт событие void CheckEvents(void); //--- (1) Упаковывает ushort-число в переданное long-число //--- (2) преобразует ushort-значение в заданный байт long-числа long UshortToLong(const ushort ushort_value,const uchar to_byte,long &long_value); protected: long UshortToByte(const ushort value,const uchar index) const; public:
Из публичной секции удалим методы, устанавливающие значения флагам событий — события происходят независимо от нашего желания, и флаги устанавливаются без участия пользователя. Поэтому держать методы для принудительной установки флагов событий мне кажется совершенно нецелосообразным:
//--- Устанавливает Флаг изменения значения свойства больше, чем на величину (1) прироста, (2) уменьшения
template<typename T> void SetControlledFlagINC(const int property,const T value);
template<typename T> void SetControlledFlagDEC(const int property,const T value);
//--- Устанавливает Флаг изменения значения свойства (1) больше, (2) меньше контрольного уровня, (3) равенства уровню
template<typename T> void SetControlledFlagMORE(const int property,const T value);
template<typename T> void SetControlledFlagLESS(const int property,const T value);
template<typename T> void SetControlledFlagEQUAL(const int property,const T value);
Методы, возвращающие установленные пользователем контролируемые величины свойств объектов, текущее значение свойств объектов, и величин
изменений свойств объектов,
теперь будут носить более удобочитаемые и осмысленные наименования:
//--- Возвращает установленную величину контролируемого приращения (1) целочисленных, (2) вещественных свойств объекта long GetControlledLongValueINC(const int property) const { return this.m_long_prop_event[property][0]; } double GetControlledDoubleValueINC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][0]; } //--- Возвращает установленную величину контролируемого уменьшения (1) целочисленных, (2) вещественных свойств объекта long GetControlledLongValueDEC(const int property) const { return this.m_long_prop_event[property][1]; } double GetControlledDoubleValueDEC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][1]; } //--- Возвращает установленный контрольный уровень (1) целочисленных, (2) вещественных свойств объекта long GetControlledLongValueLEVEL(const int property) const { return this.m_long_prop_event[property][2]; } double GetControlledDoubleValueLEVEL(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][2]; } //--- Возвращает текущее значение (1) целочисленного, (2) вещественного свойства объекта long GetPropLongValue(const int property) const { return this.m_long_prop_event[property][3]; } double GetPropDoubleValue(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][3]; } //--- Возвращает величину изменения контролируемого (1) целочисленного, (2) вещественного свойства объекта long GetPropLongChangedValue(const int property) const { return this.m_long_prop_event[property][4]; } double GetPropDoubleChangedValue(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][4]; } //--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства больше, чем на величину прироста long GetPropLongFlagINC(const int property) const { return this.m_long_prop_event[property][5]; } double GetPropDoubleFlagINC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][5]; } //--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства больше, чем на величину уменьшения long GetPropLongFlagDEC(const int property) const { return this.m_long_prop_event[property][6]; } double GetPropDoubleFlagDEC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][6]; } //--- Возвращает Флаг увеличения значения (1) целочисленного, (2) вещественного свойства больше контрольного уровня long GetPropLongFlagMORE(const int property) const { return this.m_long_prop_event[property][7]; } double GetPropDoubleFlagMORE(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][7]; } //--- Возвращает Флаг уменьшения значения (1) целочисленного, (2) вещественного свойства меньше контрольного уровня long GetPropLongFlagLESS(const int property) const { return this.m_long_prop_event[property][8]; } double GetPropDoubleFlagLESS(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][8]; } //--- Возвращает Флаг равенства значений (1) целочисленного, (2) вещественного свойства и контрольного уровня long GetPropLongFlagEQUAL(const int property) const { return this.m_long_prop_event[property][9]; } double GetPropDoubleFlagEQUAL(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][9]; }
При углубленном тестировании событийного функционала базового объекта CBaseObj были замечены ошибки при определении
событий. Оказалось, что в методе заполнения свойств базового объекта и поиска событий
FillPropertySettings() была допущена неточность — в любом случае в самом конце метода текущее состояние свойств записывалось в
прошлое состояние. Это не давало определить величину изменения свойств, так как вновь полученное значение свойства сразу же
записывалось в прошлое. При малых значениях контролируемого изменения эта ошибка не проявлялась, так как свойство успевало за один раз
измениться на величину, больше, чем задано для генерации события.
Но когда необходимо было отследить изменение на достаточно большую величину, которое происходит не за один тик, то в данном случае
этого сделать было невозможно.
Теперь внесены правки — текущее состояние записывается в прошлое
только при регистрации события:
//+------------------------------------------------------------------+ //| Заполняет массив свойств объекта | //+------------------------------------------------------------------+ template<typename T> bool CBaseObj::FillPropertySettings(const int index,T &array[][CONTROLS_TOTAL],T &array_prev[][CONTROLS_TOTAL],int &event_id) { //--- Данные в ячейках массива //--- [Индекс свойства][0] Контролируемая величина прироста значения свойства //--- [Индекс свойства][1] Контролируемая величина уменьшения значения свойства //--- [Индекс свойства][2] Контрольный уровень значения свойства //--- [Индекс свойства][3] Значение свойства //--- [Индекс свойства][4] Величина изменения значения свойства //--- [Индекс свойства][5] Флаг изменения значения свойства больше, чем на величину прироста //--- [Индекс свойства][6] Флаг изменения значения свойства больше, чем на величину уменьшения //--- [Индекс свойства][7] Флаг увеличения значения свойства больше контрольного уровня //--- [Индекс свойства][8] Флаг уменьшения значения свойства меньше контрольного уровня //--- [Индекс свойства][9] Флаг равенства значения свойства контрольному уровню //--- Устанавливаем смещение индекса double-свойства и задаём идентификатор события event_id=index+(typename(T)=="double" ? this.m_long_prop_total : 0); //--- Обнуляем все флаги событий for(int j=5;j<CONTROLS_TOTAL;j++) array[index][j]=false; //--- Величина изменения свойства T value=array[index][3]-array_prev[index][3]; array[index][4]=value; //--- Если контролируемая величина прироста значения свойства установлена if(array[index][0]<LONG_MAX) { //--- Если величина изменения свойства больше контролируемой величины увеличения - есть событие, //--- добавляем событие в список, ставим флаг и сохраняем новый размер значения свойства if(value>0 && value>array[index][0]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_INC,value)) { array[index][5]=true; array_prev[index][4]=value; } //--- Сохраняем текущее значение свойства как прошлое array_prev[index][3]=array[index][3]; } } //--- Если контролируемая величина уменьшения значения свойства установлена if(array[index][1]<LONG_MAX) { //--- Если величина изменения свойства больше контролируемой величины уменьшения - есть событие, //--- добавляем событие в список, ставим флаг и сохраняем новый размер значения свойства if(value<0 && fabs(value)>array[index][1]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_DEC,value)) { array[index][6]=true; array_prev[index][4]=value; } //--- Сохраняем текущее значение свойства как прошлое array_prev[index][3]=array[index][3]; } } //--- Если значение контролируемого уровня установлено if(array[index][2]<LONG_MAX) { value=array[index][3]-array[index][2]; //--- Если значение свойства стало больше контрольного уровня - есть событие, //--- добавляем событие в список и ставим флаг if(value>0 && array_prev[index][3]<=array[index][2]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_MORE_THEN,array[index][2])) array[index][7]=true; //--- Сохраняем текущее значение свойства как прошлое array_prev[index][3]=array[index][3]; } //--- Если значение свойства стало меньше контрольного уровня - есть событие, //--- добавляем событие в список и ставим флаг else if(value<0 && array_prev[index][3]>=array[index][2]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_LESS_THEN,array[index][2])) array[index][8]=true; //--- Сохраняем текущее значение свойства как прошлое array_prev[index][3]=array[index][3]; } //--- Если значение свойства стало равно контрольному уровню - есть событие, //--- добавляем событие в список и ставим флаг else if(value==0 && array_prev[index][3]!=array[index][2]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_EQUALS,array[index][2])) array[index][9]=true; //--- Сохраняем текущее значение свойства как прошлое array_prev[index][3]=array[index][3]; } } return true; } //+------------------------------------------------------------------+
В методе инициализации свойств базового объекта ранее свойства инициализировались значениями LONG_MAX,
теперь инициализировать значения будем нулём:
//+------------------------------------------------------------------+ //| Сбрасывает переменные отслеживаемых данных объекта | //+------------------------------------------------------------------+ void CBaseObj::ResetChangesParams(void) { if(!this.CheckControlDataArraySize(true) || !this.CheckControlDataArraySize(false)) return; this.m_list_events.Clear(); this.m_list_events.Sort(); this.m_list_events_base.Clear(); this.m_list_events_base.Sort(); //--- Данные в ячейках массива //--- [Индекс свойства][3] Значение свойства //--- [Индекс свойства][4] Величина изменения значения свойства //--- [Индекс свойства][5] Флаг изменения значения свойства больше, чем на величину прироста //--- [Индекс свойства][6] Флаг изменения значения свойства больше, чем на величину уменьшения //--- [Индекс свойства][7] Флаг увеличения значения свойства больше контрольного уровня //--- [Индекс свойства][8] Флаг уменьшения значения свойства меньше контрольного уровня //--- [Индекс свойства][9] Флаг равенства значения свойства контролируемому значению for(int i=this.m_long_prop_total-1;i>WRONG_VALUE;i--) for(int j=3; j<CONTROLS_TOTAL; j++) this.m_long_prop_event[i][j]=0; for(int i=this.m_double_prop_total-1;i>WRONG_VALUE;i--) for(int j=3; j<CONTROLS_TOTAL; j++) this.m_double_prop_event[i][j]=0; } //+------------------------------------------------------------------+
Впишем реализацию метода CheckEvents(), перенесённого из CSymbol:
//+------------------------------------------------------------------+ //| Проверяет список изменений свойств объекта и создаёт событие | //+------------------------------------------------------------------+ void CBaseObj::CheckEvents(void) { int total=this.m_list_events_base.Total(); if(total==0) return; for(int i=0;i<total;i++) { CBaseEvent *event=this.GetEventBase(i); if(event==NULL) continue; long lvalue=0; this.UshortToLong(this.MSCfromTime(this.TickTime()),0,lvalue); this.UshortToLong(event.Reason(),1,lvalue); this.UshortToLong((ushort)this.m_type,2,lvalue); if(this.EventAdd((ushort)event.ID(),lvalue,event.Value(),this.m_name)) this.m_is_event=true; } } //+------------------------------------------------------------------+
Внесём исправления в класс объекта-символа CSymbol.
Откроем файл \MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqh и
внесём изменения.
Из приватной секции класса удалим два метода:
private: struct MqlMarginRate { double Initial; // коэффициент взимания начальной маржи double Maintenance; // коэффициент взимания поддерживающей маржи }; struct MqlMarginRateMode { MqlMarginRate Long; // MarginRate длинных позиций MqlMarginRate Short; // MarginRate коротких позиций MqlMarginRate BuyStop; // MarginRate BuyStop-ордеров MqlMarginRate BuyLimit; // MarginRate BuyLimit-ордеров MqlMarginRate BuyStopLimit; // MarginRate BuyStopLimit-ордеров MqlMarginRate SellStop; // MarginRate SellStop-ордеров MqlMarginRate SellLimit; // MarginRate SellLimit-ордеров MqlMarginRate SellStopLimit; // MarginRate SellStopLimit-ордеров }; MqlMarginRateMode m_margin_rate; // Структура коэффициентов взимания маржи MqlBookInfo m_book_info_array[]; // Массив структур данных стакана long m_long_prop[SYMBOL_PROP_INTEGER_TOTAL]; // Целочисленные свойства double m_double_prop[SYMBOL_PROP_DOUBLE_TOTAL]; // Вещественные свойства string m_string_prop[SYMBOL_PROP_STRING_TOTAL]; // Строковые свойства bool m_is_change_trade_mode; // Флаг изменения режима торговли для символа //--- Инициализирует переменные контролируемых данных символа virtual void InitControlsParams(void); //--- Проверяет список изменений свойств символа и создаёт событие void CheckEvents(void);
Метод инициализации контролируемых данных не нужен, так как все необходимые для отслеживания свойства и параметры для любого класса на основе базового объекта нужно производить явным указанием значений отслеживаемых параметров, а по умолчанию никакие изменения свойств объектов-наследников не отслеживаются. Метод CheckEvents() мы уже перенесли отсюда в базовый класс CBaseObj.
Из публичной секции класса удалим методы, которые фактически дублировали методы базового объекта:
public: //--- Устанавливает величину изменения контролируемого свойства символа template<typename T> void SetControlChangedValue(const int property,const T value); //--- Устанавливает величину контролируемого (1) приращения, (2) уменьшения свойства символа, (3) контрольного уровня template<typename T> void SetControlPropertyINC(const int property,const T value); template<typename T> void SetControlPropertyDEC(const int property,const T value); template<typename T> void SetControlPropertyLEVEL(const int property,const T value); //--- Устанавливает Флаг изменения значения свойства символа больше, чем на величину (1) прироста, (2) уменьшения template<typename T> void SetControlFlagINC(const int property,const T value); template<typename T> void SetControlFlagDEC(const int property,const T value); //--- Возвращает установленную величину контролируемого приращения (1) целочисленного, (2) вещественного свойства символа long GetControlParameterINC(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledValueLongINC(property); } double GetControlParameterINC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledValueDoubleINC(property); } //--- Возвращает установленную величину контролируемого уменьшения (1) целочисленного, (2) вещественного свойства символа long GetControlParameterDEC(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledValueLongDEC(property); } double GetControlParameterDEC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledValueDoubleDEC(property); } //--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства символа больше, чем на величину прироста long GetControlFlagINC(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledFlagLongINC(property); } double GetControlFlagINC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledFlagDoubleINC(property); } //--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства символа больше, чем на величину уменьшения bool GetControlFlagDEC(const ENUM_SYMBOL_PROP_INTEGER property) const { return (bool)this.GetControlledFlagLongDEC(property); } bool GetControlFlagDEC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return (bool)this.GetControlledFlagDoubleDEC(property); } //--- Возвращает величину изменения контролируемого (1) целочисленного, (2) вещественного свойства объекта long GetControlChangedValue(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledChangedValueLong(property); } double GetControlChangedValue(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledChangedValueDouble(property); }
Методы получения и установки параметров отслеживаемых свойств символа теперь для возврата значений напрямую используют методы базового
класса. Просто приведу
список методов:
//+------------------------------------------------------------------+ //| Получение и установка параметров отслеживаемых изменений свойств | //+------------------------------------------------------------------+ //--- Исполнение //--- Флаг изменения режима торговли для символа bool IsChangedTradeMode(void) const { return this.m_is_change_trade_mode; } //--- Сделки текущей сессии //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества сделок в текущую сессию //--- получение (3) величины изменения количества сделок в текущую сессию, //--- получение флага изменения количества сделок в текущую сессию больше, чем на величину (4) прироста, (5) уменьшения void SetControlSessionDealsInc(const long value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value)); } void SetControlSessionDealsDec(const long value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value)); } void SetControlSessionDealsLevel(const long value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value)); } long GetValueChangedSessionDeals(void) const { return this.GetPropLongChangedValue(SYMBOL_PROP_SESSION_DEALS); } bool IsIncreasedSessionDeals(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SESSION_DEALS); } bool IsDecreasedSessionDeals(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SESSION_DEALS); } //--- Ордера Buy текущей сессии //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества Buy-ордеров в текущий момент //--- получение (4) величины изменения количества Buy-ордеров в текущий момент, //--- получение флага изменения количества Buy-ордеров в текущий момент больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionBuyOrdInc(const long value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value)); } void SetControlSessionBuyOrdDec(const long value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value)); } void SetControlSessionBuyOrdLevel(const long value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value)); } long GetValueChangedSessionBuyOrders(void) const { return this.GetPropLongChangedValue(SYMBOL_PROP_SESSION_BUY_ORDERS); } bool IsIncreasedSessionBuyOrders(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SESSION_BUY_ORDERS); } bool IsDecreasedSessionBuyOrders(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SESSION_BUY_ORDERS); } //--- Ордера Sell текущей сессии //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества Sell-ордеров в текущий момент //--- получение (4) величины изменения количества Sell-ордеров в текущий момент, //--- получение флага изменения количества Sell-ордеров в текущий момент больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionSellOrdInc(const long value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value)); } void SetControlSessionSellOrdDec(const long value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value)); } void SetControlSessionSellOrdLevel(const long value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value));} long GetValueChangedSessionSellOrders(void) const { return this.GetPropLongChangedValue(SYMBOL_PROP_SESSION_SELL_ORDERS); } bool IsIncreasedSessionSellOrders(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SESSION_SELL_ORDERS); } bool IsDecreasedSessionSellOrders(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SESSION_SELL_ORDERS); } //--- Объем в последней сделке //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня объема в последней сделке //--- получение (4) величины изменения объема в последней сделке, //--- получение флага изменения объема в последней сделке больше, чем на величину (5) прироста, (6) уменьшения void SetControlVolumeInc(const long value) { this.SetControlledValueINC(SYMBOL_PROP_VOLUME,(long)::fabs(value)); } void SetControlVolumeDec(const long value) { this.SetControlledValueDEC(SYMBOL_PROP_VOLUME,(long)::fabs(value)); } void SetControlVolumeLevel(const long value) { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUME,(long)::fabs(value)); } long GetValueChangedVolume(void) const { return this.GetPropLongChangedValue(SYMBOL_PROP_VOLUME); } bool IsIncreasedVolume(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_VOLUME); } bool IsDecreasedVolume(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_VOLUME); } //--- Максимальный Volume за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального объема за день //--- получение (4) величины изменения максимального объема за день, //--- получение флага изменения максимального объема за день больше, чем на величину (5) прироста, (6) уменьшения void SetControlVolumeHighInc(const long value) { this.SetControlledValueINC(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value)); } void SetControlVolumeHighDec(const long value) { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value)); } void SetControlVolumeHighLevel(const long value) { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value)); } long GetValueChangedVolumeHigh(void) const { return this.GetPropLongChangedValue(SYMBOL_PROP_VOLUMEHIGH); } bool IsIncreasedVolumeHigh(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_VOLUMEHIGH); } bool IsDecreasedVolumeHigh(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_VOLUMEHIGH); } //--- Минимальный Volume за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального объема за день //--- получение (4) величины изменения минимального объема за день, //--- получение флага изменения минимального объема за день больше, чем на величину (5) прироста, (6) уменьшения void SetControlVolumeLowInc(const long value) { this.SetControlledValueINC(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value)); } void SetControlVolumeLowDec(const long value) { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value)); } void SetControlVolumeLowLevel(const long value) { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value)); } long GetValueChangedVolumeLow(void) const { return this.GetPropLongChangedValue(SYMBOL_PROP_VOLUMELOW); } bool IsIncreasedVolumeLow(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_VOLUMELOW); } bool IsDecreasedVolumeLow(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_VOLUMELOW); } //--- Спред //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня спреда в пунктах //--- получение (4) величины изменения спреда в пунктах, //--- получение флага изменения спреда в пунктах больше, чем на величину (5) прироста, (6) уменьшения void SetControlSpreadInc(const int value) { this.SetControlledValueINC(SYMBOL_PROP_SPREAD,(long)::fabs(value)); } void SetControlSpreadDec(const int value) { this.SetControlledValueDEC(SYMBOL_PROP_SPREAD,(long)::fabs(value)); } void SetControlSpreadLevel(const int value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SPREAD,(long)::fabs(value)); } int GetValueChangedSpread(void) const { return (int)this.GetPropLongChangedValue(SYMBOL_PROP_SPREAD); } bool IsIncreasedSpread(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SPREAD); } bool IsDecreasedSpread(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SPREAD); } //--- StopLevel //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня StopLevel в пунктах //--- получение (4) величины изменения StopLevel в пунктах, //--- получение флага изменения StopLevel в пунктах больше, чем на величину (5) прироста, (6) уменьшения void SetControlStopLevelInc(const int value) { this.SetControlledValueINC(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value)); } void SetControlStopLevelDec(const int value) { this.SetControlledValueDEC(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value)); } void SetControlStopLevelLevel(const int value) { this.SetControlledValueLEVEL(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value)); } int GetValueChangedStopLevel(void) const { return (int)this.GetPropLongChangedValue(SYMBOL_PROP_TRADE_STOPS_LEVEL); } bool IsIncreasedStopLevel(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_TRADE_STOPS_LEVEL); } bool IsDecreasedStopLevel(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_TRADE_STOPS_LEVEL); } //--- Дистанция заморозки //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня FreezeLevel в пунктах //--- получение (4) величины изменения FreezeLevel в пунктах, //--- получение флага изменения FreezeLevel в пунктах больше, чем на величину (5) прироста, (6) уменьшения void SetControlFreezeLevelInc(const int value) { this.SetControlledValueINC(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value)); } void SetControlFreezeLevelDec(const int value) { this.SetControlledValueDEC(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value)); } void SetControlFreezeLevelLevel(const int value) { this.SetControlledValueLEVEL(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value)); } int GetValueChangedFreezeLevel(void) const { return (int)this.GetPropLongChangedValue(SYMBOL_PROP_TRADE_FREEZE_LEVEL); } bool IsIncreasedFreezeLevel(void) const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_TRADE_FREEZE_LEVEL); } bool IsDecreasedFreezeLevel(void) const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_TRADE_FREEZE_LEVEL); } //--- Bid //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Bid //--- получение (4) величины изменения цены Bid или Last, //--- получение флага изменения цены Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlBidInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_BID,::fabs(value)); } void SetControlBidDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_BID,::fabs(value)); } void SetControlBidLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_BID,::fabs(value)); } double GetValueChangedBid(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_BID); } bool IsIncreasedBid(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BID); } bool IsDecreasedBid(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BID); } //--- Максимальный Bid за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Bid //--- получение (4) величины изменения максимального Bid или Last, //--- получение флага изменения максимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlBidHighInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_BIDHIGH,::fabs(value)); } void SetControlBidHighDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_BIDHIGH,::fabs(value)); } void SetControlBidHighLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_BIDHIGH,::fabs(value)); } double GetValueChangedBidHigh(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDHIGH); } bool IsIncreasedBidHigh(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDHIGH); } bool IsDecreasedBidHigh(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDHIGH); } //--- Минимальный Bid за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Bid //--- получение (4) величины изменения минимального Bid или Last, //--- получение флага изменения минимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlBidLowInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_BIDLOW,::fabs(value)); } void SetControlBidLowDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_BIDLOW,::fabs(value)); } void SetControlBidLowLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_BIDLOW,::fabs(value)); } double GetValueChangedBidLow(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDLOW); } bool IsIncreasedBidLow(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDLOW); } bool IsDecreasedBidLow(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDLOW); } //--- Last //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Last //--- получение (4) величины изменения цены Bid или Last, //--- получение флага изменения цены Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlLastInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_LAST,::fabs(value)); } void SetControlLastDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_LAST,::fabs(value)); } void SetControlLastLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_LAST,::fabs(value)); } double GetValueChangedLast(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_LAST); } bool IsIncreasedLast(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LAST); } bool IsDecreasedLast(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LAST); } //--- Максимальный Last за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Last //--- получение (4) величины изменения максимального Bid или Last, //--- получение флага изменения максимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlLastHighInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_LASTHIGH,::fabs(value)); } void SetControlLastHighDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_LASTHIGH,::fabs(value)); } void SetControlLastHighLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_LASTHIGH,::fabs(value)); } double GetValueChangedLastHigh(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTHIGH); } bool IsIncreasedLastHigh(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTHIGH); } bool IsDecreasedLastHigh(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTHIGH); } //--- Минимальный Last за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Last //--- получение (4) величины изменения минимального Bid или Last, //--- получение флага изменения минимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlLastLowInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_LASTLOW,::fabs(value)); } void SetControlLastLowDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_LASTLOW,::fabs(value)); } void SetControlLastLowLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_LASTLOW,::fabs(value)); } double GetValueChangedLastLow(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTLOW); } bool IsIncreasedLastLow(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTLOW); } bool IsDecreasedLastLow(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTLOW); } //--- Bid/Last //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Bid или Last //--- получение (4) величины изменения цены Bid или Last, //--- получение флага изменения цены Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlBidLastInc(const double value); void SetControlBidLastDec(const double value); void SetControlBidLastLevel(const double value); double GetValueChangedBidLast(void) const; bool IsIncreasedBidLast(void) const; bool IsDecreasedBidLast(void) const; //--- Максимальный Bid/Last за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Bid или Last //--- получение (4) величины изменения максимального Bid или Last, //--- получение флага изменения максимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlBidLastHighInc(const double value); void SetControlBidLastHighDec(const double value); void SetControlBidLastHighLevel(const double value); double GetValueChangedBidLastHigh(void) const; bool IsIncreasedBidLastHigh(void) const; bool IsDecreasedBidLastHigh(void) const; //--- Минимальный Bid/Last за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Bid или Last //--- получение (4) величины изменения минимального Bid или Last, //--- получение флага изменения минимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения void SetControlBidLastLowInc(const double value); void SetControlBidLastLowDec(const double value); void SetControlBidLastLowLevev(const double value); double GetValueChangedBidLastLow(void) const; bool IsIncreasedBidLastLow(void) const; bool IsDecreasedBidLastLow(void) const; //--- Ask //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Ask //--- получение (4) величины изменения цены Ask, //--- получение флага изменения цены Ask больше, чем на величину (5) прироста, (6) уменьшения void SetControlAskInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_ASK,::fabs(value)); } void SetControlAskDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_ASK,::fabs(value)); } void SetControlAskLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_ASK,::fabs(value)); } double GetValueChangedAsk(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_ASK); } bool IsIncreasedAsk(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_ASK); } bool IsDecreasedAsk(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_ASK); } //--- Максимальный Ask за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Ask за день //--- получение (4) величины изменения максимального Ask за день, //--- получение флага изменения максимального Ask за день больше, чем на величину (5) прироста, (6) уменьшения void SetControlAskHighInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_ASKHIGH,::fabs(value)); } void SetControlAskHighDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_ASKHIGH,::fabs(value)); } void SetControlAskHighLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_ASKHIGH,::fabs(value)); } double GetValueChangedAskHigh(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_ASKHIGH); } bool IsIncreasedAskHigh(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_ASKHIGH); } bool IsDecreasedAskHigh(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_ASKHIGH); } //--- Минимальный Ask за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Ask за день //--- получение (4) величины изменения минимального Ask за день, //--- получение флага изменения минимального Ask за день больше, чем на величину (5) прироста, (6) уменьшения void SetControlAskLowInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_ASKLOW,::fabs(value)); } void SetControlAskLowDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_ASKLOW,::fabs(value)); } void SetControlAskLowLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_ASKLOW,::fabs(value)); } double GetValueChangedAskLow(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_ASKLOW); } bool IsIncreasedAskLow(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_ASKLOW); } bool IsDecreasedAskLow(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_ASKLOW); } //--- Реальный Volume за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня реального Volume за день //--- получение (4) величины изменения реального Volume за день, //--- получение флага изменения реального Volume за день больше, чем на величину (5) прироста, (6) уменьшения void SetControlVolumeRealInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_VOLUME_REAL,::fabs(value)); } void SetControlVolumeRealDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_VOLUME_REAL,::fabs(value)); } void SetControlVolumeRealLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUME_REAL,::fabs(value)); } double GetValueChangedVolumeReal(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUME_REAL); } bool IsIncreasedVolumeReal(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUME_REAL); } bool IsDecreasedVolumeReal(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUME_REAL); } //--- Максимальный реальный Volume за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального реального Volume за день //--- получение (4) величины изменения максимального реального Volume за день, //--- получение флага изменения максимального реального Volume за день больше, чем на величину (5) прироста, (6) уменьшения void SetControlVolumeHighRealInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value)); } void SetControlVolumeHighRealDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value)); } void SetControlVolumeHighRealLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value)); } double GetValueChangedVolumeHighReal(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUMEHIGH_REAL); } bool IsIncreasedVolumeHighReal(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUMEHIGH_REAL); } bool IsDecreasedVolumeHighReal(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUMEHIGH_REAL); } //--- Минимальный реальный Volume за день //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального реального Volume за день //--- получение (4) величины изменения минимального реального Volume за день, //--- получение флага изменения минимального реального Volume за день больше, чем на величину (5) прироста, (6) уменьшения void SetControlVolumeLowRealInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value)); } void SetControlVolumeLowRealDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value)); } void SetControlVolumeLowRealLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value)); } double GetValueChangedVolumeLowReal(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUMELOW_REAL); } bool IsIncreasedVolumeLowReal(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUMELOW_REAL); } bool IsDecreasedVolumeLowReal(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUMELOW_REAL); } //--- Цена исполнения опциона //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены исполнения опциона //--- получение (4) величины изменения цены исполнения опциона, //--- получение флага изменения цены исполнения опциона больше, чем на величину (5) прироста, (6) уменьшения void SetControlOptionStrikeInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_OPTION_STRIKE,::fabs(value)); } void SetControlOptionStrikeDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_OPTION_STRIKE,::fabs(value)); } void SetControlOptionStrikeLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_OPTION_STRIKE,::fabs(value)); } double GetValueChangedOptionStrike(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_OPTION_STRIKE); } bool IsIncreasedOptionStrike(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_OPTION_STRIKE); } bool IsDecreasedOptionStrike(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_OPTION_STRIKE); } //--- Максимально-допустимый совокупный объём позиций и ордеров в одном направлении //--- (1) Установка контрольного уровня //--- (2) получение величины изменения максимально-допустимого совокупного объёма позиций и ордеров в одном направлении, //--- получение флага (3) увеличения, (4) уменьшения максимально-допустимого совокупного объёма позиций и ордеров в одном направлении void SetControlVolumeLimitLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUME_LIMIT,::fabs(value)); } double GetValueChangedVolumeLimit(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUME_LIMIT); } bool IsIncreasedVolumeLimit(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUME_LIMIT); } bool IsDecreasedVolumeLimit(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUME_LIMIT); } //--- Своп на покупку //--- (1) Установка контрольного уровня //--- (2) получение величины изменения свопа на покупку, //--- получение флага (3) увеличения, (4) уменьшения свопа на покупку void SetControlSwapLongLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SWAP_LONG,::fabs(value)); } double GetValueChangedSwapLong(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SWAP_LONG); } bool IsIncreasedSwapLong(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SWAP_LONG); } bool IsDecreasedSwapLong(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SWAP_LONG); } //--- Своп на продажу //--- (1) Установка контрольного уровня //--- (2) получение величины изменения свопа на продажу, //--- получение флага (3) увеличения, (4) уменьшения свопа на продажу void SetControlSwapShortLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SWAP_SHORT,::fabs(value)); } double GetValueChangedSwapShort(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SWAP_SHORT); } bool IsIncreasedSwapShort(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SWAP_SHORT); } bool IsDecreasedSwapShort(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SWAP_SHORT); } //--- Cуммарный объём сделок в текущую сессию //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня суммарного объёма сделок в текущую сессию //--- получение (4) величины изменения суммарного объёма сделок в текущую сессию, //--- получение флага изменения суммарного объёма сделок в текущую сессию больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionVolumeInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_VOLUME,::fabs(value)); } void SetControlSessionVolumeDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_VOLUME,::fabs(value)); } void SetControlSessionVolumeLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_VOLUME,::fabs(value)); } double GetValueChangedSessionVolume(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_VOLUME); } bool IsIncreasedSessionVolume(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_VOLUME); } bool IsDecreasedSessionVolume(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_VOLUME); } //--- Cуммарный оборот в текущую сессию //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня суммарного оборота в текущую сессию //--- получение (4) величины изменения суммарного оборота в текущую сессию, //--- получение флага изменения суммарного оборота в текущую сессию больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionTurnoverInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value)); } void SetControlSessionTurnoverDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value)); } void SetControlSessionTurnoverLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value)); } double GetValueChangedSessionTurnover(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_TURNOVER); } bool IsIncreasedSessionTurnover(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_TURNOVER); } bool IsDecreasedSessionTurnover(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_TURNOVER); } //--- Cуммарный объём открытых позиций //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня суммарного объёма открытых позиций в текущую сессию //--- получение (4) величины изменения суммарного объёма открытых позиций в текущую сессию, //--- получение флага изменения суммарного объёма открытых позиций в текущую сессию больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionInterestInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_INTEREST,::fabs(value)); } void SetControlSessionInterestDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_INTEREST,::fabs(value)); } void SetControlSessionInterestLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_INTEREST,::fabs(value)); } double GetValueChangedSessionInterest(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_INTEREST); } bool IsIncreasedSessionInterest(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_INTEREST); } bool IsDecreasedSessionInterest(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_INTEREST); } //--- Общий объём ордеров на покупку в текущий момент //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня общего объёма ордеров на покупку в текущий момент //--- получение (4) величины изменения общего объёма ордеров на покупку в текущий момент, //--- получение флага изменения общего объёма ордеров на покупку в текущий момент больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionBuyOrdVolumeInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionBuyOrdVolumeDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionBuyOrdVolumeLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value));} double GetValueChangedSessionBuyOrdVolume(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME); } bool IsIncreasedSessionBuyOrdVolume(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME); } bool IsDecreasedSessionBuyOrdVolume(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME); } //--- Общий объём ордеров на продажу в текущий момент //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня общего объёма ордеров на продажу в текущий момент //--- получение (4) величины изменения общего объёма ордеров на продажу в текущий момент, //--- получение флага изменения общего объёма ордеров на продажу в текущий момент больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionSellOrdVolumeInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionSellOrdVolumeDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionSellOrdVolumeLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value));} double GetValueChangedSessionSellOrdVolume(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME); } bool IsIncreasedSessionSellOrdVolume(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME); } bool IsDecreasedSessionSellOrdVolume(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME); } //--- Цена открытия сессии //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены открытия сессии //--- получение (4) величины изменения цены открытия сессии, //--- получение флага изменения цены открытия сессии больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionPriceOpenInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_OPEN,::fabs(value)); } void SetControlSessionPriceOpenDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_OPEN,::fabs(value)); } void SetControlSessionPriceOpenLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_OPEN,::fabs(value)); } double GetValueChangedSessionPriceOpen(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_OPEN); } bool IsIncreasedSessionPriceOpen(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_OPEN); } bool IsDecreasedSessionPriceOpen(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_OPEN); } //--- Цена закрытия сессии //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены закрытия сессии //--- получение (4) величины изменения цены закрытия сессии, //--- получение флага изменения цены закрытия сессии больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionPriceCloseInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_CLOSE,::fabs(value)); } void SetControlSessionPriceCloseDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_CLOSE,::fabs(value)); } void SetControlSessionPriceCloseLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_CLOSE,::fabs(value)); } double GetValueChangedSessionPriceClose(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_CLOSE); } bool IsIncreasedSessionPriceClose(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_CLOSE); } bool IsDecreasedSessionPriceClose(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_CLOSE); } //--- Средневзвешенная цена сессии //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня средневзвешенной цены сессии //--- получение (4) величины изменения средневзвешенной цены сессии, //--- получение флага изменения средневзвешенной цены сессии больше, чем на величину (5) прироста, (6) уменьшения void SetControlSessionPriceAWInc(const double value) { this.SetControlledValueINC(SYMBOL_PROP_SESSION_AW,::fabs(value)); } void SetControlSessionPriceAWDec(const double value) { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_AW,::fabs(value)); } void SetControlSessionPriceAWLevel(const double value) { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_AW,::fabs(value)); } double GetValueChangedSessionPriceAW(void) const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_AW); } bool IsIncreasedSessionPriceAW(void) const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_AW); } bool IsDecreasedSessionPriceAW(void) const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_AW); } //---
И методы, реализация которых выполнена за пределами тела класса, так же теперь используют напрямую методы базового класса:
//+------------------------------------------------------------------+ //| Устанавливает контролируемую величину прироста цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastInc(const double value) { this.SetControlledValueINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value)); } //+------------------------------------------------------------------+ //|Устанавливает контролируемую величину уменьшения цены Bid или Last| //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastDec(const double value) { this.SetControlledValueDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value)); } //+------------------------------------------------------------------+ //| Устанавливает контрольный уровень цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLevel(const double value) { this.SetControlledValueLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value)); } //+------------------------------------------------------------------+ //| Возвращает величину изменения цены Bid или Last | //+------------------------------------------------------------------+ double CSymbol::GetValueChangedBidLast(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetPropDoubleChangedValue(SYMBOL_PROP_BID) : this.GetPropDoubleChangedValue(SYMBOL_PROP_LAST)); } //+------------------------------------------------------------------+ //| Возвращает флаг изменения цены Bid или Last больше, | //| чем на величину прироста | //+------------------------------------------------------------------+ bool CSymbol::IsIncreasedBidLast(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BID) : (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LAST)); } //+------------------------------------------------------------------+ //| Возвращает флаг изменения цены Bid или Last больше, | //| чем на величину уменьшения | //+------------------------------------------------------------------+ bool CSymbol::IsDecreasedBidLast(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BID) : (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LAST)); } //+------------------------------------------------------------------+ //| Устанавливает контролируемую величину прироста | //| максимальной цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastHighInc(const double value) { this.SetControlledValueINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value)); } //+------------------------------------------------------------------+ //| Устанавливает контролируемую величину уменьшения | //| максимальной цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastHighDec(const double value) { this.SetControlledValueDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value)); } //+------------------------------------------------------------------+ //| Устанавливает контрольный уровень максимальной цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastHighLevel(const double value) { this.SetControlledValueLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value)); } //+------------------------------------------------------------------+ //| Возвращает величину изменения максимальной цены Bid или Last | //+------------------------------------------------------------------+ double CSymbol::GetValueChangedBidLastHigh(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDHIGH) : this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTHIGH)); } //+------------------------------------------------------------------+ //| Возвращает флаг изменения максимальной цены | //| Bid или Last больше, чем на величину прироста | //+------------------------------------------------------------------+ bool CSymbol::IsIncreasedBidLastHigh(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDHIGH) : (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTHIGH)); } //+------------------------------------------------------------------+ //| Возвращает флаг изменения максимальной цены | //| Bid или Last больше, чем на величину уменьшения | //+------------------------------------------------------------------+ bool CSymbol::IsDecreasedBidLastHigh(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDHIGH) : (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTHIGH)); } //+------------------------------------------------------------------+ //| Устанавливает контролируемую величину прироста | //| минимальной цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLowInc(const double value) { this.SetControlledValueINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value)); } //+------------------------------------------------------------------+ //| Устанавливает контролируемую величину уменьшения | //| минимальной цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLowDec(const double value) { this.SetControlledValueDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value)); } //+------------------------------------------------------------------+ //| Устанавливает контрольный уровень минимальной цены Bid или Last | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLowLevev(const double value) { this.SetControlledValueLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value)); } //+------------------------------------------------------------------+ //| Возвращает величину изменения минимальной цены Bid или Last | //+------------------------------------------------------------------+ double CSymbol::GetValueChangedBidLastLow(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDLOW) : this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTLOW)); } //+------------------------------------------------------------------+ //| Возвращает флаг изменения минимальной цены | //| Bid или Last больше, чем на величину прироста | //+------------------------------------------------------------------+ bool CSymbol::IsIncreasedBidLastLow(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDLOW) : (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTLOW)); } //+------------------------------------------------------------------+ //| Возвращает флаг изменения минимальной цены | //| Bid или Last больше, чем на величину уменьшения | //+------------------------------------------------------------------+ bool CSymbol::IsDecreasedBidLastLow(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDLOW) : (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTLOW)); } //+------------------------------------------------------------------+
Также, в конструкторе класса мною была допущена логическая ошибка — данные базового объекта не заполнялись сразу после создания объекта-символа, что приводило к тому, что при первом запуске события не отслеживались до тех пор, пока не произойдёт какое-либо событие изменения значения свойства символа, величина изменения которого между двумя соседними тиками была незначительна, и после этого данные базового объекта заполнялись.
Исправим эту ошибку — впишем сразу же после заполнения свойств объекта-символа заполнение свойств его базового объекта:
//+------------------------------------------------------------------+ //| Закрытый параметрический конструктор | //+------------------------------------------------------------------+ CSymbol::CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name,const int index) { this.m_name=name; this.m_type=COLLECTION_SYMBOLS_ID; if(!this.Exist()) { ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\"",": ",TextByLanguage("Ошибка. Такого символа нет на сервере","Error. There is no such symbol on the server")); this.m_global_error=ERR_MARKET_UNKNOWN_SYMBOL; } bool select=::SymbolInfoInteger(this.m_name,SYMBOL_SELECT); ::ResetLastError(); if(!select) { if(!this.SetToMarketWatch()) { this.m_global_error=::GetLastError(); ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\": ",TextByLanguage("Не удалось поместить в обзор рынка. Ошибка: ","Failed to put in the market watch. Error: "),this.m_global_error); } } ::ResetLastError(); if(!::SymbolInfoTick(this.m_name,this.m_tick)) { this.m_global_error=::GetLastError(); ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\": ",TextByLanguage("Не удалось получить текущие цены. Ошибка: ","Could not get current prices. Error: "),this.m_global_error); } //--- Инициализация массивов данных базового объекта this.SetControlDataArraySizeLong(SYMBOL_PROP_INTEGER_TOTAL); this.SetControlDataArraySizeDouble(SYMBOL_PROP_DOUBLE_TOTAL); this.ResetChangesParams(); this.ResetControlsParams(); //--- Инициализация данных символа this.Reset(); this.InitMarginRates(); #ifdef __MQL5__ ::ResetLastError(); if(!this.MarginRates()) { this.m_global_error=::GetLastError(); ::Print(DFUN_ERR_LINE,this.Name(),": ",TextByLanguage("Не удалось получить коэффициенты взимания маржи. Ошибка: ","Failed to get margin rates. Error: "),this.m_global_error); return; } #endif //--- Сохранение целочисленных свойств this.m_long_prop[SYMBOL_PROP_STATUS] = symbol_status; this.m_long_prop[SYMBOL_PROP_INDEX_MW] = index; this.m_long_prop[SYMBOL_PROP_VOLUME] = (long)this.m_tick.volume; this.m_long_prop[SYMBOL_PROP_SELECT] = ::SymbolInfoInteger(this.m_name,SYMBOL_SELECT); this.m_long_prop[SYMBOL_PROP_VISIBLE] = ::SymbolInfoInteger(this.m_name,SYMBOL_VISIBLE); this.m_long_prop[SYMBOL_PROP_SESSION_DEALS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_DEALS); this.m_long_prop[SYMBOL_PROP_SESSION_BUY_ORDERS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_BUY_ORDERS); this.m_long_prop[SYMBOL_PROP_SESSION_SELL_ORDERS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_SELL_ORDERS); this.m_long_prop[SYMBOL_PROP_VOLUMEHIGH] = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMEHIGH); this.m_long_prop[SYMBOL_PROP_VOLUMELOW] = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMELOW); this.m_long_prop[SYMBOL_PROP_DIGITS] = ::SymbolInfoInteger(this.m_name,SYMBOL_DIGITS); this.m_long_prop[SYMBOL_PROP_SPREAD] = ::SymbolInfoInteger(this.m_name,SYMBOL_SPREAD); this.m_long_prop[SYMBOL_PROP_SPREAD_FLOAT] = ::SymbolInfoInteger(this.m_name,SYMBOL_SPREAD_FLOAT); this.m_long_prop[SYMBOL_PROP_TICKS_BOOKDEPTH] = ::SymbolInfoInteger(this.m_name,SYMBOL_TICKS_BOOKDEPTH); this.m_long_prop[SYMBOL_PROP_TRADE_MODE] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_MODE); this.m_long_prop[SYMBOL_PROP_START_TIME] = ::SymbolInfoInteger(this.m_name,SYMBOL_START_TIME); this.m_long_prop[SYMBOL_PROP_EXPIRATION_TIME] = ::SymbolInfoInteger(this.m_name,SYMBOL_EXPIRATION_TIME); this.m_long_prop[SYMBOL_PROP_TRADE_STOPS_LEVEL] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_STOPS_LEVEL); this.m_long_prop[SYMBOL_PROP_TRADE_FREEZE_LEVEL] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_FREEZE_LEVEL); this.m_long_prop[SYMBOL_PROP_TRADE_EXEMODE] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_EXEMODE); this.m_long_prop[SYMBOL_PROP_SWAP_ROLLOVER3DAYS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SWAP_ROLLOVER3DAYS); this.m_long_prop[SYMBOL_PROP_TIME] = this.TickTime(); this.m_long_prop[SYMBOL_PROP_EXIST] = this.SymbolExists(); this.m_long_prop[SYMBOL_PROP_CUSTOM] = this.SymbolCustom(); this.m_long_prop[SYMBOL_PROP_MARGIN_HEDGED_USE_LEG] = this.SymbolMarginHedgedUseLEG(); this.m_long_prop[SYMBOL_PROP_ORDER_MODE] = this.SymbolOrderMode(); this.m_long_prop[SYMBOL_PROP_FILLING_MODE] = this.SymbolOrderFillingMode(); this.m_long_prop[SYMBOL_PROP_EXPIRATION_MODE] = this.SymbolExpirationMode(); this.m_long_prop[SYMBOL_PROP_ORDER_GTC_MODE] = this.SymbolOrderGTCMode(); this.m_long_prop[SYMBOL_PROP_OPTION_MODE] = this.SymbolOptionMode(); this.m_long_prop[SYMBOL_PROP_OPTION_RIGHT] = this.SymbolOptionRight(); this.m_long_prop[SYMBOL_PROP_BACKGROUND_COLOR] = this.SymbolBackgroundColor(); this.m_long_prop[SYMBOL_PROP_CHART_MODE] = this.SymbolChartMode(); this.m_long_prop[SYMBOL_PROP_TRADE_CALC_MODE] = this.SymbolCalcMode(); this.m_long_prop[SYMBOL_PROP_SWAP_MODE] = this.SymbolSwapMode(); //--- Сохранение вещественных свойств this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKHIGH)] = ::SymbolInfoDouble(this.m_name,SYMBOL_ASKHIGH); this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKLOW)] = ::SymbolInfoDouble(this.m_name,SYMBOL_ASKLOW); this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTHIGH)] = ::SymbolInfoDouble(this.m_name,SYMBOL_LASTHIGH); this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTLOW)] = ::SymbolInfoDouble(this.m_name,SYMBOL_LASTLOW); this.m_double_prop[this.IndexProp(SYMBOL_PROP_POINT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_POINT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_PROFIT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_LOSS); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_SIZE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_SIZE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_CONTRACT_SIZE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_CONTRACT_SIZE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MIN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MIN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MAX)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MAX); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_STEP)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_STEP); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_LIMIT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_LIMIT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_LONG)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_LONG); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_SHORT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_SHORT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_INITIAL)] = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_INITIAL); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_MAINTENANCE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_MAINTENANCE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_TURNOVER)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_TURNOVER); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_INTEREST)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_INTEREST); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_BUY_ORDERS_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_SELL_ORDERS_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_OPEN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_OPEN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_CLOSE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_CLOSE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_AW)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_AW); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_SETTLEMENT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MIN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MAX); this.m_double_prop[this.IndexProp(SYMBOL_PROP_BID)] = this.m_tick.bid; this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASK)] = this.m_tick.ask; this.m_double_prop[this.IndexProp(SYMBOL_PROP_LAST)] = this.m_tick.last; this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDHIGH)] = this.SymbolBidHigh(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDLOW)] = this.SymbolBidLow(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_REAL)] = this.SymbolVolumeReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMEHIGH_REAL)] = this.SymbolVolumeHighReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMELOW_REAL)] = this.SymbolVolumeLowReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_OPTION_STRIKE)] = this.SymbolOptionStrike(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_ACCRUED_INTEREST)] = this.SymbolTradeAccruedInterest(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_FACE_VALUE)] = this.SymbolTradeFaceValue(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_LIQUIDITY_RATE)] = this.SymbolTradeLiquidityRate(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_HEDGED)] = this.SymbolMarginHedged(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_INITIAL)] = this.m_margin_rate.Long.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL)] = this.m_margin_rate.BuyStop.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL)] = this.m_margin_rate.BuyLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL)] = this.m_margin_rate.BuyStopLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_MAINTENANCE)] = this.m_margin_rate.Long.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE)] = this.m_margin_rate.BuyStop.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE)] = this.m_margin_rate.BuyLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE)] = this.m_margin_rate.BuyStopLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_INITIAL)] = this.m_margin_rate.Short.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL)] = this.m_margin_rate.SellStop.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL)] = this.m_margin_rate.SellLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL)] = this.m_margin_rate.SellStopLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE)] = this.m_margin_rate.Short.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE)] = this.m_margin_rate.SellStop.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE)] = this.m_margin_rate.SellLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE)]= this.m_margin_rate.SellStopLimit.Maintenance; //--- Сохранение строковых свойств this.m_string_prop[this.IndexProp(SYMBOL_PROP_NAME)] = this.m_name; this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_BASE)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_BASE); this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_PROFIT)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_PROFIT); this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_MARGIN)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_MARGIN); this.m_string_prop[this.IndexProp(SYMBOL_PROP_DESCRIPTION)] = ::SymbolInfoString(this.m_name,SYMBOL_DESCRIPTION); this.m_string_prop[this.IndexProp(SYMBOL_PROP_PATH)] = ::SymbolInfoString(this.m_name,SYMBOL_PATH); this.m_string_prop[this.IndexProp(SYMBOL_PROP_BASIS)] = this.SymbolBasis(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_BANK)] = this.SymbolBank(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_ISIN)] = this.SymbolISIN(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_FORMULA)] = this.SymbolFormula(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_PAGE)] = this.SymbolPage(); //--- Сохранение дополнительных целочисленных свойств this.m_long_prop[SYMBOL_PROP_DIGITS_LOTS] = this.SymbolDigitsLot(); //--- Заполнение текущих данных символа for(int i=0;i<SYMBOL_PROP_INTEGER_TOTAL;i++) this.m_long_prop_event[i][3]=this.m_long_prop[i]; for(int i=0;i<SYMBOL_PROP_DOUBLE_TOTAL;i++) this.m_double_prop_event[i][3]=this.m_double_prop[i]; //--- Обновление данных в базовом объекте и поиск изменений CBaseObj::Refresh(); //--- if(!select) this.RemoveFromMarketWatch(); } //+------------------------------------------------------------------+
В классе коллекции символов в файле \MQL5\Include\DoEasy\Collections\SymbolsCollection.mqh, в публичной секции
класса, так же поменяем название метода обновления символов коллекции и поиска событий SymbolsEventsControl().
Сделаем название метода более подходящим под его задачи—
обновление данных и поиск событий:
//--- Работа с событиями (1) списка символов коллекции, (2) окна обзора рынка void RefreshAndEventsControl(void); void MarketWatchEventsControl(const bool send_events=true);
Это все изменения, которые необходимо было сделать в классах базового объекта, его наследника — объекта-символа и классе коллекции символов.
Теперь приступим к доработке классов объекта-аккаунта так, чтобы и он был наследником базового объекта CBaseObj и получил от него событийный функционал для лёгкого управления отслеживанием изменений свойств объекта-аккаунта.
Ставим объект-аккаунт на новые рельсы
По прошлой статье мы помним, что при использовании базового объекта в качестве источника генерации событий мы больше не связаны необходимостью создавать флаги событий, и из комбинаций этих флагов создавать идентификаторы событий. Теперь событийный функционал базового объекта устроен гибче. А значит — нам можно удалить уже ставшие ненужными перечисления из файла Defines.mqh библиотеки:
//+------------------------------------------------------------------+ //| Данные для работы с аккаунтами | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Список флагов событий аккаунта | //+------------------------------------------------------------------+ enum ENUM_ACCOUNT_EVENT_FLAGS { ACCOUNT_EVENT_FLAG_NO_EVENT = 0, // Нет события ACCOUNT_EVENT_FLAG_LEVERAGE = 1, // Изменение предоставленного плеча ACCOUNT_EVENT_FLAG_LIMIT_ORDERS = 2, // Изменение максимально допустимого количества действующих отложенных ордеров ACCOUNT_EVENT_FLAG_TRADE_ALLOWED = 4, // Изменение разрешения торговли на счёте ACCOUNT_EVENT_FLAG_TRADE_EXPERT = 8, // Изменение разрешения автоторговли на счёте ACCOUNT_EVENT_FLAG_BALANCE = 16, // Изменение баланса больше заданной величины в +/- ACCOUNT_EVENT_FLAG_EQUITY = 32, // Изменение собственных средств больше заданной величины в +/- ACCOUNT_EVENT_FLAG_PROFIT = 64, // Изменение профита больше заданной величины в +/- ACCOUNT_EVENT_FLAG_CREDIT = 128, // Изменение размера предоставленного кредита в валюте депозита ACCOUNT_EVENT_FLAG_MARGIN = 256, // Изменение размера зарезервированных залоговых средств на счете в валюте депозита больше заданной величины в +/- ACCOUNT_EVENT_FLAG_MARGIN_FREE = 512, // Изменение размера средств на счете в валюте депозита, доступных для открытия позиции больше заданной величины в +/- ACCOUNT_EVENT_FLAG_MARGIN_LEVEL = 1024, // Изменение уровня залоговых средств на счете в процентах больше заданной величины в +/- ACCOUNT_EVENT_FLAG_MARGIN_INITIAL = 2048, // Изменение размера средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам больше заданной величины в +/- ACCOUNT_EVENT_FLAG_MARGIN_MAINTENANCE = 4096, // Изменение размера средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям больше заданной величины в +/- ACCOUNT_EVENT_FLAG_MARGIN_SO_CALL = 8192, // Изменение уровня залоговых средств, при котором происходит MarginCall ACCOUNT_EVENT_FLAG_MARGIN_SO_SO = 16384, // Изменение уровня залоговых средств, при достижении которого происходит StopOut ACCOUNT_EVENT_FLAG_ASSETS = 32768, // Изменение текущего размера активов на счёте больше заданной величины в +/- ACCOUNT_EVENT_FLAG_LIABILITIES = 65536, // Изменение текущего размера обязательств на счёте больше заданной величины в +/- ACCOUNT_EVENT_FLAG_COMISSION_BLOCKED = 131072, // Изменение текущей суммы заблокированных комиссий по счёту больше заданной величины в +/- }; //+------------------------------------------------------------------+ //| Список возможных событий аккаунта | //+------------------------------------------------------------------+ enum ENUM_ACCOUNT_EVENT { ACCOUNT_EVENT_NO_EVENT = TRADE_EVENTS_NEXT_CODE, // Нет события ACCOUNT_EVENT_LEVERAGE_INC, // Увеличение предоставленного плеча ACCOUNT_EVENT_LEVERAGE_DEC, // Уменьшение предоставленного плеча ACCOUNT_EVENT_LIMIT_ORDERS_INC, // Увеличение максимально допустимого количества действующих отложенных ордеров ACCOUNT_EVENT_LIMIT_ORDERS_DEC, // Уменьшение максимально допустимого количества действующих отложенных ордеров ACCOUNT_EVENT_TRADE_ALLOWED_ON, // Разрешение торговли на счёте ACCOUNT_EVENT_TRADE_ALLOWED_OFF, // Запрет торговли на счёте ACCOUNT_EVENT_TRADE_EXPERT_ON, // Разрешение автоторговли на счёте ACCOUNT_EVENT_TRADE_EXPERT_OFF, // Запрет автоторговли на счёте ACCOUNT_EVENT_BALANCE_INC, // Увеличение баланса больше заданной величины ACCOUNT_EVENT_BALANCE_DEC, // Уменьшение баланса больше заданной величины ACCOUNT_EVENT_EQUITY_INC, // Увеличение собственных средств больше заданной величины ACCOUNT_EVENT_EQUITY_DEC, // Уменьшение собственных средств больше заданной величины ACCOUNT_EVENT_PROFIT_INC, // Увеличение профита больше заданной величины ACCOUNT_EVENT_PROFIT_DEC, // Уменьшение профита больше заданной величины ACCOUNT_EVENT_CREDIT_INC, // Увеличение размера предоставленного кредита в валюте депозита ACCOUNT_EVENT_CREDIT_DEC, // Уменьшение размера предоставленного кредита в валюте депозита ACCOUNT_EVENT_MARGIN_INC, // Увеличение размера зарезервированных залоговых средств на счете в валюте депозита ACCOUNT_EVENT_MARGIN_DEC, // Уменьшение размера зарезервированных залоговых средств на счете в валюте депозита ACCOUNT_EVENT_MARGIN_FREE_INC, // Увеличение размера средств на счете в валюте депозита, доступных для открытия позиции ACCOUNT_EVENT_MARGIN_FREE_DEC, // Уменьшение размера средств на счете в валюте депозита, доступных для открытия позиции ACCOUNT_EVENT_MARGIN_LEVEL_INC, // Увеличение уровня залоговых средств на счете в процентах ACCOUNT_EVENT_MARGIN_LEVEL_DEC, // Уменьшение уровня залоговых средств на счете в процентах ACCOUNT_EVENT_MARGIN_INITIAL_INC, // Увеличение размера средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам ACCOUNT_EVENT_MARGIN_INITIAL_DEC, // Уменьшение размера средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам ACCOUNT_EVENT_MARGIN_MAINTENANCE_INC, // Увеличение размера средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям ACCOUNT_EVENT_MARGIN_MAINTENANCE_DEC, // Уменьшение размера средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям ACCOUNT_EVENT_MARGIN_SO_CALL_INC, // Увеличение уровня залоговых средств, при котором происходит MarginCall ACCOUNT_EVENT_MARGIN_SO_CALL_DEC, // Уменьшение уровня залоговых средств, при котором происходит MarginCall ACCOUNT_EVENT_MARGIN_SO_SO_INC, // Увеличение уровня залоговых средств, при достижении которого происходит StopOut ACCOUNT_EVENT_MARGIN_SO_SO_DEC, // Уменьшение уровня залоговых средств, при достижении которого происходит StopOut ACCOUNT_EVENT_ASSETS_INC, // Увеличение текущего размера активов на счёте ACCOUNT_EVENT_ASSETS_DEC, // Уменьшение текущего размера активов на счёте ACCOUNT_EVENT_LIABILITIES_INC, // Увеличение текущего размера обязательств на счёте ACCOUNT_EVENT_LIABILITIES_DEC, // Уменьшение текущего размера обязательств на счёте ACCOUNT_EVENT_COMISSION_BLOCKED_INC, // Увеличение текущей суммы заблокированных комиссий по счёту ACCOUNT_EVENT_COMISSION_BLOCKED_DEC, // Уменьшение текущей суммы заблокированных комиссий по счёту };
И всё, что останется от данных перечислений, это макроподстановка, указывающая на код следующего события:
//+------------------------------------------------------------------+ //| Данные для работы с аккаунтами | //+------------------------------------------------------------------+ #define ACCOUNT_EVENTS_NEXT_CODE (TRADE_EVENTS_NEXT_CODE) // Код следующего событя после последнего кода события аккаунта //+------------------------------------------------------------------+ //| Целочисленные свойства аккаунта | //+------------------------------------------------------------------+
Откроем файл \MQL5\Include\DoEasy\Objects\Accounts\Account.mqh и внесём в него необходимые изменения.
В публичной секции класса объявим виртуальный метод Refresh():
public: //--- Конструктор CAccount(void); //--- Устанавливает (1) целочисленное, (2) вещественное и (3) строковое свойство аккаунта void SetProperty(ENUM_ACCOUNT_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_ACCOUNT_PROP_DOUBLE property,double value) { this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_ACCOUNT_PROP_STRING property,string value) { this.m_string_prop[this.IndexProp(property)]=value; } //--- Возвращает из массива свойств (1) целочисленное, (2) вещественное и (3) строковое свойство аккаунта long GetProperty(ENUM_ACCOUNT_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_ACCOUNT_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_ACCOUNT_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Возвращает флаг расчёта уровне MarginCall и StopOut в процентах bool IsPercentsForSOLevels(void) const { return this.MarginSOMode()==ACCOUNT_STOPOUT_MODE_PERCENT; } //--- Возвращает флаг поддержания объектом-аккаунтом данного свойства virtual bool SupportProperty(ENUM_ACCOUNT_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_ACCOUNT_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_ACCOUNT_PROP_STRING property) { return true; } //--- Сравнивает объекты CAccount между собой по всем возможным свойствам (для сортировки списков по указанному свойству объекта-аккаунта) virtual int Compare(const CObject *node,const int mode=0) const; //--- Сравнивает объекты CAccount между собой по свойствам счёта (для поиска равных объектов-аккаунтов) bool IsEqual(CAccount* compared_account) const; //--- Обновляет все данные аккаунта virtual void Refresh(void); //--- (1) Сохраняет объект-аккаунт в файл, (2), загружает объект-аккаунт из файла virtual bool Save(const int file_handle); virtual bool Load(const int file_handle);
Для обновления данных текущего аккаунта будем использовать метод Refresh() точно так же, как и в классе CSymbol, и во всех последующих классах на основе базового объекта CBaseObj). Ранее мы обновляли данные текущего аккаунта из класса коллекции аккаунтов. Но для того чтобы все классы имели одинаковую структуру, сделаем всё так же, как сделали в CSymbol, и будем делать в остальных будущих классах.
Для получения и установки параметров отслеживаемых свойств символа мы в классе CSymbol уже создали методы.
Создадим
такие же методы и для класса объекта-аккаунта:
//+------------------------------------------------------------------+ //| Получение и установка параметров отслеживаемых изменений свойств | //+------------------------------------------------------------------+ //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня плеча //--- получение (3) величины изменения плеча, //--- получение флага изменения плеча больше, чем на величину (4) прироста, (5) уменьшения void SetControlLeverageInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_LEVERAGE,(long)::fabs(value)); } void SetControlLeverageDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_LEVERAGE,(long)::fabs(value)); } void SetControlLeverageLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_LEVERAGE,(long)::fabs(value)); } long GetValueChangedLeverage(void) const { return this.GetPropLongChangedValue(ACCOUNT_PROP_LEVERAGE); } bool IsIncreasedLeverage(void) const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_LEVERAGE); } bool IsDecreasedLeverage(void) const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_LEVERAGE); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества действующих отложенных ордеров //--- получение (3) величины изменения количества действующих отложенных ордеров, //--- получение флага изменения количества действующих отложенных ордеров больше, чем на величину (4) прироста, (5) уменьшения void SetControlLimitOrdersInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_LIMIT_ORDERS,(long)::fabs(value)); } void SetControlLimitOrdersDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_LIMIT_ORDERS,(long)::fabs(value)); } void SetControlLimitOrdersLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_LIMIT_ORDERS,(long)::fabs(value)); } long GetValueChangedLimitOrders(void) const { return this.GetPropLongChangedValue(ACCOUNT_PROP_LIMIT_ORDERS); } bool IsIncreasedLimitOrders(void) const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_LIMIT_ORDERS); } bool IsDecreasedLimitOrders(void) const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_LIMIT_ORDERS); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня разрешения торговли для текущего счета со стороны сервера //--- получение (3) величины изменения разрешения торговли для текущего счета со стороны сервера, //--- получение флага изменения разрешения торговли для текущего счета со стороны сервера больше, чем на величину (4) прироста, (5) уменьшения void SetControlTradeAllowedInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_TRADE_ALLOWED,(long)::fabs(value)); } void SetControlTradeAllowedDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_TRADE_ALLOWED,(long)::fabs(value)); } void SetControlTradeAllowedLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_TRADE_ALLOWED,(long)::fabs(value)); } long GetValueChangedTradeAllowed(void) const { return this.GetPropLongChangedValue(ACCOUNT_PROP_TRADE_ALLOWED); } bool IsIncreasedTradeAllowed(void) const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_TRADE_ALLOWED); } bool IsDecreasedTradeAllowed(void) const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_TRADE_ALLOWED); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня разрешения торговли для эксперта со стороны сервера //--- получение (3) величины изменения разрешения торговли для эксперта со стороны сервера, //--- получение флага изменения разрешения торговли для эксперта со стороны сервера больше, чем на величину (4) прироста, (5) уменьшения void SetControlTradeExpertInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_TRADE_EXPERT,(long)::fabs(value)); } void SetControlTradeExpertDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_TRADE_EXPERT,(long)::fabs(value)); } void SetControlTradeExpertLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_TRADE_EXPERT,(long)::fabs(value)); } long GetValueChangedTradeExpert(void) const { return this.GetPropLongChangedValue(ACCOUNT_PROP_TRADE_EXPERT); } bool IsIncreasedTradeExpert(void) const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_TRADE_EXPERT); } bool IsDecreasedTradeExpert(void) const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_TRADE_EXPERT); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня баланса //--- получение (3) величины изменения баланса, //--- получение флага изменения баланса больше, чем на величину (4) прироста, (5) уменьшения void SetControlBalanceInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_BALANCE,(double)::fabs(value)); } void SetControlBalanceDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_BALANCE,(double)::fabs(value)); } void SetControlBalanceLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_BALANCE,(double)::fabs(value)); } double GetValueChangedBalance(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_BALANCE); } bool IsIncreasedBalance(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_BALANCE); } bool IsDecreasedBalance(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_BALANCE); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня кредита //--- получение (3) величины изменения кредита, //--- получение флага изменения кредита больше, чем на величину (4) прироста, (5) уменьшения void SetControlCreditInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_CREDIT,(double)::fabs(value)); } void SetControlCreditDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_CREDIT,(double)::fabs(value)); } void SetControlCreditLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_CREDIT,(double)::fabs(value)); } double GetValueChangedCredit(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_CREDIT); } bool IsIncreasedCredit(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_CREDIT); } bool IsDecreasedCredit(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_CREDIT); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня прибыли //--- получение (3) величины изменения прибыли, //--- получение флага изменения прибыли больше, чем на величину (4) прироста, (5) уменьшения void SetControlProfitInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_PROFIT,(double)::fabs(value)); } void SetControlProfitDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_PROFIT,(double)::fabs(value)); } void SetControlProfitLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_PROFIT,(double)::fabs(value)); } double GetValueChangedProfit(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_PROFIT); } bool IsIncreasedProfit(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_PROFIT); } bool IsDecreasedProfit(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_PROFIT); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня средств //--- получение (3) величины изменения средств, //--- получение флага изменения средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlEquityInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_EQUITY,(double)::fabs(value)); } void SetControlEquityDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_EQUITY,(double)::fabs(value)); } void SetControlEquityLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_EQUITY,(double)::fabs(value)); } double GetValueChangedEquity(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_EQUITY); } bool IsIncreasedEquity(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_EQUITY); } bool IsDecreasedEquity(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_EQUITY); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня залоговых средств //--- получение (3) величины изменения залоговых средств, //--- получение флага изменения залоговых средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN,(double)::fabs(value)); } void SetControlMarginDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN,(double)::fabs(value)); } void SetControlMarginLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN,(double)::fabs(value)); } double GetValueChangedMargin(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN); } bool IsIncreasedMargin(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN); } bool IsDecreasedMargin(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня свободных средств //--- получение (3) величины изменения свободных средств, //--- получение флага изменения свободных средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginFreeInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_FREE,(double)::fabs(value)); } void SetControlMarginFreeDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_FREE,(double)::fabs(value)); } void SetControlMarginFreeLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_FREE,(double)::fabs(value)); } double GetValueChangedMarginFree(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_FREE); } bool IsIncreasedMarginFree(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_FREE); } bool IsDecreasedMarginFree(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_FREE); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня уровня свободных средств //--- получение (3) величины изменения уровня свободных средств, //--- получение флага изменения уровня свободных средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginLevelInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_LEVEL,(double)::fabs(value)); } void SetControlMarginLevelDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_LEVEL,(double)::fabs(value)); } void SetControlMarginLevelLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_LEVEL,(double)::fabs(value)); } double GetValueChangedMarginLevel(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_LEVEL); } bool IsIncreasedMarginLevel(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_LEVEL); } bool IsDecreasedMarginLevel(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_LEVEL); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня Margin Call //--- получение (3) величины изменения уровня Margin Call, //--- получение флага изменения уровня Margin Call больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginCallInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_SO_CALL,(double)::fabs(value)); } void SetControlMarginCallDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_SO_CALL,(double)::fabs(value)); } void SetControlMarginCallLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_SO_CALL,(double)::fabs(value)); } double GetValueChangedMarginCall(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_SO_CALL); } bool IsIncreasedMarginCall(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_SO_CALL); } bool IsDecreasedMarginCall(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_SO_CALL); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня Margin StopOut //--- получение (3) величины изменения уровня Margin StopOut, //--- получение флага изменения уровня Margin StopOut больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginStopOutInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_SO_SO,(double)::fabs(value)); } void SetControlMarginStopOutDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_SO_SO,(double)::fabs(value)); } void SetControlMarginStopOutLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_SO_SO,(double)::fabs(value)); } double GetValueChangedMarginStopOut(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_SO_SO); } bool IsIncreasedMarginStopOut(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_SO_SO); } bool IsDecreasedMarginStopOut(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_SO_SO); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня величины прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам //--- получение (3) величины изменения величины прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам, //--- получение флага изменения величины прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginInitialInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_INITIAL,(double)::fabs(value)); } void SetControlMarginInitialDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_INITIAL,(double)::fabs(value)); } void SetControlMarginInitialLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_INITIAL,(double)::fabs(value)); } double GetValueChangedMarginInitial(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_INITIAL); } bool IsIncreasedMarginInitial(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_INITIAL); } bool IsDecreasedMarginInitial(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_INITIAL); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня величины прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям //--- получение (3) величины изменения величины прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям, //--- получение флага изменения величины прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginMaintenanceInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_MAINTENANCE,(double)::fabs(value)); } void SetControlMarginMaintenanceDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_MAINTENANCE,(double)::fabs(value)); } void SetControlMarginMaintenanceLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_MAINTENANCE,(double)::fabs(value)); } double GetValueChangedMarginMaintenance(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_MAINTENANCE); } bool IsIncreasedMarginMaintenance(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_MAINTENANCE); } bool IsDecreasedMarginMaintenance(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_MAINTENANCE); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня активов //--- получение (3) величины изменения активов, //--- получение флага изменения активов больше, чем на величину (4) прироста, (5) уменьшения void SetControlAssetsInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_ASSETS,(double)::fabs(value)); } void SetControlAssetsDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_ASSETS,(double)::fabs(value)); } void SetControlAssetsLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_ASSETS,(double)::fabs(value)); } double GetValueChangedAssets(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_ASSETS); } bool IsIncreasedAssets(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_ASSETS); } bool IsDecreasedAssets(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_ASSETS); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня обязательств //--- получение (3) величины изменения обязательств, //--- получение флага изменения обязательств больше, чем на величину (4) прироста, (5) уменьшения void SetControlLiabilitiesInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_LIABILITIES,(double)::fabs(value)); } void SetControlLiabilitiesDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_LIABILITIES,(double)::fabs(value)); } void SetControlLiabilitiesLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_LIABILITIES,(double)::fabs(value)); } double GetValueChangedLiabilities(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_LIABILITIES); } bool IsIncreasedLiabilities(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_LIABILITIES); } bool IsDecreasedLiabilities(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_LIABILITIES); } //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня заблокированных комиссий //--- получение (3) величины изменения заблокированных комиссий, //--- получение флага изменения заблокированных комиссий больше, чем на величину (4) прироста, (5) уменьшения void SetControlComissionBlockedInc(const long value) { this.SetControlledValueINC(ACCOUNT_PROP_COMMISSION_BLOCKED,(double)::fabs(value)); } void SetControlComissionBlockedDec(const long value) { this.SetControlledValueDEC(ACCOUNT_PROP_COMMISSION_BLOCKED,(double)::fabs(value)); } void SetControlComissionBlockedLevel(const long value) { this.SetControlledValueLEVEL(ACCOUNT_PROP_COMMISSION_BLOCKED,(double)::fabs(value)); } double GetValueChangedComissionBlocked(void) const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_COMMISSION_BLOCKED); } bool IsIncreasedComissionBlocked(void) const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_COMMISSION_BLOCKED); } bool IsDecreasedComissionBlocked(void) const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_COMMISSION_BLOCKED); } //+------------------------------------------------------------------+
В конструкторе класса сначала укажем размеры массивов данных,
а затем
инициализируем все контролируемые данные в базовом объекте CBaseObj,
и далее — после заполнения всех свойств объекта-аккаунта, заполним
свойства и в базовом объекте. Напоследок обновим все данные аккаунта в
базовом объекте CBaseObj:
//+------------------------------------------------------------------+ //| Конструктор | //+------------------------------------------------------------------+ CAccount::CAccount(void) { //--- Инициализация контролируемых данных this.SetControlDataArraySizeLong(ACCOUNT_PROP_INTEGER_TOTAL); this.SetControlDataArraySizeDouble(ACCOUNT_PROP_DOUBLE_TOTAL); this.ResetChangesParams(); this.ResetControlsParams(); //--- Сохранение целочисленных свойств this.m_long_prop[ACCOUNT_PROP_LOGIN] = ::AccountInfoInteger(ACCOUNT_LOGIN); this.m_long_prop[ACCOUNT_PROP_TRADE_MODE] = ::AccountInfoInteger(ACCOUNT_TRADE_MODE); this.m_long_prop[ACCOUNT_PROP_LEVERAGE] = ::AccountInfoInteger(ACCOUNT_LEVERAGE); this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS] = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS); this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE] = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE); this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED] = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED); this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT] = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT); this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ; this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ; this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE] = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4); //--- Сохранение вещественных свойств this.m_double_prop[this.IndexProp(ACCOUNT_PROP_BALANCE)] = ::AccountInfoDouble(ACCOUNT_BALANCE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_CREDIT)] = ::AccountInfoDouble(ACCOUNT_CREDIT); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_PROFIT)] = ::AccountInfoDouble(ACCOUNT_PROFIT); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_EQUITY)] = ::AccountInfoDouble(ACCOUNT_EQUITY); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN)] = ::AccountInfoDouble(ACCOUNT_MARGIN); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_FREE)] = ::AccountInfoDouble(ACCOUNT_MARGIN_FREE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_LEVEL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_LEVEL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_CALL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_SO)] = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_SO); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_INITIAL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_INITIAL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_MAINTENANCE)]=::AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_ASSETS)] = ::AccountInfoDouble(ACCOUNT_ASSETS); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_LIABILITIES)] = ::AccountInfoDouble(ACCOUNT_LIABILITIES); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_COMMISSION_BLOCKED)]=::AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED); //--- Сохранение строковых свойств this.m_string_prop[this.IndexProp(ACCOUNT_PROP_NAME)] = ::AccountInfoString(ACCOUNT_NAME); this.m_string_prop[this.IndexProp(ACCOUNT_PROP_SERVER)] = ::AccountInfoString(ACCOUNT_SERVER); this.m_string_prop[this.IndexProp(ACCOUNT_PROP_CURRENCY)] = ::AccountInfoString(ACCOUNT_CURRENCY); this.m_string_prop[this.IndexProp(ACCOUNT_PROP_COMPANY)] = ::AccountInfoString(ACCOUNT_COMPANY); //--- Имя объекта-аккаунта this.m_name=TextByLanguage("Счёт ","Account ")+(string)this.Login()+": "+this.Name()+" ("+this.Company()+")"; this.m_type=COLLECTION_ACCOUNT_ID; //--- Заполнение текущих данных аккаунта for(int i=0;i<ACCOUNT_PROP_INTEGER_TOTAL;i++) this.m_long_prop_event[i][3]=this.m_long_prop[i]; for(int i=0;i<ACCOUNT_PROP_DOUBLE_TOTAL;i++) this.m_double_prop_event[i][3]=this.m_double_prop[i]; //--- Обновление данных в базовом объекте и поиск изменений CBaseObj::Refresh(); } //+-------------------------------------------------------------------+
За пределами тела класса напишем реализацию виртуального метода обновления данных аккаунта:
//+------------------------------------------------------------------+ //| Обновляет все данные аккаунта | //+------------------------------------------------------------------+ void CAccount::Refresh(void) { //--- Инициализация событийных данных this.m_is_event=false; this.m_hash_sum=0; //--- Обновление целочисленных свойств this.m_long_prop[ACCOUNT_PROP_LOGIN] = ::AccountInfoInteger(ACCOUNT_LOGIN); this.m_long_prop[ACCOUNT_PROP_TRADE_MODE] = ::AccountInfoInteger(ACCOUNT_TRADE_MODE); this.m_long_prop[ACCOUNT_PROP_LEVERAGE] = ::AccountInfoInteger(ACCOUNT_LEVERAGE); this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS] = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS); this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE] = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE); this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED] = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED); this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT] = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT); this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ; this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ; this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE] = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4); //--- Обновление вещественных свойств this.m_double_prop[this.IndexProp(ACCOUNT_PROP_BALANCE)] = ::AccountInfoDouble(ACCOUNT_BALANCE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_CREDIT)] = ::AccountInfoDouble(ACCOUNT_CREDIT); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_PROFIT)] = ::AccountInfoDouble(ACCOUNT_PROFIT); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_EQUITY)] = ::AccountInfoDouble(ACCOUNT_EQUITY); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN)] = ::AccountInfoDouble(ACCOUNT_MARGIN); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_FREE)] = ::AccountInfoDouble(ACCOUNT_MARGIN_FREE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_LEVEL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_LEVEL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_CALL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_SO)] = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_SO); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_INITIAL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_INITIAL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_MAINTENANCE)] =::AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_ASSETS)] = ::AccountInfoDouble(ACCOUNT_ASSETS); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_LIABILITIES)] = ::AccountInfoDouble(ACCOUNT_LIABILITIES); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_COMMISSION_BLOCKED)] =::AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED); //--- Заполнение текущих данных аккаунта в базовом объекте for(int i=0;i<ACCOUNT_PROP_INTEGER_TOTAL;i++) this.m_long_prop_event[i][3]=this.m_long_prop[i]; for(int i=0;i<ACCOUNT_PROP_DOUBLE_TOTAL;i++) this.m_double_prop_event[i][3]=this.m_double_prop[i]; //--- Обновление данных в базовом объекте и поиск изменений CBaseObj::Refresh(); this.CheckEvents(); } //+------------------------------------------------------------------+
Здесь сначала сбрасывается флаг события аккаунта и обнуляется
хэш-сумма (скорее всего и от хэш-суммы далее избавимся, если окажется, что она не потребуется для других объектов на основе
CBaseObj).
Далее заполняются все свойства объекта-аккаунта, а затем — как и в конструкторе класса — заполняются
данные аккаунта в базовом объекте, вызывается метод обновления базового
объекта, в котором происходит помимо обновления текущих данных ещё и поиск изменения значений свойств объекта, и при превышении
величины изменения значений, заданных для поиска событий, генерируются базовые события объекта.
Затем при помощи метода CheckEvents() родительского класса проверяем
наличие базовых событий в списке базовых событий объекта CBaseObj, и при их наличии метод создаёт список событий своего
наследника: в данном случае — список событий аккаунта.
Класс CAccount доработан.
Теперь внесём правки в класс коллекции аккаунтов.
Откроем файл \MQL5\Include\DoEasy\Collections\AccountsCollection.mqh и внесём в
него необходимые изменения.
Удалим всё ставшее ненужным:
//+------------------------------------------------------------------+ //| Коллекция аккаунтов | //+------------------------------------------------------------------+ class CAccountsCollection : public CBaseObj { private: struct MqlDataAccount { //--- Целочисленные свойства счёта long login; // ACCOUNT_LOGIN (Номер счёта) long leverage; // ACCOUNT_LEVERAGE (Размер предоставленного плеча) int limit_orders; // ACCOUNT_LIMIT_ORDERS (Максимально допустимое количество действующих отложенных ордеров) bool trade_allowed; // ACCOUNT_TRADE_ALLOWED (Разрешенность торговли для текущего счета со стороны сервера) bool trade_expert; // ACCOUNT_TRADE_EXPERT (Разрешенность торговли для эксперта со стороны сервера) //--- Вещественные свойства счёта double balance; // ACCOUNT_BALANCE (Баланс счета в валюте депозита) double credit; // ACCOUNT_CREDIT (Размер предоставленного кредита в валюте депозита) double profit; // ACCOUNT_PROFIT (Размер текущей прибыли на счете в валюте депозита) double equity; // ACCOUNT_EQUITY (Значение собственных средств на счете в валюте депозита) double margin; // ACCOUNT_MARGIN (Размер зарезервированных залоговых средств на счете в валюте депозита) double margin_free; // ACCOUNT_MARGIN_FREE (Размер свободных средств на счете в валюте депозита, доступных для открытия позиции) double margin_level; // ACCOUNT_MARGIN_LEVEL (Уровень залоговых средств на счете в процентах) double margin_so_call; // ACCOUNT_MARGIN_SO_CALL (Уровень залоговых средств, при котором происходит MarginCall) double margin_so_so; // ACCOUNT_MARGIN_SO_SO (Уровень залоговых средств, при достижении которого происходит StopOut) double margin_initial; // ACCOUNT_MARGIN_INITIAL (Размер средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам) double margin_maintenance; // ACCOUNT_MARGIN_MAINTENANCE (Размер средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям) double assets; // ACCOUNT_ASSETS (Текущий размер активов на счёте) double liabilities; // ACCOUNT_LIABILITIES (Текущий размер обязательств на счёте) double comission_blocked; // ACCOUNT_COMMISSION_BLOCKED (Текущая сумма заблокированных комиссий по счёту) }; MqlDataAccount m_struct_curr_account; // Текущие данные счёта MqlDataAccount m_struct_prev_account; // Прошлые данные счёта string m_symbol; // Текущий символ CListObj m_list_accounts; // Список объектов-аккаунтов int m_index_current; // Индекс объекта-аккаунта с данными текущего счёта //--- Плечо long m_changed_leverage_value; // Величина изменения плеча bool m_is_change_leverage_inc; // Флаг увеличения плеча bool m_is_change_leverage_dec; // Флаг уменьшения плеча //--- Количество действующих отложенных ордеров int m_changed_limit_orders_value; // Величина изменения максимально допустимого количества действующих отложенных ордеров bool m_is_change_limit_orders_inc; // Флаг увеличения максимально допустимого количества действующих отложенных ордеров bool m_is_change_limit_orders_dec; // Флаг уменьшения максимально допустимого количества действующих отложенных ордеров //--- Торговля на счёте bool m_is_change_trade_allowed_on; // Флаг разрешения торговли для текущего счета со стороны сервера bool m_is_change_trade_allowed_off; // Флаг запрета торговли для текущего счета со стороны сервера //--- Автоторговля на счёте bool m_is_change_trade_expert_on; // Флаг разрешения торговли для эксперта со стороны сервера bool m_is_change_trade_expert_off; // Флаг запрета торговли для эксперта со стороны сервера //--- Баланс double m_control_balance_inc; // Контролируемая величина прироста баланса double m_control_balance_dec; // Контролируемая величина уменьшения баланса double m_changed_balance_value; // Величина изменения баланса bool m_is_change_balance_inc; // Флаг изменения баланса больше, чем на величину прироста bool m_is_change_balance_dec; // Флаг изменения баланса больше, чем на величину уменьшения //--- Кредит double m_changed_credit_value; // Величина изменения кредита bool m_is_change_credit_inc; // Флаг увеличения кредита bool m_is_change_credit_dec; // Флаг уменьшения кредита //--- Профит double m_control_profit_inc; // Контролируемая величина прироста прибыли double m_control_profit_dec; // Контролируемая величина уменьшения прибыли double m_changed_profit_value; // Величина изменения прибыли bool m_is_change_profit_inc; // Флаг изменения прибыли больше, чем на величину прироста bool m_is_change_profit_dec; // Флаг изменения прибыли больше, чем на величину уменьшения //--- Средства double m_control_equity_inc; // Контролируемая величина прироста средств double m_control_equity_dec; // Контролируемая величина уменьшения средств double m_changed_equity_value; // Величина изменения средств bool m_is_change_equity_inc; // Флаг изменения средств больше, чем на величину прироста bool m_is_change_equity_dec; // Флаг изменения средств больше, чем на величину уменьшения //--- Маржа double m_control_margin_inc; // Контролируемая величина прироста залоговых средств double m_control_margin_dec; // Контролируемая величина уменьшения залоговых средств double m_changed_margin_value; // Величина изменения залоговых средств bool m_is_change_margin_inc; // Флаг изменения залоговых средств больше, чем на величину прироста bool m_is_change_margin_dec; // Флаг изменения залоговых средств больше, чем на величину уменьшения //--- Свободная маржа double m_control_margin_free_inc; // Контролируемая величина прироста свободных средств double m_control_margin_free_dec; // Контролируемая величина уменьшения свободных средств double m_changed_margin_free_value; // Величина изменения свободных средств bool m_is_change_margin_free_inc; // Флаг изменения свободных средств больше, чем на величину прироста bool m_is_change_margin_free_dec; // Флаг изменения свободных средств больше, чем на величину уменьшения //--- Уровень маржи double m_control_margin_level_inc; // Контролируемая величина прироста уровня свободных средств double m_control_margin_level_dec; // Контролируемая величина уменьшения уровня свободных средств double m_changed_margin_level_value; // Величина изменения уровня свободных средств bool m_is_change_margin_level_inc; // Флаг изменения уровня свободных средств больше, чем на величину прироста bool m_is_change_margin_level_dec; // Флаг изменения уровня свободных средств больше, чем на величину уменьшения //--- Margin Call double m_changed_margin_so_call_value; // Величина изменения уровня Margin Call bool m_is_change_margin_so_call_inc; // Флаг увеличения уровня Margin Call bool m_is_change_margin_so_call_dec; // Флаг уменьшения уровня Margin Call //--- MarginStopOut double m_changed_margin_so_so_value; // Величина изменения уровня Margin StopOut bool m_is_change_margin_so_so_inc; // Флаг увеличения уровня Margin StopOut bool m_is_change_margin_so_so_dec; // Флаг уменьшения уровня Margin StopOut //--- Гарантийная сумма по отложенным ордерам double m_control_margin_initial_inc; // Контролируемая величина прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам double m_control_margin_initial_dec; // Контролируемая величина уменьшения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам double m_changed_margin_initial_value; // Величина изменения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам bool m_is_change_margin_initial_inc; // Флаг изменения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам больше, чем на величину прироста bool m_is_change_margin_initial_dec; // Флаг изменения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам больше, чем на величину уменьшения //--- Гарантийная сумма по открытым позициям double m_control_margin_maintenance_inc; // Контролируемая величина прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям double m_control_margin_maintenance_dec; // Контролируемая величина уменьшения зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям double m_changed_margin_maintenance_value; // Величина изменения размера зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям bool m_is_change_margin_maintenance_inc; // Флаг изменения размера зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям bool m_is_change_margin_maintenance_dec; // Флаг изменения размера зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям //--- Активы double m_control_assets_inc; // Контролируемая величина прироста активов double m_control_assets_dec; // Контролируемая величина уменьшения активов double m_changed_assets_value; // Величина изменения активов bool m_is_change_assets_inc; // Флаг изменения активов больше, чем на величину прироста bool m_is_change_assets_dec; // Флаг изменения активов больше, чем на величину уменьшения //--- Обязательства double m_control_liabilities_inc; // Контролируемая величина прироста обязательств double m_control_liabilities_dec; // Контролируемая величина уменьшения обязательств double m_changed_liabilities_value; // Величина изменения обязательств bool m_is_change_liabilities_inc; // Флаг изменения обязательств больше, чем на величину прироста bool m_is_change_liabilities_dec; // Флаг изменения обязательств больше, чем на величину уменьшения //--- Заблокированные комиссии double m_control_comission_blocked_inc; // Контролируемая величина прироста заблокированных комиссий double m_control_comission_blocked_dec; // Контролируемая величина уменьшения заблокированных комиссий double m_changed_comission_blocked_value; // Величина изменения заблокированных комиссий bool m_is_change_comission_blocked_inc; // Флаг изменения заблокированных комиссий больше, чем на величину прироста bool m_is_change_comission_blocked_dec; // Флаг изменения заблокированных комиссий больше, чем на величину уменьшения //--- Инициализирует переменные (1) отслеживаемых, (2) контролируемых данных аккаунта void InitChangesParams(void); void InitControlsParams(void); //--- Устанавливает тип события и заполняет список событий virtual void SetTypeEvent(void); //--- Записывает данные текущего счёта в свойства объекта-аккаунта void SetAccountsParams(CAccount* account); //--- Проверяет наличие объекта-аккаунта в списке-коллекции bool IsPresent(CAccount* account); //--- Находит и возвращает индекс объекта-аккаунта с данными текущего счёта int Index(void); public: //--- Возвращает полный список-коллекцию аккаунтов "как есть" CArrayObj *GetList(void) { return &this.m_list_accounts; } //--- Возвращает список по выбранному (1) целочисленному, (2) вещественному и (3) строковому свойству, удовлетворяющему сравниваемому критерию CArrayObj *GetList(ENUM_ACCOUNT_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);} CArrayObj *GetList(ENUM_ACCOUNT_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);} CArrayObj *GetList(ENUM_ACCOUNT_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);} //--- Возвращает (1) индекс текущего объекта-аккаунта, (2) идентификатор события по его номеру в списке int IndexCurrentAccount(void) const { return this.m_index_current; } ENUM_ACCOUNT_EVENT GetEventID(const int shift=WRONG_VALUE,const bool check_out=true); //--- (1) Устанавливает, (2) возвращает текущий символ void SetSymbol(const string symbol) { this.m_symbol=symbol; } string GetSymbol(void) const { return this.m_symbol; } //--- Конструктор, деструктор CAccountsCollection(); ~CAccountsCollection(); //--- Добавляет объект-аккаунт в список bool AddToList(CAccount* account); //--- (1) Сохраняет объекты-аккаунты из списка в файлы //--- (2) Загружает объекты-аккаунты из файлов в список bool SaveObjects(void); bool LoadObjects(void); //--- Возвращает описание события аккаунта string EventDescription(const ENUM_ACCOUNT_EVENT event); //--- Обновляет данные текущего аккаунта virtual void Refresh(void); //--- Получение и установка параметров отслеживаемых изменений //--- Плечо: //--- (1) Величина изменения плеча, (2) Флаг увеличения плеча, (3) Флаг уменьшения плеча long GetValueChangedLeverage(void) const { return this.m_changed_leverage_value; } bool IsIncreaseLeverage(void) const { return this.m_is_change_leverage_inc; } bool IsDecreaseLeverage(void) const { return this.m_is_change_leverage_dec; } //--- Количество действующих отложенных ордеров: //--- (1) Величина изменения, (2) Флаг увеличения, (3) Флаг уменьшения int GetValueChangedLimitOrders(void) const { return this.m_changed_limit_orders_value; } bool IsIncreaseLimitOrders(void) const { return this.m_is_change_limit_orders_inc; } bool IsDecreaseLimitOrders(void) const { return this.m_is_change_limit_orders_dec; } //--- Торговля на счёте: //--- (1) Флаг разрешения торговли для текущего счета, (2) Флаг запрета торговли для текущего счета со стороны сервера bool IsOnTradeAllowed(void) const { return this.m_is_change_trade_allowed_on; } bool IsOffTradeAllowed(void) const { return this.m_is_change_trade_allowed_off; } //--- Автоторговля на счёте: //--- (1) Флаг разрешения торговли для эксперта, (2) Флаг запрета торговли для эксперта со стороны сервера bool IsOnTradeExpert(void) const { return this.m_is_change_trade_expert_on; } bool IsOffTradeExpert(void) const { return this.m_is_change_trade_expert_off; } //--- Баланс: //--- установка контролируемой величины (1) прироста, (2) уменьшения баланса //--- получение (3) величины изменения баланса, //--- получение флага изменения баланса больше, чем на величину (4) прироста, (5) уменьшения void SetControlBalanceInc(const double value) { this.m_control_balance_inc=::fabs(value); } void SetControlBalanceDec(const double value) { this.m_control_balance_dec=::fabs(value); } double GetValueChangedBalance(void) const { return this.m_changed_balance_value; } bool IsIncreaseBalance(void) const { return this.m_is_change_balance_inc; } bool IsDecreaseBalance(void) const { return this.m_is_change_balance_dec; } //--- Кредит: //--- получение (1) величины изменения кредита, (2) флага увеличения кредита, (3) флага уменьшения кредита double GetValueChangedCredit(void) const { return this.m_changed_credit_value; } bool IsIncreaseCredit(void) const { return this.m_is_change_credit_inc; } bool IsDecreaseCredit(void) const { return this.m_is_change_credit_dec; } //--- Профит: //--- установка контролируемой величины (1) прироста, (2) уменьшения прибыли //--- получение (3) величины изменения прибыли, //--- получение флага изменения прибыли больше, чем на величину (4) прироста, (5) уменьшения void SetControlProfitInc(const double value) { this.m_control_profit_inc=::fabs(value); } void SetControlProfitDec(const double value) { this.m_control_profit_dec=::fabs(value); } double GetValueChangedProfit(void) const { return this.m_changed_profit_value; } bool IsIncreaseProfit(void) const { return this.m_is_change_profit_inc; } bool IsDecreaseProfit(void) const { return this.m_is_change_profit_dec; } //--- Средства: //--- установка контролируемой величины (1) прироста, (2) уменьшения средств //--- получение (3) величины изменения средств, //--- получение флага изменения средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlEquityInc(const double value) { this.m_control_equity_inc=::fabs(value); } void SetControlEquityDec(const double value) { this.m_control_equity_dec=::fabs(value); } double GetValueChangedEquity(void) const { return this.m_changed_equity_value; } bool IsIncreaseEquity(void) const { return this.m_is_change_equity_inc; } bool IsDecreaseEquity(void) const { return this.m_is_change_equity_dec; } //--- Маржа: //--- установка контролируемой величины (1) прироста, (2) уменьшения залоговых средств //--- получение (3) величины изменения залоговых средств, //--- получение флага изменения залоговых средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginInc(const double value) { this.m_control_margin_inc=::fabs(value); } void SetControlMarginDec(const double value) { this.m_control_margin_dec=::fabs(value); } double GetValueChangedMargin(void) const { return this.m_changed_margin_value; } bool IsIncreaseMargin(void) const { return this.m_is_change_margin_inc; } bool IsDecreaseMargin(void) const { return this.m_is_change_margin_dec; } //--- Свободная маржа: //--- установка контролируемой величины (1) прироста, (2) уменьшения свободных средств //--- получение (3) величины изменения свободных средств, //--- получение флага изменения свободных средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginFreeInc(const double value) { this.m_control_margin_free_inc=::fabs(value); } void SetControlMarginFreeDec(const double value) { this.m_control_margin_free_dec=::fabs(value); } double GetValueChangedMarginFree(void) const { return this.m_changed_margin_free_value; } bool IsIncreaseMarginFree(void) const { return this.m_is_change_margin_free_inc; } bool IsDecreaseMarginFree(void) const { return this.m_is_change_margin_free_dec; } //--- Уровень маржи: //--- установка контролируемой величины (1) прироста, (2) уменьшения уровня свободных средств //--- получение (3) величины изменения уровня свободных средств, //--- получение флага изменения уровня свободных средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginLevelInc(const double value) { this.m_control_margin_level_inc=::fabs(value); } void SetControlMarginLevelDec(const double value) { this.m_control_margin_level_dec=::fabs(value); } double GetValueChangedMarginLevel(void) const { return this.m_changed_margin_level_value; } bool IsIncreaseMarginLevel(void) const { return this.m_is_change_margin_level_inc; } bool IsDecreaseMarginLevel(void) const { return this.m_is_change_margin_level_dec; } //--- Margin Call: //--- получение (1) величины изменения Margin Call, (2) флага увеличения уровня Margin Call, (3) флага уменьшения уровня Margin Call double GetValueChangedMarginCall(void) const { return this.m_changed_margin_so_call_value; } bool IsIncreaseMarginCall(void) const { return this.m_is_change_margin_so_call_inc; } bool IsDecreaseMarginCall(void) const { return this.m_is_change_margin_so_call_dec; } //--- Margin StopOut: //--- получение (1) величины изменения Margin StopOut, (2) флага увеличения уровня Margin StopOut, (3) флага уменьшения уровня Margin StopOut double GetValueChangedMarginStopOut(void) const { return this.m_changed_margin_so_so_value; } bool IsIncreaseMarginStopOut(void) const { return this.m_is_change_margin_so_so_inc; } bool IsDecreasMarginStopOute(void) const { return this.m_is_change_margin_so_so_dec; } //--- Гарантийная сумма по отложенным ордерам: //--- установка контролируемой величины (1) прироста, (2) уменьшения размера зарезервированных средств гарантийной суммы по отложенным ордерам //--- получение (3) величины изменения уровня зарезервированных средств, //--- получение флага изменения уровня зарезервированных средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginInitialInc(const double value) { this.m_control_margin_initial_inc=::fabs(value); } void SetControlMarginInitialDec(const double value) { this.m_control_margin_initial_dec=::fabs(value); } double GetValueChangedMarginInitial(void) const { return this.m_changed_margin_initial_value; } bool IsIncreaseMarginInitial(void) const { return this.m_is_change_margin_initial_inc; } bool IsDecreaseMarginInitial(void) const { return this.m_is_change_margin_initial_dec; } //--- Гарантийная сумма по открытым позициям: //--- установка контролируемой величины (1) прироста, (2) уменьшения размера зарезервированных средств гарантийной суммы по открытым позициям //--- получение (3) величины изменения уровня зарезервированных средств, //--- получение флага изменения уровня зарезервированных средств больше, чем на величину (4) прироста, (5) уменьшения void SetControlMarginMaintenanceInc(const double value) { this.m_control_margin_maintenance_inc=::fabs(value); } void SetControlMarginMaintenanceDec(const double value) { this.m_control_margin_maintenance_dec=::fabs(value); } double GetValueChangedMarginMaintenance(void) const { return this.m_changed_margin_maintenance_value; } bool IsIncreaseMarginMaintenance(void) const { return this.m_is_change_margin_maintenance_inc; } bool IsDecreaseMarginMaintenance(void) const { return this.m_is_change_margin_maintenance_dec; } //--- Активы: //--- установка контролируемой величины (1) прироста, (2) уменьшения активов //--- получение (3) величины изменения уровня активов, //--- получение флага изменения уровня активов больше, чем на величину (4) прироста, (5) уменьшения void SetControlAssetsInc(const double value) { this.m_control_assets_inc=::fabs(value); } void SetControlAssetsDec(const double value) { this.m_control_assets_dec=::fabs(value); } double GetValueChangedAssets(void) const { return this.m_changed_assets_value; } bool IsIncreaseAssets(void) const { return this.m_is_change_assets_inc; } bool IsDecreaseAssets(void) const { return this.m_is_change_assets_dec; } //--- Обязательства: //--- установка контролируемой величины (1) прироста, (2) уменьшения обязательств //--- получение (3) величины изменения уровня обязательств, //--- получение флага изменения уровня обязательств больше, чем на величину (4) прироста, (5) уменьшения void SetControlLiabilitiesInc(const double value) { this.m_control_liabilities_inc=::fabs(value); } void SetControlLiabilitiesDec(const double value) { this.m_control_liabilities_dec=::fabs(value); } double GetValueChangedLiabilities(void) const { return this.m_changed_liabilities_value; } bool IsIncreaseLiabilities(void) const { return this.m_is_change_liabilities_inc; } bool IsDecreaseLiabilities(void) const { return this.m_is_change_liabilities_dec; } //--- Заблокированные комиссии: //--- установка контролируемой величины (1) прироста, (2) уменьшения заблокированных комиссий //--- получение (3) величины изменения уровня заблокированных комиссий, //--- получение флага изменения уровня заблокированных комиссий больше, чем на величину (4) прироста, (5) уменьшения void SetControlComissionBlockedInc(const double value) { this.m_control_comission_blocked_inc=::fabs(value); } void SetControlComissionBlockedDec(const double value) { this.m_control_comission_blocked_dec=::fabs(value); } double GetValueChangedComissionBlocked(void) const { return this.m_changed_comission_blocked_value; } bool IsIncreaseComissionBlocked(void) const { return this.m_is_change_comission_blocked_inc; } bool IsDecreaseComissionBlocked(void) const { return this.m_is_change_comission_blocked_dec; } }; //+------------------------------------------------------------------+
Изменим типы методов и добавим объявления некоторых необходимых переменных и методов:
//+------------------------------------------------------------------+ //| Коллекция аккаунтов | //+------------------------------------------------------------------+ class CAccountsCollection : public CBaseObj { private: string m_symbol; // Текущий символ CListObj m_list_accounts; // Список объектов-аккаунтов int m_index_current; // Индекс объекта-аккаунта с данными текущего счёта int m_last_event; // Последнее событие //--- Проверяет наличие объекта-аккаунта в списке-коллекции bool IsPresent(CAccount* account); //--- Находит и возвращает индекс объекта-аккаунта с данными текущего счёта int Index(void); public: //--- Возвращает полный список-коллекцию аккаунтов "как есть" CArrayObj *GetList(void) { return &this.m_list_accounts; } //--- Возвращает список по выбранному (1) целочисленному, (2) вещественному и (3) строковому свойству, удовлетворяющему сравниваемому критерию CArrayObj *GetList(ENUM_ACCOUNT_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);} CArrayObj *GetList(ENUM_ACCOUNT_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);} CArrayObj *GetList(ENUM_ACCOUNT_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);} //--- Возвращает (1) индекс текущего объекта-аккаунта, (2) идентификатор события по его номеру в списке int IndexCurrentAccount(void) const { return this.m_index_current; } int GetEventID(const int shift=WRONG_VALUE,const bool check_out=true); //--- (1) Устанавливает, (2) возвращает текущий символ void SetSymbol(const string symbol) { this.m_symbol=symbol; } string GetSymbol(void) const { return this.m_symbol; } //--- (1) Обновляет данные, (2) работа с событиями текущего аккаунта virtual void Refresh(void); void RefreshAndEventsControl(void); //--- Конструктор, деструктор CAccountsCollection(); ~CAccountsCollection(); //--- Добавляет объект-аккаунт в список bool AddToList(CAccount* account); //--- (1) Сохраняет объекты-аккаунты из списка в файлы //--- (2) Загружает объекты-аккаунты из файлов в список bool SaveObjects(void); bool LoadObjects(void); };
Удалим из конструктора класса вызов двух, теперь удалённых методов, и очистку удалённой структуры:
//+------------------------------------------------------------------+ //| Конструктор | //+------------------------------------------------------------------+ CAccountsCollection::CAccountsCollection(void) : m_symbol(::Symbol()) { this.m_list_accounts.Clear(); this.m_list_accounts.Sort(SORT_BY_ACCOUNT_LOGIN); this.m_list_accounts.Type(COLLECTION_ACCOUNT_ID); ::ZeroMemory(this.m_struct_prev_account); ::ZeroMemory(this.m_tick); this.InitChangesParams(); this.InitControlsParams(); //--- Создание папки хранения файлов аккаунтов this.SetSubFolderName("Accounts"); ::ResetLastError(); if(!::FolderCreate(this.m_folder_name,FILE_COMMON)) ::Print(DFUN,TextByLanguage("Не удалось создать папку хранения файлов. Ошибка ","Could not create file storage folder. Error "),::GetLastError()); //--- Создание и добавление в список объекта-аккаунта текущего счёта CAccount* account=new CAccount(); if(account!=NULL) { if(!this.AddToList(account)) { ::Print(DFUN_ERR_LINE,TextByLanguage("Ошибка. Не удалось добавить текущий объект-аккаунт в список-коллекцию.","Error. Failed to add current account object to collection list.")); delete account; } else account.PrintShort(); } else ::Print(DFUN,TextByLanguage("Ошибка. Не удалось создать объект-аккаунт с данными текущего счёта.","Error. Failed to create an account object with current account data.")); //--- Загрузка объектов-аккаунтов из файлов в коллекцию this.LoadObjects(); //--- Сохранение индекса текущего аккаунта this.m_index_current=this.Index(); } //+------------------------------------------------------------------+
Все эти переменные, структуры и методы теперь заменены уже готовым функционалом базового объекта и для классов-наследников их заново делать не нужно. Равно как и в методе обновления данных аккаунта нужно удалить событийный функционал:
//+------------------------------------------------------------------+ //| Обновляет данные текущего аккаунта | //+------------------------------------------------------------------+ void CAccountsCollection::Refresh(void) { ::ResetLastError(); if(!::SymbolInfoTick(::Symbol(),this.m_tick)) { this.m_global_error=::GetLastError(); return; } if(this.m_index_current==WRONG_VALUE) return; CAccount* account=this.m_list_accounts.At(this.m_index_current); if(account==NULL) return; //--- Подготовка событийных данных this.m_is_event=false; ::ZeroMemory(this.m_struct_curr_account); this.m_hash_sum=0; this.SetAccountsParams(account); //--- Первый запуск if(!this.m_struct_prev_account.login) { this.m_struct_prev_account=this.m_struct_curr_account; this.m_hash_sum_prev=this.m_hash_sum; return; } //--- Если хэш-сумма аккаунта изменилась if(this.m_hash_sum!=this.m_hash_sum_prev) { this.m_list_events.Clear(); this.m_event_code=this.SetEventCode(); this.SetTypeEvent(); int total=this.m_list_events.Total(); if(total>0) { this.m_is_event=true; for(int i=0;i<total;i++) { CEventBaseObj *event=this.GetEvent(i,false); if(event==NULL) continue; ENUM_ACCOUNT_EVENT event_id=(ENUM_ACCOUNT_EVENT)event.ID(); if(event_id==ACCOUNT_EVENT_NO_EVENT) continue; long lparam=event.LParam(); double dparam=event.DParam(); string sparam=event.SParam(); ::EventChartCustom(this.m_chart_id,(ushort)event_id,lparam,dparam,sparam); } } this.m_hash_sum_prev=this.m_hash_sum; } } //+------------------------------------------------------------------+
Всё удалённое заменяем на вызов метода обновления базового класса:
//+------------------------------------------------------------------+ //| Обновляет данные текущего аккаунта | //+------------------------------------------------------------------+ void CAccountsCollection::Refresh(void) { ::ResetLastError(); if(!::SymbolInfoTick(::Symbol(),this.m_tick)) { this.m_global_error=::GetLastError(); return; } if(this.m_index_current==WRONG_VALUE) return; CAccount* account=this.m_list_accounts.At(this.m_index_current); if(account==NULL) return; account.Refresh(); } //+------------------------------------------------------------------+
Метод, обновляющий данные объекта и ищущий изменения свойств для генерации событий:
//+------------------------------------------------------------------+ //| Работа с событиями списка символов коллекции | //+------------------------------------------------------------------+ void CAccountsCollection::RefreshAndEventsControl(void) { ::ResetLastError(); if(!::SymbolInfoTick(::Symbol(),this.m_tick)) { this.m_global_error=::GetLastError(); return; } if(this.m_index_current==WRONG_VALUE) return; this.m_is_event=false; this.m_list_events.Clear(); this.m_list_events.Sort(); CAccount* account=this.m_list_accounts.At(this.m_index_current); if(account==NULL) return; account.Refresh(); if(!account.IsEvent()) return; CArrayObj *list=account.GetListEvents(); if(list==NULL) return; this.m_is_event=true; this.m_event_code=account.GetEventCode(); int n=list.Total(); for(int j=0; j<n; j++) { CEventBaseObj *event=list.At(j); if(event==NULL) continue; this.m_last_event=event.ID(); if(this.EventAdd((ushort)event.ID(),event.LParam(),event.DParam(),event.SParam())) { ::EventChartCustom(this.m_chart_id,(ushort)event.ID(),event.LParam(),event.DParam(),event.SParam()); } } } //+------------------------------------------------------------------+
Здесь: получаем тик текущего символа, и при ошибке его получения сохраняем код
ошибки выходим из метода. Если текущий аккаунт в списке коллекции аккаунтов по какой-то причине не был найден, и его
индекс отрицателен, то выходим из метода.
Сбрасываем флаг
события аккаунта, очищаем список событий аккаунта и устанавливаем ему флаг
сортированного списка.
Получаем объект текущего аккаунта из списка
коллекции аккаунтов и обновляем данные аккаунта.
Если в данный момент нет события аккаунта, то дальше делать нечего —
выходим из метода.
Иначе — получаем список базовых событий аккаунта из
базового объекта, ставим флаг события аккаунта, получаем
код последнего события (тоже скорее всего далее удалим эти "пережитки прошлого"), и в
цикле по списку базовых событий получаем очередное событие из списка, сохраняем
последнее событие аккаунта, добавляем его в список событий аккаунта и отправляем
событие на график управляющей программы.
Удалим из листинга класса реализации методов SetAccountsParams(), SetEventCode(), EventDescription(), InitChangesParams() и InitControlsParams().
Метод, возвращающий событие аккаунта по его номеру в списке, ранее возвращал значение перечисления. Теперь
перечисление удалено, и метод возвращает
int-значение. Соответственно, если
событие не найдено, то возвращаем -1:
//+------------------------------------------------------------------+ //| Возвращает событие аккаунта по его номеру в списке | //+------------------------------------------------------------------+ int CAccountsCollection::GetEventID(const int shift=WRONG_VALUE,const bool check_out=true) { CEventBaseObj *event=this.GetEvent(shift,check_out); if(event==NULL) return WRONG_VALUE; return (int)event.ID(); } //+------------------------------------------------------------------+
Это все необходимые изменения в классе коллекции аккаунтов.
Осталось внести небольшие изменения в класс основного объекта библиотеки CEngine.
Откроем файл
\MQL5\Include\DoEasy\
Engine.mqh и внесём изменения.
Ранее переменная, хранящая последнее событие аккаунта m_last_account_event и методы, возвращающие её GetAccountEventByIndex() и LastAccountEvent(),
имели тип перечисления
ENUM_ACCOUNT_EVENT, от которого мы избавились. Сделаем их с типом
int:
//+------------------------------------------------------------------+ //| Класс-основа библиотеки | //+------------------------------------------------------------------+ class CEngine : public CObject { private: CHistoryCollection m_history; // Коллекция исторических ордеров и сделок CMarketCollection m_market; // Коллекция рыночных ордеров и сделок CEventsCollection m_events; // Коллекция событий CAccountsCollection m_accounts; // Коллекция аккаунтов CSymbolsCollection m_symbols; // Коллекция символов CArrayObj m_list_counters; // Список счётчиков таймера int m_global_error; // Код глобальной ошибки bool m_first_start; // Флаг первого запуска bool m_is_hedge; // Флаг хедж-счёта bool m_is_tester; // Флаг работы в тестере bool m_is_market_trade_event; // Флаг торгового события на счёте bool m_is_history_trade_event; // Флаг торгового события в истории счёта bool m_is_account_event; // Флаг события изменения аккаунта bool m_is_symbol_event; // Флаг события изменения свойств символа ENUM_TRADE_EVENT m_last_trade_event; // Последнее торговое событие на счёте int m_last_account_event; // Последнее событие в свойствах счёта
//--- Возвращает список (1) аккаунтов, (2) событий аккаунтов, (3) событие изменения аккаунта по его индексу в списке //--- (4) текущий аккаунт, (5) описание события CArrayObj *GetListAllAccounts(void) { return this.m_accounts.GetList(); } CArrayObj *GetListAccountEvents(void) { return this.m_accounts.GetListEvents(); } int GetAccountEventByIndex(const int index=-1) { return this.m_accounts.GetEventID(index); } CAccount *GetAccountCurrent(void);
//--- Возвращает (1) последнее торговое событие, (2) последнее событие в свойствах счёта, (3) флаг счёта-хедж, (4) флаг работы в тестере ENUM_TRADE_EVENT LastTradeEvent(void) const { return this.m_last_trade_event; } int LastAccountEvent(void) const { return this.m_last_account_event; } int LastSymbolsEvent(void) const { return this.m_last_symbol_event; }
В конструкторе класса, в его списке инициализации инициализируем переменную
m_last_account_event значением -1. Ранее мы её инициализировали константой ACCOUNT_EVENT_NO_EVENT удалённого
перечисления ENUM_ACCOUNT_EVENT.
//+------------------------------------------------------------------+ //| CEngine конструктор | //+------------------------------------------------------------------+ CEngine::CEngine() : m_first_start(true), m_last_trade_event(TRADE_EVENT_NO_EVENT), m_last_account_event(WRONG_VALUE), m_last_symbol_event(WRONG_VALUE), m_global_error(ERR_SUCCESS) { this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif; this.m_is_tester=::MQLInfoInteger(MQL_TESTER); this.m_list_counters.Sort(); this.m_list_counters.Clear(); this.CreateCounter(COLLECTION_ORD_COUNTER_ID,COLLECTION_ORD_COUNTER_STEP,COLLECTION_ORD_PAUSE); this.CreateCounter(COLLECTION_ACC_COUNTER_ID,COLLECTION_ACC_COUNTER_STEP,COLLECTION_ACC_PAUSE); this.CreateCounter(COLLECTION_SYM_COUNTER_ID1,COLLECTION_SYM_COUNTER_STEP1,COLLECTION_SYM_PAUSE1); this.CreateCounter(COLLECTION_SYM_COUNTER_ID2,COLLECTION_SYM_COUNTER_STEP2,COLLECTION_SYM_PAUSE2); ::ResetLastError(); #ifdef __MQL5__ if(!::EventSetMillisecondTimer(TIMER_FREQUENCY)) { ::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError()); this.m_global_error=::GetLastError(); } //---__MQL4__ #else if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY)) { ::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError()); this.m_global_error=::GetLastError(); } #endif } //+------------------------------------------------------------------+
Так как мы поменяли название метода Refresh() класса коллекции символов на RefreshAndEventsControl(), и точно такой же метод создали в
классе коллекции аккаунтов, то
заменим в методах работы с событиями символов и аккаунтов
имя вызываемого метода:
//+------------------------------------------------------------------+ //| Работа с событиями коллекции символов | //+------------------------------------------------------------------+ void CEngine::SymbolEventsControl(void) { this.m_symbols.RefreshAndEventsControl(); this.m_is_symbol_event=this.m_symbols.IsEvent(); //--- Если есть изменения свойств символа if(this.m_is_symbol_event) { //--- Получаем последнее событие изменения свойств символа this.m_last_symbol_event=this.m_symbols.GetLastEvent(); } } //+------------------------------------------------------------------+
//+------------------------------------------------------------------+ //| Проверка событий аккаунта | //+------------------------------------------------------------------+ void CEngine::AccountEventsControl(void) { //--- Проверка изменений свойств аккаунта и установка флага событий изменения аккаунта this.m_accounts.RefreshAndEventsControl(); this.m_is_account_event=this.m_accounts.IsEvent(); //--- Если есть изменения свойств аккаунта if(this.m_is_account_event) { //--- Получаем последнее событие изменения свойств аккаунта this.m_last_account_event=this.m_accounts.GetEventID(); } } //+------------------------------------------------------------------+
Это все изменения в классе CEngine.
Теперь у нас есть возможность программно задавать для любого из классов, основанных на базовом объекте CBaseObj, те свойства, которые мы
желаем отслеживать, а также величины изменения свойств, при превышении которых будут генерироваться события наследников базового
класса.
Посмотрим как это всё можно делать.
Тестирование установки параметров отслеживания и получения событий объектов
Для тестирования возьмём тестовый советник из прошлой статьи и
сохраним его
в новой папке и с
новым именем
\MQL5\Experts\TestDoEasy\Part18\TestDoEasyPart18.mq5.
Итак. Нам необходимо протестировать установку параметров, которые мы хотим отследить на предмет их изменения. На заданные нами величины. В двух разных классах. И сделать это теперь возможно одинаковыми спообами.
Будем отслеживать для класса CSymbol
- Увеличение цены Bid всех используемых символов на 10 пунктов
- Уменьшение цены Bid всех используемых символов на 10 пунктов
- Увеличение спреда всех используемых символов на 4 пункта
- Уменьшение спреда всех используемых символов на 4 пункта
- Проконтролируем пересечение значением спреда всех используемых символов уровня в 15 пунктов
- Проконтролируем пересечение ценой Bid текущего символа значения 1.10300
- Увеличение текущей прибыли на 10 единиц валюты счёта
- Увеличение размера средств на 15 единиц валюты счёта
- Проконтролируем увеличение текущей прибыли выше уровня 20 единиц валюты счёта
При увеличении размера средств больше 15 единиц, закроем самую прибыльную позицию при её наличии, и при условии, что её прибыль больше нуля.
Для теста все необходимые значения установим в обработчике OnInit():
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Вызов данной функции выводит в журнал список констант перечисления, //--- заданного в файле DELib.mqh в строках 22 и 25, для проверки корректности констант //EnumNumbersTest(); //--- Установка глобальных переменных советника prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_"; for(int i=0;i<TOTAL_BUTT;i++) { butt_data[i].name=prefix+EnumToString((ENUM_BUTTONS)i); butt_data[i].text=EnumToButtText((ENUM_BUTTONS)i); } lot=NormalizeLot(Symbol(),fmax(InpLots,MinimumLots(Symbol())*2.0)); magic_number=InpMagic; stoploss=InpStopLoss; takeprofit=InpTakeProfit; distance_pending=InpDistance; distance_stoplimit=InpDistanceSL; slippage=InpSlippage; trailing_stop=InpTrailingStop*Point(); trailing_step=InpTrailingStep*Point(); trailing_start=InpTrailingStart; stoploss_to_modify=InpStopLossModify; takeprofit_to_modify=InpTakeProfitModify; //--- Проверка на выбор работы с полным списком used_symbols_mode=InpModeUsedSymbols; if((ENUM_SYMBOLS_MODE)used_symbols_mode==SYMBOLS_MODE_ALL) { int total=SymbolsTotal(false); string ru_n="\nКоличество символов на сервере "+(string)total+".\nМаксимальное количество: "+(string)SYMBOLS_COMMON_TOTAL+" символов."; string en_n="\nThe number of symbols on server "+(string)total+".\nMaximal number: "+(string)SYMBOLS_COMMON_TOTAL+" symbols."; string caption=TextByLanguage("Внимание!","Attention!"); string ru="Выбран режим работы с полным списком.\nВ этом режиме первичная подготовка списка коллекции символов может занять длительное время."+ru_n+"\nПродолжить?\n\"Нет\" - работа с текущим символом \""+Symbol()+"\""; string en="Full list mode selected.\nIn this mode, the initial preparation of the collection symbols list may take a long time."+en_n+"\nContinue?\n\"No\" - working with the current symbol \""+Symbol()+"\""; string message=TextByLanguage(ru,en); int flags=(MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2); int mb_res=MessageBox(message,caption,flags); switch(mb_res) { case IDNO : used_symbols_mode=SYMBOLS_MODE_CURRENT; break; default: break; } } //--- Заполнение массива используемых символов used_symbols=InpUsedSymbols; CreateUsedSymbolsArray((ENUM_SYMBOLS_MODE)used_symbols_mode,used_symbols,array_used_symbols); //--- Установка типа используемого списка символов в коллекции символов engine.SetUsedSymbols(array_used_symbols); //--- Отображение выбранного режима работы с коллекцией объектов-символов Print(engine.ModeSymbolsListDescription(),TextByLanguage(". Количество используемых символов: ",". The number of symbols used: "),engine.GetSymbolsCollectionTotal()); //--- Установка контрольных значений для символов string ru1="",ru2="",ru3="",en1="",en2="",en3=""; //--- Получаем список всех символов коллекции CArrayObj *list=engine.GetListAllUsedSymbols(); if(list!=NULL && list.Total()!=0) { //--- В цикле по списку устанавливаем нужные значения для отслеживаемых свойств символов //--- По умолчанию всем свойствам установлены значения LONG_MAX, что означает "Не отслеживать данное свойство" //--- Включить или выключить (задать величину меньше LONG_MAX или наоборот - установить значение LONG_MAX) можно в любое время в любом месте программы for(int i=0;i<list.Total();i++) { CSymbol* symbol=list.At(i); if(symbol==NULL) continue; //--- Установка контроля увеличения цены символа на 10 пунктов symbol.SetControlBidInc(10*symbol.Point()); ru1="Контролируем увеличение цены Bid для символа "; ru2=" на "; ru3=" пунктов"; en1="Bid price increase control for symbol "; en2=" by "; en3=" points"; Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),DoubleToString(symbol.GetControlledDoubleValueINC(SYMBOL_PROP_BID),symbol.Digits())); //--- Установка контроля уменьшения цены символа на 10 пунктов symbol.SetControlBidDec(10*symbol.Point()); ru1="Контролируем уменьшение цены Bid для символа "; ru2=" на "; ru3=" пунктов"; en1="Bid price decrease control for symbol "; en2=" by "; en3=" points"; Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),DoubleToString(symbol.GetControlledDoubleValueINC(SYMBOL_PROP_BID),symbol.Digits())); //--- Установка контроля увеличения спреда символа на 4 пункта symbol.SetControlSpreadInc(4); ru1="Контролируем увеличение спреда для символа "; ru2=" на "; ru3=" пунктов"; en1="Spread value increase control for symbol "; en2=" by "; en3=" points"; Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),(string)symbol.GetControlledLongValueINC(SYMBOL_PROP_SPREAD),TextByLanguage(ru3,en3)); //--- Установка контроля уменьшения спреда символа на 4 пункта symbol.SetControlSpreadDec(4); ru1="Контролируем уменьшение спреда для символа "; ru2=" на "; ru3=" пунктов"; en1="Spread value decrease control for symbol "; en2=" by "; en3=" points"; Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),(string)symbol.GetControlledLongValueDEC(SYMBOL_PROP_SPREAD),TextByLanguage(ru3,en3)); //--- Установка контроля размера спреда по значению 15 пунктов symbol.SetControlSpreadLevel(15); ru1="Контролируем значение спреда для символа "; ru2=" в "; ru3=" пунктов"; en1="Control the spread value for the symbol "; en2=" at "; en3=" points"; Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),(string)symbol.GetControlledLongValueLEVEL(SYMBOL_PROP_SPREAD),TextByLanguage(ru3,en3)); Print("------"); //--- Установка контроля пересечения ценой значения 1.10700 для текущего символа if(symbol.Name()==Symbol()) { symbol.SetControlBidLevel(1.10300); ru1="Контролируемый уровень цены Bid для символа "; ru2=" установлен в значение "; en1="Controlled level of Bid price for the symbol "; en2=" is set to "; Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),DoubleToString(symbol.GetControlledDoubleValueLEVEL(SYMBOL_PROP_BID),symbol.Digits())); } } } //--- Установка контрольных значений для текущего аккаунта Print("------"); CAccount* account=engine.GetAccountCurrent(); if(account!=NULL) { //--- Установка контроля увеличения значения прибыли account.SetControlledValueINC(ACCOUNT_PROP_PROFIT,10.0); Print(TextByLanguage("Контролируем увеличение прибыли аккаунта на ","Controlling account profit increase by "),DoubleToString(account.GetControlledDoubleValueINC(ACCOUNT_PROP_PROFIT),(int)account.CurrencyDigits())," ",account.Currency()); //--- Установка контроля увеличения значения средств account.SetControlledValueINC(ACCOUNT_PROP_EQUITY,15.0); Print(TextByLanguage("Контролируем увеличение средств аккаунта на ","Controlling account equity increase by "),DoubleToString(account.GetControlledDoubleValueINC(ACCOUNT_PROP_EQUITY),(int)account.CurrencyDigits())," ",account.Currency()); //--- Установка контрольного уровня прибыли account.SetControlledValueLEVEL(ACCOUNT_PROP_PROFIT,20.0); Print(TextByLanguage("Контролируем уровень прибыли аккаунта в ","Controlling the account profit level of "),DoubleToString(account.GetControlledDoubleValueLEVEL(ACCOUNT_PROP_PROFIT),(int)account.CurrencyDigits())," ",account.Currency()); } //--- Проверка и удаление неудалённых графических объектов советника if(IsPresentObects(prefix)) ObjectsDeleteAll(0,prefix); //--- Создание панели кнопок if(!CreateButtons(InpButtShiftX,InpButtShiftY)) return INIT_FAILED; //--- Установка состояния кнопки активизации трейлингов ButtonState(butt_data[TOTAL_BUTT-1].name,trailing_on); //--- Установка параметров торгового класса CTrade #ifdef __MQL5__ trade.SetDeviationInPoints(slippage); trade.SetExpertMagicNumber(magic_number); trade.SetTypeFillingBySymbol(Symbol()); trade.SetMarginMode(); trade.LogLevel(LOG_LEVEL_NO); #endif //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+
В листинге всё прокомментировано, и, надеюсь, понятно для самостоятельного изучения. Замечу лишь, что после установки отслеживаемого
значения свойству, это установленное значение тут же распечатываем в журнал (как пример получения установленного отслеживаемого
значения свойства).
Из обработчика OnTick() удалим переменную для хранения последнего события аккаунта last_account_event —
она была нужна ранее для определения нового события.
Теперь обработчик выглядит так:
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Инициализация последних событий static ENUM_TRADE_EVENT last_trade_event=WRONG_VALUE; //--- Если работа в тестере if(MQLInfoInteger(MQL_TESTER)) { engine.OnTimer(); PressButtonsControl(); } //--- Если последнее торговое событие изменилось if(engine.LastTradeEvent()!=last_trade_event) { last_trade_event=engine.LastTradeEvent(); Comment("\nLast trade event: ",engine.GetLastTradeEventDescription()); engine.ResetLastTradeEvent(); } //--- Если есть событие аккаунта if(engine.IsAccountsEvent()) { //--- Если это тестер if(MQLInfoInteger(MQL_TESTER)) { //--- Получим список всех событий аккаунта, произошедших одновременно CArrayObj* list=engine.GetListAccountEvents(); if(list!=NULL) { //--- В цикле получаем очередное событие int total=list.Total(); for(int i=0;i<total;i++) { //--- берём событие из списка CEventBaseObj *event=list.At(i); if(event==NULL) continue; //--- Отправляем событие в обработчик событий long lparam=event.LParam(); double dparam=event.DParam(); string sparam=event.SParam(); OnDoEasyEvent(CHARTEVENT_CUSTOM+event.ID(),lparam,dparam,sparam); } } } } //--- Если есть событие коллекции символов if(engine.IsSymbolsEvent()) { //--- Если это тестер if(MQLInfoInteger(MQL_TESTER)) { //--- Получим список всех событий символов, произошедших одновременно CArrayObj* list=engine.GetListSymbolsEvents(); if(list!=NULL) { //--- В цикле получаем очередное событие int total=list.Total(); for(int i=0;i<total;i++) { //--- берём событие из списка CEventBaseObj *event=list.At(i); if(event==NULL) continue; //--- Отправляем событие в обработчик событий long lparam=event.LParam(); double dparam=event.DParam(); string sparam=event.SParam(); OnDoEasyEvent(CHARTEVENT_CUSTOM+event.ID(),lparam,dparam,sparam); } } } } //--- Если установлен флаг трейлинга if(trailing_on) { TrailingPositions(); TrailingOrders(); } } //+------------------------------------------------------------------+
Теперь все флаги о новых событиях можно получить из главного объекта библиотеки CEngine, и что более важно — можно
получить даже два одинаковых события с разных символов (касается определения событий символов, а аккаунт всегда один — текущий). А вот при
использовании переменных это было невозможно — так как текущее и прошлое события якобы одинаковы, а, значит, нет события. Это было не
правильно.
В обработчик событий библиотеки были внесены доработки для определения событий аккаунта и реакции на увеличение размера средств на заданную величину:
//+------------------------------------------------------------------+ //| Обработка событий библиотеки DoEasy | //+------------------------------------------------------------------+ void OnDoEasyEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { int idx=id-CHARTEVENT_CUSTOM; string event="::"+string(idx); //--- Извлекаем из lparam (1) милисекунды времени события, (2) причину, (3) источник события и (4) устанавливаем точное время события ushort msc=engine.EventMSC(lparam); ushort reason=engine.EventReason(lparam); ushort source=engine.EventSource(lparam); long time=TimeCurrent()*1000+msc; //--- Обработка событий символов if(source==COLLECTION_SYMBOLS_ID) { CSymbol *symbol=engine.GetSymbolObjByName(sparam); if(symbol==NULL) return; //--- Количество знаков после запятой в значении события - если long-событие, то 0, иначе - Digits() символа int digits=(idx<SYMBOL_PROP_INTEGER_TOTAL ? 0 : symbol.Digits()); //--- Текстовое описание события string id_descr=(idx<SYMBOL_PROP_INTEGER_TOTAL ? symbol.GetPropertyDescription((ENUM_SYMBOL_PROP_INTEGER)idx) : symbol.GetPropertyDescription((ENUM_SYMBOL_PROP_DOUBLE)idx)); //--- Текстовое значение величины изменения свойства string value=DoubleToString(dparam,digits); //--- Проверка причин события и просто вывод в журнал его описания if(reason==BASE_EVENT_REASON_INC) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_DEC) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_MORE_THEN) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_LESS_THEN) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_EQUALS) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } } //--- Обработка событий аккаунта else if(source==COLLECTION_ACCOUNT_ID) { CAccount *account=engine.GetAccountCurrent(); if(account==NULL) return; //--- Количество знаков после запятой в значении события - если long-событие, то 0, иначе - Digits() символа int digits=int(idx<ACCOUNT_PROP_INTEGER_TOTAL ? 0 : account.CurrencyDigits()); //--- Текстовое описание события string id_descr=(idx<ACCOUNT_PROP_INTEGER_TOTAL ? account.GetPropertyDescription((ENUM_ACCOUNT_PROP_INTEGER)idx) : account.GetPropertyDescription((ENUM_ACCOUNT_PROP_DOUBLE)idx)); //--- Текстовое значение величины изменения свойства string value=DoubleToString(dparam,digits); //--- Проверка причин события и обработка увеличения средств на заданную величину, //--- для остальных событий - просто вывод в журнал его описания //--- Если это увеличение значения свойства if(reason==BASE_EVENT_REASON_INC) { //--- Распечатаем событие в журнал Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); //--- если это увеличение средств if(idx==ACCOUNT_PROP_EQUITY) { //--- Получаем список всех открытых позиций CArrayObj* list_positions=engine.GetListMarketPosition(); //--- Выбираем позиции с прибылью болше нуля list_positions=CSelect::ByOrderProperty(list_positions,ORDER_PROP_PROFIT_FULL,0,MORE); if(list_positions!=NULL) { //--- Сортируем список по прибыли с учётом комиссии и свопа list_positions.Sort(SORT_BY_ORDER_PROFIT_FULL); //--- Получаем индекс позиции с наибольшей прибылью int index=CSelect::FindOrderMax(list_positions,ORDER_PROP_PROFIT_FULL); if(index>WRONG_VALUE) { COrder* position=list_positions.At(index); if(position!=NULL) { //--- Получаем тикет позиции с наибольшей прибылью и закрываем позицию по тикету #ifdef __MQL5__ trade.PositionClose(position.Ticket()); #else PositionClose(position.Ticket(),position.Volume()); #endif } } } } } //--- Остальные события просто выводим в журнал if(reason==BASE_EVENT_REASON_DEC) { Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_MORE_THEN) { Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_LESS_THEN) { Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_EQUALS) { Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } } //--- Обработка торговых событий else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE) { event=EnumToString((ENUM_TRADE_EVENT)ushort(idx)); int digits=(int)SymbolInfoInteger(sparam,SYMBOL_DIGITS); } //--- Обработка событий окна обзор рынка else if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE) { string name=""; //--- Событие окна "Обзор рынка" string descr=engine.GetMWEventDescription((ENUM_MW_EVENT)idx); name=(idx==MARKET_WATCH_EVENT_SYMBOL_SORT ? "" : ": "+sparam); Print(TimeMSCtoString(lparam)," ",descr,name); } } //+------------------------------------------------------------------+
Все действия по определению событий прокомментированы в коде, и, надеюсь, понятны. Также были поменяны местами блоки обработки событий от разных классов (непринципиально — просто для порядка) и разделены условиями if - else, что важно по причине того, что у нас есть несколько типов событий: события символов и аккаунта, которые обрабатываются одинаково — по идентификаторам коллекций, и есть торговые события и события окна "Обзор рынка", которые обрабатываются по значению перечислений этих событий. Вот чтобы не было конфликтов между разными методиками определения событий, и были разделены блоки условными операторами.
Полный листинг советника можно взять из прикреплённых ниже файлов.
Скомпилируем советник, установим в настройках тестера нулевые значения для параметров StopLoss in points и TakeProfit in points, выберем для параметра Mode of used symbols list значение "Работа только с текущим символом" и запустим визуальный тест советника M15 Last month:
Перед запуском теста видим, что в журнал распечатаны установленные значения для отслеживаемых свойств символа и аккаунта. Во время визуального тестирования в журнал выводятся сообщения о полученных событий от тех свойств, изменения значений которых мы отслеживаем. При увеличении средств больше контролируемой величины, прибыльные позиции закрываются.
Итак: мы создали базовый объект для всех объектов библиотеки, который наделяет своих наследников событийным функционалом и методами
установки и получения параметров отслеживания для любых свойств любых объектов в любое время.
В дальнейшем это сильно упростит разработку новых классов новых объектов.
Что дальше
В следующей статье сделаем класс сообщений библиотеки — внутренних (сообщений от библиотечных методов) и внешних (сообщения об ошибках
и прочие сообщения от терминала).
Ниже прикреплены все файлы текущей версии библиотеки и файлы тестового советника. Их можно скачать и протестировать всё
самостоятельно.
При возникновении вопросов, замечаний и пожеланий, вы можете озвучить их в комментариях к статье.
Статьи этой серии:
Часть 1. Концепция, организация данных
Часть
2. Коллекция исторических ордеров и сделок
Часть 3. Коллекция рыночных ордеров и
позиций, организация поиска
Часть 4. Торговые события. Концепция
Часть 5. Классы и коллекция торговых событий. Отправка событий в программу
Часть 6. События на счёте с типом неттинг
Часть
7. События срабатывания StopLimit-ордеров, подготовка функционала для регистрации событий модификации ордеров и позиций
Часть
8. События модификации ордеров и позиций
Часть 9. Совместимость с MQL4 -
Подготовка данных
Часть 10. Совместимость с MQL4 - События открытия позиций и
активации отложенных ордеров
Часть 11. Совместимость с MQL4 - События закрытия
позиций
Часть 12. Класс объекта "аккаунт", коллекция объектов-аккаунтов
Часть 13. События объекта "аккаунт"
Часть
14. Объект "Символ"
Часть 15. Коллекция объектов-символов
Часть
16. События коллекции символов
Часть 17. Интерактивность объектов библиотеки
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования