English 中文 Español Deutsch 日本語 Português
Графика в библиотеке DoEasy (Часть 96): Работа с событиями мышки и графика в объектах-формах

Графика в библиотеке DoEasy (Часть 96): Работа с событиями мышки и графика в объектах-формах

MetaTrader 5Примеры | 11 февраля 2022, 16:54
1 657 4
Artyom Trishkin
Artyom Trishkin

Содержание


Концепция

В прошлой статье мы, для управления составными графическими объектами, добавили в их состав элементы управления точками привязки базового графического объекта. По задумке, перемещение таких элементов управления повлечёт за собой перемещение точки привязки базового графического объекта, тем самым изменяя его ориентацию в пространстве графика. Для управления мышкой этими контрольными точками нам необходимо создать для объектов на канвасе (графический элемент, объект-форма) обработчики событий мышки. При этом при наведении курсора мыши на объект-форму, он должен знать об этом и изменять свои свойства. Дополнительно должно учитываться удерживает ли пользователь при этом кнопку мышки в нажатом состоянии. Если зажать кнопку мышки в пределах объекта-формы и начать её двигать, то прокрутка графика мышью должна быть отключена (плюс инструмент перекрестие и контекстное меню графика), а сама форма должна перемещаться за курсором.

При этом остальные объекты-формы не должны реагировать на перемещение мышки с зажатой кнопкой при пересечении их места расположения. С другой стороны, если зажать кнопку мышки за пределами любой формы и начать двигать курсор, то это должно повлечь за собой смещение графика (если оно разрешено в настройках), а объекты-формы никак не должны реагировать на пересечение их места расположения курсором с зажатой кнопкой — чтобы график продолжал смещаться, а не формы начинали при этом перемещаться за курсором.
На протяжении последующих статей мы постепенно создадим такой функционал для объектов-форм, а уже после этого продолжим развитие составных графических объектов.

Помимо этого, сегодня доработаем класс объекта-символа, так как с момента его написания у символов графика появились новые свойства, которые желательно учитывать и отслеживать их изменение. Новых свойств появилось не так много, но состав некоторых свойств является достаточно внушительным по количеству констант перечислений, описывающих эти свойства (ENUM_SYMBOL_SECTOR, ENUM_SYMBOL_INDUSTRY), поэтому новых индексов сообщений для класса сообщений библиотеки будет много, а также будут достаточно объёмными методы, возвращающие описания этих свойств.


Доработка классов библиотеки

В файле \MQL5\Include\DoEasy\Data.mqh впишем индексы новых сообщений:

//--- CSymbol
   MSG_SYM_PROP_INDEX,                                // Индекс в окне \"Обзор рынка\"
   MSG_SYM_PROP_SECTOR,                               // Сектор экономики
   MSG_SYM_PROP_INDUSTRY,                             // Вид промышленности или отрасль экономики
   MSG_SYM_PROP_CUSTOM,                               // Пользовательский символ
   MSG_SYM_PROP_CHART_MODE,                           // Тип цены для построения баров
   MSG_SYM_PROP_EXIST,                                // Символ с таким именем существует
   MSG_SYM_PROP_SELECT,                               // Символ выбран в Market Watch
   MSG_SYM_PROP_VISIBLE,                              // Символ отображается в Market Watch
   MSG_SYM_PROP_SESSION_DEALS,                        // Количество сделок в текущей сессии
   MSG_SYM_PROP_SESSION_BUY_ORDERS,                   // Общее число ордеров на покупку в текущий момент
   MSG_SYM_PROP_SESSION_SELL_ORDERS,                  // Общее число ордеров на продажу в текущий момент
   MSG_SYM_PROP_VOLUME,                               // Объем в последней сделке
   MSG_SYM_PROP_VOLUMEHIGH,                           // Максимальный объём за день
   MSG_SYM_PROP_VOLUMELOW,                            // Минимальный объём за день
   MSG_SYM_PROP_TIME,                                 // Время последней котировки
   MSG_SYM_PROP_TIME_MSC,                             // Время последней котировки в миллисекундах
   MSG_SYM_PROP_DIGITS,                               // Количество знаков после запятой
   MSG_SYM_PROP_DIGITS_LOTS,                          // Количество знаков после запятой в значении лота

...

   MSG_SYM_PROP_SESSION_PRICE_LIMIT_MAX,              // Максимально допустимое значение цены на сессию
   MSG_SYM_PROP_MARGIN_HEDGED,                        // Размер контракта или маржи для одного лота перекрытых позиций
   
   MSG_SYM_PROP_PRICE_CHANGE,                         // Изменение текущей цены относительно конца предыдущего торгового дня, в процентах
   MSG_SYM_PROP_PRICE_VOLATILITY,                     // Волатильность цены в процентах
   MSG_SYM_PROP_PRICE_THEORETICAL,                    // Теоретическая цена опциона
   MSG_SYM_PROP_PRICE_DELTA,                          // Дельта опциона/варранта
   MSG_SYM_PROP_PRICE_THETA,                          // Тета опциона/варранта
   MSG_SYM_PROP_PRICE_GAMMA,                          // Гамма опциона/варранта
   MSG_SYM_PROP_PRICE_VEGA,                           // Вега опциона/варранта
   MSG_SYM_PROP_PRICE_RHO,                            // Ро опциона/варранта
   MSG_SYM_PROP_PRICE_OMEGA,                          // Омега опциона/варранта
   MSG_SYM_PROP_PRICE_SENSITIVITY,                    // Чувствительность опциона/варранта
   //---
   MSG_SYM_PROP_NAME,                                 // Имя символа
   MSG_SYM_PROP_BASIS,                                // Имя базового актива для производного инструмента
   MSG_SYM_PROP_COUNTRY,                              // Страна
   MSG_SYM_PROP_SECTOR_NAME,                          // Сектор экономики
   MSG_SYM_PROP_INDUSTRY_NAME,                        // Отрасль экономики или вид промышленности
   MSG_SYM_PROP_CURRENCY_BASE,                        // Базовая валюта инструмента
   MSG_SYM_PROP_CURRENCY_PROFIT,                      // Валюта прибыли
   MSG_SYM_PROP_CURRENCY_MARGIN,                      // Валюта залоговых средств
   MSG_SYM_PROP_BANK,                                 // Источник текущей котировки
   MSG_SYM_PROP_DESCRIPTION,                          // Описание символа
   MSG_SYM_PROP_FORMULA,                              // Формула для построения цены пользовательского символа
   MSG_SYM_PROP_ISIN,                                 // Имя торгового символа в системе международных идентификационных кодов
   MSG_SYM_PROP_PAGE,                                 // Адрес интернет страницы с информацией по символу
   MSG_SYM_PROP_PATH,                                 // Путь в дереве символов
   MSG_SYM_PROP_CAYEGORY,                             // Категория символа
   MSG_SYM_PROP_EXCHANGE,                             // Название биржи или площадки, на которой торгуется символ
   //---

...

   //---
   MSG_SYM_EVENT_SYMBOL_ADD,                          // В окно "Обзор рынка" добавлен символ
   MSG_SYM_EVENT_SYMBOL_DEL,                          // Из окна "Обзор рынка" удалён символ
   MSG_SYM_EVENT_SYMBOL_SORT,                         // Изменено расположение символов в окне "Обзор рынка"
   MSG_SYM_SYMBOLS_MODE_CURRENT,                      // Работа только с текущим символом
   MSG_SYM_SYMBOLS_MODE_DEFINES,                      // Работа с предопределённым списком символов
   MSG_SYM_SYMBOLS_MODE_MARKET_WATCH,                 // Работа с символами из окна "Обзор рынка"
   MSG_SYM_SYMBOLS_MODE_ALL,                          // Работа с полным списком всех доступных символов
   MSG_SYM_SYMBOLS_BOOK_ADD,                          // Осуществлена подписка на стакан цен 
   MSG_SYM_SYMBOLS_BOOK_DEL,                          // Осуществлена отписка от стакан цен 
   MSG_SYM_SYMBOLS_MODE_BOOK,                         // Подписка на стакан цен
   MSG_SYM_SYMBOLS_ERR_BOOK_ADD,                      // Ошибка при подписке на стакан цен 
   MSG_SYM_SYMBOLS_ERR_BOOK_DEL,                      // Ошибка при отписке от стакан цен 
   
   //--- ENUM_SYMBOL_SECTOR
   MSG_SYM_SECTOR_UNDEFINED,                          // Не определен
   MSG_SYM_SECTOR_BASIC_MATERIALS,                    // Сырье
   MSG_SYM_SECTOR_COMMUNICATION_SERVICES,             // Услуги связи
   MSG_SYM_SECTOR_CONSUMER_CYCLICAL,                  // Потребление циклического спроса
   MSG_SYM_SECTOR_CONSUMER_DEFENSIVE,                 // Основное потребление
   MSG_SYM_SECTOR_CURRENCY,                           // Валюты
   MSG_SYM_SECTOR_CURRENCY_CRYPTO,                    // Криптовалюты
   MSG_SYM_SECTOR_ENERGY,                             // Энергетика
   MSG_SYM_SECTOR_FINANCIAL,                          // Финансы
   MSG_SYM_SECTOR_HEALTHCARE,                         // Здравоохранение
   MSG_SYM_SECTOR_INDUSTRIALS,                        // Промышленность
   MSG_SYM_SECTOR_REAL_ESTATE,                        // Недвижимость
   MSG_SYM_SECTOR_TECHNOLOGY,                         // Технологии
   MSG_SYM_SECTOR_UTILITIES,                          // Коммунальные услуги
   MSG_SYM_SECTOR_INDEXES,                            // Индексы
   MSG_SYM_SECTOR_COMMODITIES,                        // Биржевые товары
   
   //--- ENUM_SYMBOL_INDUSTRY
   MSG_SYM_INDUSTRY_UNDEFINED,                        // Не определено
   //--- Сырье
   MSG_SYM_INDUSTRY_AGRICULTURAL_INPUTS,              // Сельскохозяйственные ресурсы
   MSG_SYM_INDUSTRY_ALUMINIUM,                        // Алюминий
   MSG_SYM_INDUSTRY_BUILDING_MATERIALS,               // Строительные материалы
   MSG_SYM_INDUSTRY_CHEMICALS,                        // Химикаты
   MSG_SYM_INDUSTRY_COKING_COAL,                      // Коксующийся уголь
   MSG_SYM_INDUSTRY_COPPER,                           // Медь
   MSG_SYM_INDUSTRY_GOLD,                             // Золото
   MSG_SYM_INDUSTRY_LUMBER_WOOD,                      // Производство пиломатериалов и древесины
   MSG_SYM_INDUSTRY_INDUSTRIAL_METALS,                // Прочие промышленные металлы и добыча
   MSG_SYM_INDUSTRY_PRECIOUS_METALS,                  // Прочие драгоценные металлы и добыча
   MSG_SYM_INDUSTRY_PAPER,                            // Целлюлозно-бумажные изделия
   MSG_SYM_INDUSTRY_SILVER,                           // Серебро
   MSG_SYM_INDUSTRY_SPECIALTY_CHEMICALS,              // Специальные химикаты
   MSG_SYM_INDUSTRY_STEEL,                            // Сталь
   //--- Услуги связи
   MSG_SYM_INDUSTRY_ADVERTISING,                      // Рекламные агентства
   MSG_SYM_INDUSTRY_BROADCASTING,                     // Вещание
   MSG_SYM_INDUSTRY_GAMING_MULTIMEDIA,                // Электронные игры и мультимедиа
   MSG_SYM_INDUSTRY_ENTERTAINMENT,                    // Развлечения
   MSG_SYM_INDUSTRY_INTERNET_CONTENT,                 // Интернет-контент и информация
   MSG_SYM_INDUSTRY_PUBLISHING,                       // Издательство
   MSG_SYM_INDUSTRY_TELECOM,                          // Телекоммуникационные услуги
   //--- Потребление циклического спроса
   MSG_SYM_INDUSTRY_APPAREL_MANUFACTURING,            // Производство одежды
   MSG_SYM_INDUSTRY_APPAREL_RETAIL,                   // Розничная продажа одежды
   MSG_SYM_INDUSTRY_AUTO_MANUFACTURERS,               // Автомобилестроение
   MSG_SYM_INDUSTRY_AUTO_PARTS,                       // Автозапчасти
   MSG_SYM_INDUSTRY_AUTO_DEALERSHIP,                  // Дилеры легковых и грузовых автомобилей
   MSG_SYM_INDUSTRY_DEPARTMENT_STORES,                // Универсальные магазины
   MSG_SYM_INDUSTRY_FOOTWEAR_ACCESSORIES,             // Обувь и аксессуары
   MSG_SYM_INDUSTRY_FURNISHINGS,                      // Мебель, фурнитура и бытовая техника
   MSG_SYM_INDUSTRY_GAMBLING,                         // Игорные предприятия
   MSG_SYM_INDUSTRY_HOME_IMPROV_RETAIL,               // Розничная торговля товарами для дома
   MSG_SYM_INDUSTRY_INTERNET_RETAIL,                  // Розничная онлайн-торговля
   MSG_SYM_INDUSTRY_LEISURE,                          // Досуг
   MSG_SYM_INDUSTRY_LODGING,                          // Жилье
   MSG_SYM_INDUSTRY_LUXURY_GOODS,                     // Товары класса "люкс"
   MSG_SYM_INDUSTRY_PACKAGING_CONTAINERS,             // Упаковка
   MSG_SYM_INDUSTRY_PERSONAL_SERVICES,                // Персональные услуги
   MSG_SYM_INDUSTRY_RECREATIONAL_VEHICLES,            // Транспортные средства для отдыха
   MSG_SYM_INDUSTRY_RESIDENT_CONSTRUCTION,            // Жилищное строительство
   MSG_SYM_INDUSTRY_RESORTS_CASINOS,                  // Курорты и казино
   MSG_SYM_INDUSTRY_RESTAURANTS,                      // Рестораны
   MSG_SYM_INDUSTRY_SPECIALTY_RETAIL,                 // Специализированная розничная торговля
   MSG_SYM_INDUSTRY_TEXTILE_MANUFACTURING,            // Текстильное производство
   MSG_SYM_INDUSTRY_TRAVEL_SERVICES,                  // Туристические услуги
   //--- Основное потребление
   MSG_SYM_INDUSTRY_BEVERAGES_BREWERS,                // Напитки - Пивовары
   MSG_SYM_INDUSTRY_BEVERAGES_NON_ALCO,               // Напитки - Безалкогольные
   MSG_SYM_INDUSTRY_BEVERAGES_WINERIES,               // Напитки - Винзаводы и ликеро-водочные заводы
   MSG_SYM_INDUSTRY_CONFECTIONERS,                    // Кондитеры
   MSG_SYM_INDUSTRY_DISCOUNT_STORES,                  // Дисконтные магазины
   MSG_SYM_INDUSTRY_EDUCATION_TRAINIG,                // Образование и обучение
   MSG_SYM_INDUSTRY_FARM_PRODUCTS,                    // Сельскохозяйственные продукты
   MSG_SYM_INDUSTRY_FOOD_DISTRIBUTION,                // Дистрибуция продуктов питания
   MSG_SYM_INDUSTRY_GROCERY_STORES,                   // Продуктовые магазины
   MSG_SYM_INDUSTRY_HOUSEHOLD_PRODUCTS,               // Товары для дома и быта
   MSG_SYM_INDUSTRY_PACKAGED_FOODS,                   // Упакованные продукты
   MSG_SYM_INDUSTRY_TOBACCO,                          // Табак
   //--- Энергетика
   MSG_SYM_INDUSTRY_OIL_GAS_DRILLING,                 // Бурение нефтяных и газовых скважин
   MSG_SYM_INDUSTRY_OIL_GAS_EP,                       // Добыча и переработка нефти и газа
   MSG_SYM_INDUSTRY_OIL_GAS_EQUIPMENT,                // Нефтегазовое оборудование и услуги
   MSG_SYM_INDUSTRY_OIL_GAS_INTEGRATED,               // Интегрированные нефтегазовые компании
   MSG_SYM_INDUSTRY_OIL_GAS_MIDSTREAM,                // Транспортировка нефти и газа
   MSG_SYM_INDUSTRY_OIL_GAS_REFINING,                 // Переработка и сбыт нефти и газа
   MSG_SYM_INDUSTRY_THERMAL_COAL,                     // Энергетический уголь
   MSG_SYM_INDUSTRY_URANIUM,                          // Уран
   //--- Финансы
   MSG_SYM_INDUSTRY_EXCHANGE_TRADED_FUND,             // Биржевой фонд
   MSG_SYM_INDUSTRY_ASSETS_MANAGEMENT,                // Управление активами
   MSG_SYM_INDUSTRY_BANKS_DIVERSIFIED,                // Банки - Диверсифицированные
   MSG_SYM_INDUSTRY_BANKS_REGIONAL,                   // Банки - Региональные
   MSG_SYM_INDUSTRY_CAPITAL_MARKETS,                  // Финансовые рынки
   MSG_SYM_INDUSTRY_CLOSE_END_FUND_DEBT,              // Закрытый фонд - Долговые инструменты
   MSG_SYM_INDUSTRY_CLOSE_END_FUND_EQUITY,            // Закрытый фонд - Акции
   MSG_SYM_INDUSTRY_CLOSE_END_FUND_FOREIGN,           // Закрытый фонд - Иностранные
   MSG_SYM_INDUSTRY_CREDIT_SERVICES,                  // Кредитные услуги
   MSG_SYM_INDUSTRY_FINANCIAL_CONGLOMERATE,           // Финансовые конгломераты
   MSG_SYM_INDUSTRY_FINANCIAL_DATA_EXCHANGE,          // Финансовые данные и биржи
   MSG_SYM_INDUSTRY_INSURANCE_BROKERS,                // Страховые брокеры
   MSG_SYM_INDUSTRY_INSURANCE_DIVERSIFIED,            // Страхование - Диверсифицированные
   MSG_SYM_INDUSTRY_INSURANCE_LIFE,                   // Страхование - Жизнь
   MSG_SYM_INDUSTRY_INSURANCE_PROPERTY,               // Страхование - Недвижимость и несчастные случаи
   MSG_SYM_INDUSTRY_INSURANCE_REINSURANCE,            // Страхование - Перестрахование
   MSG_SYM_INDUSTRY_INSURANCE_SPECIALTY,              // Страхование - Специальное
   MSG_SYM_INDUSTRY_MORTGAGE_FINANCE,                 // Ипотечное финансирование
   MSG_SYM_INDUSTRY_SHELL_COMPANIES,                  // Шелл-компании
   //--- Здравоохранение
   MSG_SYM_INDUSTRY_BIOTECHNOLOGY,                    // Биотехнологии
   MSG_SYM_INDUSTRY_DIAGNOSTICS_RESEARCH,             // Диагностика и исследования
   MSG_SYM_INDUSTRY_DRUGS_MANUFACTURERS,              // Фармацевтическое производство - Общее
   MSG_SYM_INDUSTRY_DRUGS_MANUFACTURERS_SPEC,         // Фармацевтическое производство - Специальное и дженерики
   MSG_SYM_INDUSTRY_HEALTHCARE_PLANS,                 // Планы здравоохранения
   MSG_SYM_INDUSTRY_HEALTH_INFORMATION,               // Информационные службы здравоохранения
   MSG_SYM_INDUSTRY_MEDICAL_FACILITIES,               // Медицинские учреждения
   MSG_SYM_INDUSTRY_MEDICAL_DEVICES,                  // Медицинское оборудование
   MSG_SYM_INDUSTRY_MEDICAL_DISTRIBUTION,             // Медицинские дистрибьюторы
   MSG_SYM_INDUSTRY_MEDICAL_INSTRUMENTS,              // Медицинские инструменты и расходные материалы
   MSG_SYM_INDUSTRY_PHARM_RETAILERS,                  // Фармацевтические ритейлеры
   //--- Промышленность
   MSG_SYM_INDUSTRY_AEROSPACE_DEFENSE,                // Аэрокосмическая и оборонная промышленность
   MSG_SYM_INDUSTRY_AIRLINES,                         // Авиакомпании
   MSG_SYM_INDUSTRY_AIRPORTS_SERVICES,                // Аэропорты и воздушные перевозки
   MSG_SYM_INDUSTRY_BUILDING_PRODUCTS,                // Строительные материалы и оборудование
   MSG_SYM_INDUSTRY_BUSINESS_EQUIPMENT,               // Деловое оборудование и материалы
   MSG_SYM_INDUSTRY_CONGLOMERATES,                    // Конгломераты
   MSG_SYM_INDUSTRY_CONSULTING_SERVICES,              // Консалтинговые услуги
   MSG_SYM_INDUSTRY_ELECTRICAL_EQUIPMENT,             // Электрооборудование и запчасти
   MSG_SYM_INDUSTRY_ENGINEERING_CONSTRUCTION,         // Инженерное дело и строительство
   MSG_SYM_INDUSTRY_FARM_HEAVY_MACHINERY,             // Сельскохозяйственное и тяжелое строительное оборудование
   MSG_SYM_INDUSTRY_INDUSTRIAL_DISTRIBUTION,          // Промышленные дистрибьюторы
   MSG_SYM_INDUSTRY_INFRASTRUCTURE_OPERATIONS,        // Инфраструктурные операции
   MSG_SYM_INDUSTRY_FREIGHT_LOGISTICS,                // Интегрированные перевозки и логистика
   MSG_SYM_INDUSTRY_MARINE_SHIPPING,                  // Морские перевозки
   MSG_SYM_INDUSTRY_METAL_FABRICATION,                // Металлопроизводство
   MSG_SYM_INDUSTRY_POLLUTION_CONTROL,                // Контроль загрязнения и очистка
   MSG_SYM_INDUSTRY_RAILROADS,                        // Железные дороги
   MSG_SYM_INDUSTRY_RENTAL_LEASING,                   // Аренда и лизинг
   MSG_SYM_INDUSTRY_SECURITY_PROTECTION,              // Безопасность и защита
   MSG_SYM_INDUSTRY_SPEALITY_BUSINESS_SERVICES,       // Специализированные бизнес-услуги
   MSG_SYM_INDUSTRY_SPEALITY_MACHINERY,               // Специализированные промышленные машины
   MSG_SYM_INDUSTRY_STUFFING_EMPLOYMENT,              // Услуги по трудоустройству
   MSG_SYM_INDUSTRY_TOOLS_ACCESSORIES,                // Инструменты и инвентарь
   MSG_SYM_INDUSTRY_TRUCKING,                         // Грузоперевозки
   MSG_SYM_INDUSTRY_WASTE_MANAGEMENT,                 // Управление отходами
   //--- Недвижимость
   MSG_SYM_INDUSTRY_REAL_ESTATE_DEVELOPMENT,          // Недвижимость - Строительство
   MSG_SYM_INDUSTRY_REAL_ESTATE_DIVERSIFIED,          // Недвижимость - Диверсифицированные
   MSG_SYM_INDUSTRY_REAL_ESTATE_SERVICES,             // Услуги в сфере недвижимости
   MSG_SYM_INDUSTRY_REIT_DIVERSIFIED,                 // Инвестиционный фонд недвижимости - Диверсифицированные
   MSG_SYM_INDUSTRY_REIT_HEALTCARE,                   // Инвестиционный фонд недвижимости - Медицинские учреждения
   MSG_SYM_INDUSTRY_REIT_HOTEL_MOTEL,                 // Инвестиционный фонд недвижимости - Отели
   MSG_SYM_INDUSTRY_REIT_INDUSTRIAL,                  // Инвестиционный фонд недвижимости - Промышленность
   MSG_SYM_INDUSTRY_REIT_MORTAGE,                     // Инвестиционный фонд недвижимости - Ипотека
   MSG_SYM_INDUSTRY_REIT_OFFICE,                      // Инвестиционный фонд недвижимости - Офисы
   MSG_SYM_INDUSTRY_REIT_RESIDENTAL,                  // Инвестиционный фонд недвижимости - Жилые помещения
   MSG_SYM_INDUSTRY_REIT_RETAIL,                      // Инвестиционный фонд недвижимости - Розница
   MSG_SYM_INDUSTRY_REIT_SPECIALITY,                  // Инвестиционный фонд недвижимости - Специальные помещения
   //--- Технологии
   MSG_SYM_INDUSTRY_COMMUNICATION_EQUIPMENT,          // Коммуникационное оборудование
   MSG_SYM_INDUSTRY_COMPUTER_HARDWARE,                // Компьютерное оборудование
   MSG_SYM_INDUSTRY_CONSUMER_ELECTRONICS,             // Бытовая электроника
   MSG_SYM_INDUSTRY_ELECTRONIC_COMPONENTS,            // Электронные компоненты
   MSG_SYM_INDUSTRY_ELECTRONIC_DISTRIBUTION,          // Дистрибуция электроники и компьютеров
   MSG_SYM_INDUSTRY_IT_SERVICES,                      // Услуги информационных технологий
   MSG_SYM_INDUSTRY_SCIENTIFIC_INSTRUMENTS,           // Научно-технические инструменты
   MSG_SYM_INDUSTRY_SEMICONDUCTOR_EQUIPMENT,          // Полупроводниковое оборудование и материалы
   MSG_SYM_INDUSTRY_SEMICONDUCTORS,                   // Полупроводники
   MSG_SYM_INDUSTRY_SOFTWARE_APPLICATION,             // Программное обеспечение - Приложения
   MSG_SYM_INDUSTRY_SOFTWARE_INFRASTRUCTURE,          // Программное обеспечение - Инфраструктура
   MSG_SYM_INDUSTRY_SOLAR,                            // Солнечная энергетика
   //--- Коммунальные услуги
   MSG_SYM_INDUSTRY_UTILITIES_DIVERSIFIED,            // Коммунальные предприятия - Диверсифицированные
   MSG_SYM_INDUSTRY_UTILITIES_POWERPRODUCERS,         // Коммунальные предприятия - Независимые производители энергии
   MSG_SYM_INDUSTRY_UTILITIES_RENEWABLE,              // Коммунальные предприятия - Возобновляемая энергия
   MSG_SYM_INDUSTRY_UTILITIES_REGULATED_ELECTRIC,     // Коммунальные предприятия - Регулируемые электрические компании
   MSG_SYM_INDUSTRY_UTILITIES_REGULATED_GAS,          // Коммунальные предприятия - Регулируемые газовые компании
   MSG_SYM_INDUSTRY_UTILITIES_REGULATED_WATER,        // Коммунальные предприятия - Регулируемые водоканалы  

//--- CAccount

и текстовые сообщения, соответствующие вновь добавленным индексам:

//--- CSymbol
   {"Индекс в окне \"Обзор рынка\"","Index in the \"Market Watch window\""},
   
   {"Сектор экономики","The sector of the economy"},
   {"Вид промышленности или отрасль экономики","The industry or the economy branch"},
   
   {"Пользовательский символ","Custom symbol"},
   {"Тип цены для построения баров","Price type used for generating symbols bars"},
   {"Символ с таким именем существует","Symbol with this name exists"},
   {"Символ выбран в Market Watch","Symbol is selected in Market Watch"},
   {"Символ отображается в Market Watch","Symbol is visible in Market Watch"},
   {"Количество сделок в текущей сессии","Number of deals in the current session"},
   {"Общее число ордеров на покупку в текущий момент","Number of Buy orders at the moment"},
   {"Общее число ордеров на продажу в текущий момент","Number of Sell orders at the moment"},
   {"Объем в последней сделке","Volume of the last deal"},
   {"Максимальный объём за день","Maximal day volume"},
   {"Минимальный объём за день","Minimal day volume"},
   {"Время последней котировки","Time of the last quote"},
   {"Время последней котировки в миллисекундах","Time of the last quote in milliseconds"},
   {"Количество знаков после запятой","Digits after a decimal point"},
   {"Количество знаков после запятой в значении лота","Digits after a decimal point in the value of the lot"},

...

   {"Максимально допустимое значение цены на сессию","Maximal price of the current session"},
   {"Размер контракта или маржи для одного лота перекрытых позиций","Contract size or margin value per one lot of hedged positions"},
   
   {"Изменение текущей цены относительно конца предыдущего торгового дня, в процентах","Change of the current price relative to the end of the previous trading day in %"},
   {"Волатильность цены в процентах","Price volatility in %"},
   {"Теоретическая цена опциона","Theoretical option price"},
   {"Дельта опциона/варранта","Option/warrant delta"},
   {"Тета опциона/варранта","Option/warrant theta"},
   {"Гамма опциона/варранта","Option/warrant gamma"},
   {"Вега опциона/варранта","Option/warrant vega"},
   {"Ро опциона/варранта","Option/warrant rho"},
   {"Омега опциона/варранта","Option/warrant omega"},
   {"Чувствительность опциона/варранта","Option/warrant sensitivity"},

   {"Имя символа","Symbol name"},
   {"Имя базового актива для производного инструмента","The underlying asset of a derivative"},
   {"Страна","Cuntry"},
   {"Сектор экономики","Sector of the economy"},
   {"Отрасль экономики или вид промышленности","Branch of the economy or type of industry"},
   {"Базовая валюта инструмента","Basic currency of a symbol"},
   {"Валюта прибыли","Profit currency"},
   {"Валюта залоговых средств","Margin currency"},
   {"Источник текущей котировки","Feeder of the current quote"},
   {"Описание символа","Symbol description"},
   {"Формула для построения цены пользовательского символа","The formula used for custom symbol pricing"},
   {"Имя торгового символа в системе международных идентификационных кодов","The name of a symbol in the ISIN system"},
   {"Адрес интернет страницы с информацией по символу","The address of the web page containing symbol information"},
   {"Путь в дереве символов","Path in the symbol tree"},
   {"Название категории или сектора, к которой принадлежит торговый символ","The name of the sector or category to which the trading symbol belongs"},
   {"Название биржи или площадки, на которой торгуется символ","The name of the exchange in which the financial symbol is traded"},
   //---

...

   {"В окно \"Обзор рынка\" добавлен символ","Added a symbol to the \"Market Watch\" window"},
   {"Из окна \"Обзор рынка\" удалён символ","From the \"Market Watch\" window was removed"},
   {"Изменено расположение символов в окне \"Обзор рынка\"","Changed the arrangement of symbols in the \"Market Watch\" window"},
   {"Работа только с текущим символом","Work only with the current symbol"},
   {"Работа с предопределённым списком символов","Work with a predefined list of symbols"},
   {"Работа с символами из окна \"Обзор рынка\"","Working with symbols from the \"Market Watch\" window"},
   {"Работа с полным списком всех доступных символов","Work with the full list of all available symbols"},
   {"Осуществлена подписка на стакан цен ","Subscribed to Depth of Market"},
   {"Осуществлена отписка от стакан цен ","Unsubscribed from Depth of Market"},
   {"Подписка на стакан цен","Subscription to Depth of Market"},
   {"Ошибка при подписке на стакан цен",""},
   {"Ошибка при отписке от стакан цен",""},
   
   //--- ENUM_SYMBOL_SECTOR
   {"Не определен","Undefined"},
   {"Сырье","Basic materials"},
   {"Услуги связи","Communication services"},
   {"Потребление циклического спроса","Consumer cyclical"},
   {"Основное потребление","Consumer defensive"},
   {"Валюты","Currencies"},
   {"Криптовалюты","Cryptocurrencies"},
   {"Энергетика","Energy"},
   {"Финансы","Finance"},
   {"Здравоохранение","Healthcare"},
   {"Промышленность","Industrials"},
   {"Недвижимость","Real estate"},
   {"Технологии","Technology"},
   {"Коммунальные услуги","Utilities"},
   {"Индексы","Indexes"},
   {"Биржевые товары","Commodities"},
   
   //--- ENUM_SYMBOL_INDUSTRY
   {"Не определено","Undefined"},
   //--- Сырье
   {"Сельскохозяйственные ресурсы","Agricultural inputs"},
   {"Алюминий","Aluminium"},
   {"Строительные материалы","Building materials"},
   {"Химикаты","Chemicals"},
   {"Коксующийся уголь","Coking coal"},
   {"Медь","Copper"},
   {"Золото","Gold"},
   {"Производство пиломатериалов и древесины","Lumber and wood production"},
   {"Прочие промышленные металлы и добыча","Other industrial metals and mining"},
   {"Прочие драгоценные металлы и добыча","Other precious metals and mining"},
   {"Целлюлозно-бумажные изделия","Paper and paper products"},
   {"Серебро","Silver"},
   {"Специальные химикаты","Specialty chemicals"},
   {"Сталь","Steel"},
   //--- Услуги связи
   {"Рекламные агентства","Advertising agencies"},
   {"Вещание","Broadcasting"},
   {"Электронные игры и мультимедиа","Electronic gaming and multimedia"},
   {"Развлечения","Entertainment"},
   {"Интернет-контент и информация","Internet content and information"},
   {"Издательство","Publishing"},
   {"Телекоммуникационные услуги","Telecom services"},
   //--- Потребление циклического спроса
   {"Производство одежды","Apparel manufacturing"},
   {"Розничная продажа одежды","Apparel retail"},
   {"Автомобилестроение","Auto manufacturers"},
   {"Автозапчасти","Auto parts"},
   {"Дилеры легковых и грузовых автомобилей","Auto and truck dealerships"},
   {"Универсальные магазины","Department stores"},
   {"Обувь и аксессуары","Footwear and accessories"},
   {"Мебель, фурнитура и бытовая техника","Furnishing, fixtures and appliances"},
   {"Игорные предприятия","Gambling"},
   {"Розничная торговля товарами для дома","Home improvement retail"},
   {"Розничная онлайн-торговля","Internet retail"},
   {"Досуг","Leisure"},
   {"Жилье","Lodging"},
   {"Товары класса \"люкс\"","Luxury goods"},
   {"Упаковка","Packaging and containers"},
   {"Персональные услуги","Personal services"},
   {"Транспортные средства для отдыха","Recreational vehicles"},
   {"Жилищное строительство","Residential construction"},
   {"Курорты и казино","Resorts and casinos"},
   {"Рестораны","Restaurants"},
   {"Специализированная розничная торговля","Specialty retail"},
   {"Текстильное производство","Textile manufacturing"},
   {"Туристические услуги","Travel services"},
   //--- Основное потребление
   {"Напитки - Пивовары","Beverages - Brewers"},
   {"Напитки - Безалкогольные","Beverages - Non-alcoholic"},
   {"Напитки - Винзаводы и ликеро-водочные заводы","Beverages - Wineries and distilleries"},
   {"Кондитеры","Confectioners"},
   {"Дисконтные магазины","Discount stores"},
   {"Образование и обучение","Education and training services"},
   {"Сельскохозяйственные продукты","Farm products"},
   {"Дистрибуция продуктов питания","Food distribution"},
   {"Продуктовые магазины","Grocery stores"},
   {"Товары для дома и быта","Household and personal products"},
   {"Упакованные продукты","Packaged foods"},
   {"Табак","Tobacco"},
   //--- Энергетика
   {"Бурение нефтяных и газовых скважин","Oil and gas drilling"},
   {"Добыча и переработка нефти и газа","Oil and gas extraction and processing"},
   {"Нефтегазовое оборудование и услуги","Oil and gas equipment and services"},
   {"Интегрированные нефтегазовые компании","Oil and gas integrated"},
   {"Транспортировка нефти и газа","Oil and gas midstream"},
   {"Переработка и сбыт нефти и газа","Oil and gas refining and marketing"},
   {"Энергетический уголь","Thermal coal"},
   {"Уран","Uranium"},
   //--- Финансы
   {"Биржевой фонд","Exchange traded fund"},
   {"Управление активами","Assets management"},
   {"Банки - Диверсифицированные","Banks - Diversified"},
   {"Банки - Региональные","Banks - Regional"},
   {"Финансовые рынки","Capital markets"},
   {"Закрытый фонд - Долговые инструменты","Closed-End fund - Debt"},
   {"Закрытый фонд - Акции","Closed-end fund - Equity"},
   {"Закрытый фонд - Иностранные","Closed-end fund - Foreign"},
   {"Кредитные услуги","Credit services"},
   {"Финансовые конгломераты","Financial conglomerates"},
   {"Финансовые данные и биржи","Financial data and stock exchange"},
   {"Страховые брокеры","Insurance brokers"},
   {"Страхование - Диверсифицированные","Insurance - Diversified"},
   {"Страхование - Жизнь","Insurance - Life"},
   {"Страхование - Недвижимость и несчастные случаи","Insurance - Property and casualty"},
   {"Страхование - Перестрахование","Insurance - Reinsurance"},
   {"Страхование - Специальное","Insurance - Specialty"},
   {"Ипотечное финансирование","Mortgage finance"},
   {"Шелл-компании","Shell companies"},
   //--- Здравоохранение
   {"Биотехнологии","Biotechnology"},
   {"Диагностика и исследования","Diagnostics and research"},
   {"Фармацевтическое производство - Общее","Drugs manufacturers - general"},
   {"Фармацевтическое производство - Специальное и дженерики","Drugs manufacturers - Specialty and generic"},
   {"Планы здравоохранения","Healthcare plans"},
   {"Информационные службы здравоохранения","Health information services"},
   {"Медицинские учреждения","Medical care facilities"},
   {"Медицинское оборудование","Medical devices"},
   {"Медицинские дистрибьюторы","Medical distribution"},
   {"Медицинские инструменты и расходные материалы","Medical instruments and supplies"},
   {"Фармацевтические ритейлеры","Pharmaceutical retailers"},
   //--- Промышленность
   {"Аэрокосмическая и оборонная промышленность","Aerospace and defense"},
   {"Авиакомпании","Airlines"},
   {"Аэропорты и воздушные перевозки","Airports and air services"},
   {"Строительные материалы и оборудование","Building products and equipment"},
   {"Деловое оборудование и материалы","Business equipment and supplies"},
   {"Конгломераты","Conglomerates"},
   {"Консалтинговые услуги","Consulting services"},
   {"Электрооборудование и запчасти","Electrical equipment and parts"},
   {"Инженерное дело и строительство","Engineering and construction"},
   {"Сельскохозяйственное и тяжелое строительное оборудование","Farm and heavy construction machinery"},
   {"Промышленные дистрибьюторы","Industrial distribution"},
   {"Инфраструктурные операции","Infrastructure operations"},
   {"Интегрированные перевозки и логистика","Integrated freight and logistics"},
   {"Морские перевозки","Marine shipping"},
   {"Металлопроизводство","Metal fabrication"},
   {"Контроль загрязнения и очистка","Pollution and treatment controls"},
   {"Железные дороги","Railroads"},
   {"Аренда и лизинг","Rental and leasing services"},
   {"Безопасность и защита","Security and protection services"},
   {"Специализированные бизнес-услуги","Specialty business services"},
   {"Специализированные промышленные машины","Specialty industrial machinery"},
   {"Услуги по трудоустройству","Stuffing and employment services"},
   {"Инструменты и инвентарь","Tools and accessories"},
   {"Грузоперевозки","Trucking"},
   {"Управление отходами","Waste management"},
   //--- Недвижимость
   {"Недвижимость - Строительство","Real estate - Development"},
   {"Недвижимость - Диверсифицированные","Real estate - Diversified"},
   {"Услуги в сфере недвижимости","Real estate services"},
   {"Инвестиционный фонд недвижимости - Диверсифицированные","REIT - Diversified"},
   {"Инвестиционный фонд недвижимости - Медицинские учреждения","REIT - Healthcase facilities"},
   {"Инвестиционный фонд недвижимости - Отели","REIT - Hotel and motel"},
   {"Инвестиционный фонд недвижимости - Промышленность","REIT - Industrial"},
   {"Инвестиционный фонд недвижимости - Ипотека","REIT - Mortgage"},
   {"Инвестиционный фонд недвижимости - Офисы","REIT - Office"},
   {"Инвестиционный фонд недвижимости - Жилые помещения","REIT - Residential"},
   {"Инвестиционный фонд недвижимости - Розница","REIT - Retail"},
   {"Инвестиционный фонд недвижимости - Специальные помещения","REIT - Specialty"},
   //--- Технологии
   {"Коммуникационное оборудование","Communication equipment"},
   {"Компьютерное оборудование","Computer hardware"},
   {"Бытовая электроника","Consumer electronics"},
   {"Электронные компоненты","Electronic components"},
   {"Дистрибуция электроники и компьютеров","Electronics and computer distribution"},
   {"Услуги информационных технологий","Information technology services"},
   {"Научно-технические инструменты","Scientific and technical instruments"},
   {"Полупроводниковое оборудование и материалы","Semiconductor equipment and materials"},
   {"Полупроводники","Semiconductors"},
   {"Программное обеспечение - Приложения","Software - Application"},
   {"Программное обеспечение - Инфраструктура","Software - Infrastructure"},
   {"Солнечная энергетика","Solar"},
   //--- Коммунальные услуги
   {"Коммунальные предприятия - Диверсифицированные","Utilities - Diversified"},
   {"Коммунальные предприятия - Независимые производители энергии","Utilities - Independent power producers"},
   {"Коммунальные предприятия - Возобновляемая энергия","Utilities - Renewable"},
   {"Коммунальные предприятия - Регулируемые электрические компании","Utilities - Regulated electric"},
   {"Коммунальные предприятия - Регулируемые газовые компании","Utilities - Regulated gas"},
   {"Коммунальные предприятия - Регулируемые водоканалы","Utilities - Regulated water"},
   
//--- CAccount


В файле \MQL5\Include\DoEasy\Defines.mqh впишем новые константы в перечисления целочисленных, вещественных и строковых свойств объекта-символа:

//+------------------------------------------------------------------+
//| Целочисленные свойства символа                                   |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_INTEGER
  {
   SYMBOL_PROP_STATUS = 0,                                  // Статус символа
   SYMBOL_PROP_INDEX_MW,                                    // Индекс символа в окне "Обзор рынка"
   SYMBOL_PROP_SECTOR,                                      // Сектор экономики, к которому относится символ
   SYMBOL_PROP_INDUSTRY,                                    // Вид промышленности или отрасль экономики, к которому относится символ
   SYMBOL_PROP_CUSTOM,                                      // Признак того, что символ является пользовательским
   SYMBOL_PROP_CHART_MODE,                                  // Тип цены для построения баров – Bid или Last (из перечисления ENUM_SYMBOL_CHART_MODE)
   SYMBOL_PROP_EXIST,                                       // Признак того, что символ с таким именем существует
   SYMBOL_PROP_SELECT,                                      // Признак того, что символ выбран в Market Watch
   SYMBOL_PROP_VISIBLE,                                     // Признак того, что выбранный символ отображается в Market Watch
   SYMBOL_PROP_SESSION_DEALS,                               // Количество сделок в текущей сессии 
   SYMBOL_PROP_SESSION_BUY_ORDERS,                          // Общее число ордеров на покупку в текущий момент
   SYMBOL_PROP_SESSION_SELL_ORDERS,                         // Общее число ордеров на продажу в текущий момент
   SYMBOL_PROP_VOLUME,                                      // Volume - объем в последней сделке
   SYMBOL_PROP_VOLUMEHIGH,                                  // Максимальный Volume за день
   SYMBOL_PROP_VOLUMELOW,                                   // Минимальный Volume за день
   SYMBOL_PROP_TIME,                                        // Время последней котировки
   SYMBOL_PROP_TIME_MSC,                                    // Время последней котировки в миллисекундах
   SYMBOL_PROP_DIGITS,                                      // Количество знаков после запятой
   SYMBOL_PROP_DIGITS_LOTS,                                 // Количество знаков после запятой для лота
   SYMBOL_PROP_SPREAD,                                      // Размер спреда в пунктах
   SYMBOL_PROP_SPREAD_FLOAT,                                // Признак плавающего спреда
   SYMBOL_PROP_TICKS_BOOKDEPTH,                             // Максимальное количество показываемых заявок в стакане
   SYMBOL_PROP_BOOKDEPTH_STATE,                             // Признак подписки на стакан
   SYMBOL_PROP_TRADE_CALC_MODE,                             // Способ вычисления стоимости контракта (из перечисления ENUM_SYMBOL_CALC_MODE)
   SYMBOL_PROP_TRADE_MODE,                                  // Тип исполнения ордеров (из перечисления ENUM_SYMBOL_TRADE_MODE)
   SYMBOL_PROP_START_TIME,                                  // Дата начала торгов по инструменту (обычно используется для фьючерсов)
   SYMBOL_PROP_EXPIRATION_TIME,                             // Дата окончания торгов по инструменту (обычно используется для фьючерсов)
   SYMBOL_PROP_TRADE_STOPS_LEVEL,                           // Минимальный отступ в пунктах от текущей цены закрытия для установки Stop ордеров
   SYMBOL_PROP_TRADE_FREEZE_LEVEL,                          // Дистанция заморозки торговых операций (в пунктах)
   SYMBOL_PROP_TRADE_EXEMODE,                               // Режим заключения сделок (из перечисления ENUM_SYMBOL_TRADE_EXECUTION)
   SYMBOL_PROP_SWAP_MODE,                                   // Модель расчета свопа (из перечисления ENUM_SYMBOL_SWAP_MODE)
   SYMBOL_PROP_SWAP_ROLLOVER3DAYS,                          // День недели для начисления тройного свопа (из перечисления ENUM_DAY_OF_WEEK)
   SYMBOL_PROP_MARGIN_HEDGED_USE_LEG,                       // Режим расчета хеджированной маржи по наибольшей стороне (Buy или Sell)
   SYMBOL_PROP_EXPIRATION_MODE,                             // Флаги разрешенных режимов истечения ордера
   SYMBOL_PROP_FILLING_MODE,                                // Флаги разрешенных режимов заливки ордера
   SYMBOL_PROP_ORDER_MODE,                                  // Флаги разрешенных типов ордера
   SYMBOL_PROP_ORDER_GTC_MODE,                              // Срок действия StopLoss и TakeProfit ордеров, если SYMBOL_EXPIRATION_MODE=SYMBOL_EXPIRATION_GTC (из перечисления ENUM_SYMBOL_ORDER_GTC_MODE)
   SYMBOL_PROP_OPTION_MODE,                                 // Тип опциона (из перечисления ENUM_SYMBOL_OPTION_MODE)
   SYMBOL_PROP_OPTION_RIGHT,                                // Право опциона (Call/Put) (из перечисления ENUM_SYMBOL_OPTION_RIGHT)
   //--- пропускаемое свойство
   SYMBOL_PROP_BACKGROUND_COLOR                             // Цвет фона, которым подсвечивается символ в Market Watch
  }; 
#define SYMBOL_PROP_INTEGER_TOTAL    (40)                   // Общее количество целочисленных свойств
#define SYMBOL_PROP_INTEGER_SKIP     (1)                    // Количество неиспользуемых в сортировке целочисленных свойств символа
//+------------------------------------------------------------------+
//| Вещественные свойства символа                                    |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_DOUBLE
  {
   SYMBOL_PROP_BID = SYMBOL_PROP_INTEGER_TOTAL,             // Bid - лучшее предложение на продажу
   SYMBOL_PROP_BIDHIGH,                                     // Максимальный Bid за день
   SYMBOL_PROP_BIDLOW,                                      // Минимальный Bid за день
   SYMBOL_PROP_ASK,                                         // Ask - лучшее предложение на покупку
   SYMBOL_PROP_ASKHIGH,                                     // Максимальный Ask за день
   SYMBOL_PROP_ASKLOW,                                      // Минимальный Ask за день
   SYMBOL_PROP_LAST,                                        // Цена, по которой совершена последняя сделка
   SYMBOL_PROP_LASTHIGH,                                    // Максимальный Last за день
   SYMBOL_PROP_LASTLOW,                                     // Минимальный Last за день
   SYMBOL_PROP_VOLUME_REAL,                                 // Volume за день
   SYMBOL_PROP_VOLUMEHIGH_REAL,                             // Максимальный Volume за день
   SYMBOL_PROP_VOLUMELOW_REAL,                              // Минимальный Volume за день
   SYMBOL_PROP_OPTION_STRIKE,                               // Цена исполнения опциона
   SYMBOL_PROP_POINT,                                       // Значение одного пункта
   SYMBOL_PROP_TRADE_TICK_VALUE,                            // Значение SYMBOL_TRADE_TICK_VALUE_PROFIT
   SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT,                     // Рассчитанная стоимость тика для прибыльной позиции
   SYMBOL_PROP_TRADE_TICK_VALUE_LOSS,                       // Рассчитанная стоимость тика для убыточной позиции
   SYMBOL_PROP_TRADE_TICK_SIZE,                             // Минимальное изменение цены
   SYMBOL_PROP_TRADE_CONTRACT_SIZE,                         // Размер торгового контракта
   SYMBOL_PROP_TRADE_ACCRUED_INTEREST,                      // Накопленный купонный доход
   SYMBOL_PROP_TRADE_FACE_VALUE,                            // Номинальная стоимость – начальная стоимость облигации, установленная эмитентом
   SYMBOL_PROP_TRADE_LIQUIDITY_RATE,                        // Коэффициент ликвидности – доля от стоимости актива, которую можно использовать в качестве залога
   SYMBOL_PROP_VOLUME_MIN,                                  // Минимальный объем для заключения сделки
   SYMBOL_PROP_VOLUME_MAX,                                  // Максимальный объем для заключения сделки
   SYMBOL_PROP_VOLUME_STEP,                                 // Минимальный шаг изменения объема для заключения сделки
   SYMBOL_PROP_VOLUME_LIMIT,                                // Максимально допустимый совокупный объем открытой позиции и отложенных ордеров в одном направлении (покупка или продажа)
   SYMBOL_PROP_SWAP_LONG,                                   // Значение свопа в покупку
   SYMBOL_PROP_SWAP_SHORT,                                  // Значение свопа в продажу
   SYMBOL_PROP_MARGIN_INITIAL,                              // Начальная (инициирующая) маржа
   SYMBOL_PROP_MARGIN_MAINTENANCE,                          // Поддерживающая маржа по инструменту
   SYMBOL_PROP_MARGIN_LONG_INITIAL,                         // Коэффициент взимания начальной маржи по длинным позициям
   SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL,                     // Коэффициент взимания начальной маржи по BuyStop ордерам
   SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL,                    // Коэффициент взимания начальной маржи по BuyLimit ордерам
   SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL,                // Коэффициент взимания начальной маржи по BuyStopLimit ордерам
   SYMBOL_PROP_MARGIN_LONG_MAINTENANCE,                     // Коэффициент взимания поддерживающей маржи по длинным позициям
   SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE,                 // Коэффициент взимания поддерживающей маржи по BuyStop ордерам
   SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE,                // Коэффициент взимания поддерживающей маржи по BuyLimit ордерам
   SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE,            // Коэффициент взимания поддерживающей маржи по BuyStopLimit ордерам
   SYMBOL_PROP_MARGIN_SHORT_INITIAL,                        // Коэффициент взимания начальной маржи по коротким позициям
   SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL,                    // Коэффициент взимания начальной маржи по SellStop ордерам
   SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL,                   // Коэффициент взимания начальной маржи по SellLimit ордерам
   SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL,               // Коэффициент взимания начальной маржи по SellStopLimit ордерам
   SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE,                    // Коэффициент взимания поддерживающей маржи по коротким позициям
   SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE,                // Коэффициент взимания поддерживающей маржи по SellStop ордерам
   SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE,               // Коэффициент взимания поддерживающей маржи по SellLimit ордерам
   SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE,           // Коэффициент взимания поддерживающей маржи по SellStopLimit ордерам
   SYMBOL_PROP_SESSION_VOLUME,                              // Cуммарный объём сделок в текущую сессию
   SYMBOL_PROP_SESSION_TURNOVER,                            // Cуммарный оборот в текущую сессию
   SYMBOL_PROP_SESSION_INTEREST,                            // Cуммарный объём открытых позиций
   SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,                   // Общий объём ордеров на покупку в текущий момент
   SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,                  // Общий объём ордеров на продажу в текущий момент
   SYMBOL_PROP_SESSION_OPEN,                                // Цена открытия сессии
   SYMBOL_PROP_SESSION_CLOSE,                               // Цена закрытия сессии
   SYMBOL_PROP_SESSION_AW,                                  // Средневзвешенная цена сессии
   SYMBOL_PROP_SESSION_PRICE_SETTLEMENT,                    // Цена поставки на текущую сессию
   SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN,                     // Минимально допустимое значение цены на сессию 
   SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX,                     // Максимально допустимое значение цены на сессию
   SYMBOL_PROP_MARGIN_HEDGED,                               // Размер контракта или маржи для одного лота перекрытых позиций (разнонаправленные позиции по одному символу).
   SYMBOL_PROP_PRICE_CHANGE,                                // Изменение текущей цены относительно конца предыдущего торгового дня, выраженное в процентах
   SYMBOL_PROP_PRICE_VOLATILITY,                            // Волатильность цены в процентах
   SYMBOL_PROP_PRICE_THEORETICAL,                           // Теоретическая цена опциона
   SYMBOL_PROP_PRICE_DELTA,                                 // Дельта опциона/варранта. Показывает, на сколько единиц изменится цена опциона при изменении цены базового актива на 1 единицу
   SYMBOL_PROP_PRICE_THETA,                                 // Тета опциона/варранта. Количество пунктов, которое будет терять цена опциона каждый день из-за временного распада, т.е. при приближении даты экспирации
   SYMBOL_PROP_PRICE_GAMMA,                                 // Гамма опциона/варранта. Показывает скорость изменения дельты – насколько быстро или медленно меняется опционная премия
   SYMBOL_PROP_PRICE_VEGA,                                  // Вега опциона/варранта. Показывает количество пунктов, на которое изменится цена опциона при изменении волатильности на 1%
   SYMBOL_PROP_PRICE_RHO,                                   // Ро опциона/варранта. Отражает чувствительность теоретической цены опциона к изменению процентной ставки на 1%
   SYMBOL_PROP_PRICE_OMEGA,                                 // Омега опциона/варранта. Эластичность опциона – относительное процентное изменение цены опциона на процентное изменение цены базового актива
   SYMBOL_PROP_PRICE_SENSITIVITY,                           // Чувствительность опциона/варранта.  Показывает, на сколько пунктов должна измениться цена базового актива опциона, чтобы цена опциона изменилась на один пункт
  
  };
#define SYMBOL_PROP_DOUBLE_TOTAL     (68)                   // Общее количество вещественных свойств
#define SYMBOL_PROP_DOUBLE_SKIP      (0)                    // Количество неиспользуемых в сортировке вещественных свойств символа
//+------------------------------------------------------------------+
//| Строковые свойства символа                                       |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_STRING
  {
   SYMBOL_PROP_NAME = (SYMBOL_PROP_INTEGER_TOTAL+SYMBOL_PROP_DOUBLE_TOTAL),   // Имя символа
   SYMBOL_PROP_BASIS,                                       // Имя базового актива для производного инструмента
   SYMBOL_PROP_CURRENCY_BASE,                               // Базовая валюта инструмента
   SYMBOL_PROP_CURRENCY_PROFIT,                             // Валюта прибыли
   SYMBOL_PROP_CURRENCY_MARGIN,                             // Валюта, в которой вычисляются залоговые средства
   SYMBOL_PROP_BANK,                                        // Источник текущей котировки
   SYMBOL_PROP_DESCRIPTION,                                 // Строковое описание символа
   SYMBOL_PROP_FORMULA,                                     // Формула для построения цены пользовательского символа
   SYMBOL_PROP_ISIN,                                        // Имя торгового символа в системе международных идентификационных кодов ценных бумаг — ISIN
   SYMBOL_PROP_PAGE,                                        // Адрес интернет страницы с информацией по символу
   SYMBOL_PROP_PATH,                                        // Путь в дереве символов
   SYMBOL_PROP_CATEGORY,                                    // Категория символа
   SYMBOL_PROP_EXCHANGE,                                    // Название биржи или площадки, на которой торгуется символ
   SYMBOL_PROP_COUNTRY,                                     // Страна, к которой отнесен финансовый инструмент
   SYMBOL_PROP_SECTOR_NAME,                                 // Сектор экономики, к которому относится финансовый инструмент
   SYMBOL_PROP_INDUSTRY_NAME,                               // Отрасль экономики или вид промышленности, к которой относится финансовый инструмент
  };
#define SYMBOL_PROP_STRING_TOTAL     (16)                   // Общее количество строковых свойств
//+------------------------------------------------------------------+

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


В перечислении возможных критериев сортировки символов добавим новые константы, соответствующие вновь добавленным константам перечислений всех свойств объекта — чтобы мы могли выбирать, сортировать и фильтровать символы по новым свойствам:

//+------------------------------------------------------------------+
//| Возможные критерии сортировки символов                           |
//+------------------------------------------------------------------+
#define FIRST_SYM_DBL_PROP          (SYMBOL_PROP_INTEGER_TOTAL-SYMBOL_PROP_INTEGER_SKIP)
#define FIRST_SYM_STR_PROP          (SYMBOL_PROP_INTEGER_TOTAL-SYMBOL_PROP_INTEGER_SKIP+SYMBOL_PROP_DOUBLE_TOTAL-SYMBOL_PROP_DOUBLE_SKIP)
enum ENUM_SORT_SYMBOLS_MODE
  {
//--- Сортировка по целочисленным свойствам
   SORT_BY_SYMBOL_STATUS = 0,                               // Сортировать по статусу символа
   SORT_BY_SYMBOL_INDEX_MW,                                 // Сортировать по индексу в окне "Обзор рынка"
   SORT_BY_SYMBOL_SECTOR,                                   // Сортировать по сектору экономики
   SORT_BY_SYMBOL_INDUSTRY,                                 // Сортировать по виду промышленности или отрасли экономики
   SORT_BY_SYMBOL_CUSTOM,                                   // Сортировать по признаку пользовательского символа
   SORT_BY_SYMBOL_CHART_MODE,                               // Сортировать по типу цены для построения баров – Bid или Last (из перечисления ENUM_SYMBOL_CHART_MODE)
   SORT_BY_SYMBOL_EXIST,                                    // Сортировать по признаку того, что символ с таким именем существует
   SORT_BY_SYMBOL_SELECT,                                   // Сортировать по признаку того, что символ выбран в Market Watch
   SORT_BY_SYMBOL_VISIBLE,                                  // Сортировать по признаку того, что выбранный символ отображается в Market Watch
   SORT_BY_SYMBOL_SESSION_DEALS,                            // Сортировать по количеству сделок в текущей сессии 
   SORT_BY_SYMBOL_SESSION_BUY_ORDERS,                       // Сортировать по общему числу ордеров на покупку в текущий момент
   SORT_BY_SYMBOL_SESSION_SELL_ORDERS,                      // Сортировать по общему числу ордеров на продажу в текущий момент
   SORT_BY_SYMBOL_VOLUME,                                   // Сортировать по Volume - объему в последней сделке
   SORT_BY_SYMBOL_VOLUMEHIGH,                               // Сортировать по максимальному Volume за день
   SORT_BY_SYMBOL_VOLUMELOW,                                // Сортировать по минимальному Volume за день
   SORT_BY_SYMBOL_TIME,                                     // Сортировать по времени последней котировки
   SORT_BY_SYMBOL_TIME_MSC,                                 // Сортировать по времени последней котировки в миллисекундах
   SORT_BY_SYMBOL_DIGITS,                                   // Сортировать по количеству знаков после запятой
   SORT_BY_SYMBOL_DIGITS_LOT,                               // Сортировать по количеству знаков после запятой в лоте
   SORT_BY_SYMBOL_SPREAD,                                   // Сортировать по размеру спреда в пунктах
   SORT_BY_SYMBOL_SPREAD_FLOAT,                             // Сортировать по признаку плавающего спреда
   SORT_BY_SYMBOL_TICKS_BOOKDEPTH,                          // Сортировать по максимальному количеству показываемых заявок в стакане
   SORT_BY_SYMBOL_BOOKDEPTH_STATE,                          // Сортировать по признаку подписки на стакан цен
   SORT_BY_SYMBOL_TRADE_CALC_MODE,                          // Сортировать по способу вычисления стоимости контракта (из перечисления ENUM_SYMBOL_CALC_MODE)
   SORT_BY_SYMBOL_TRADE_MODE,                               // Сортировать по типу исполнения ордеров (из перечисления ENUM_SYMBOL_TRADE_MODE)
   SORT_BY_SYMBOL_START_TIME,                               // Сортировать по дате начала торгов по инструменту (обычно используется для фьючерсов)
   SORT_BY_SYMBOL_EXPIRATION_TIME,                          // Сортировать по дате окончания торгов по инструменту (обычно используется для фьючерсов)
   SORT_BY_SYMBOL_TRADE_STOPS_LEVEL,                        // Сортировать по минимальному отступу в пунктах от текущей цены закрытия для установки Stop ордеров
   SORT_BY_SYMBOL_TRADE_FREEZE_LEVEL,                       // Сортировать по дистанции заморозки торговых операций (в пунктах)
   SORT_BY_SYMBOL_TRADE_EXEMODE,                            // Сортировать по режиму заключения сделок (из перечисления ENUM_SYMBOL_TRADE_EXECUTION)
   SORT_BY_SYMBOL_SWAP_MODE,                                // Сортировать по модели расчета свопа (из перечисления ENUM_SYMBOL_SWAP_MODE)
   SORT_BY_SYMBOL_SWAP_ROLLOVER3DAYS,                       // Сортировать по дню недели для начисления тройного свопа (из перечисления ENUM_DAY_OF_WEEK)
   SORT_BY_SYMBOL_MARGIN_HEDGED_USE_LEG,                    // Сортировать по режиму расчета хеджированной маржи по наибольшей стороне (Buy или Sell)
   SORT_BY_SYMBOL_EXPIRATION_MODE,                          // Сортировать по флагам разрешенных режимов истечения ордера
   SORT_BY_SYMBOL_FILLING_MODE,                             // Сортировать по флагам разрешенных режимов заливки ордера
   SORT_BY_SYMBOL_ORDER_MODE,                               // Сортировать по флагам разрешенных типов ордера
   SORT_BY_SYMBOL_ORDER_GTC_MODE,                           // Сортировать по сроку действия StopLoss и TakeProfit ордеров
   SORT_BY_SYMBOL_OPTION_MODE,                              // Сортировать по типу опциона (из перечисления ENUM_SYMBOL_OPTION_MODE)
   SORT_BY_SYMBOL_OPTION_RIGHT,                             // Сортировать по праву опциона (Call/Put) (из перечисления ENUM_SYMBOL_OPTION_RIGHT)
//--- Сортировка по вещественным свойствам
   SORT_BY_SYMBOL_BID = FIRST_SYM_DBL_PROP,                 // Сортировать по Bid
   SORT_BY_SYMBOL_BIDHIGH,                                  // Сортировать по максимальному Bid за день
   SORT_BY_SYMBOL_BIDLOW,                                   // Сортировать по минимальному Bid за день
   SORT_BY_SYMBOL_ASK,                                      // Сортировать по Ask
   SORT_BY_SYMBOL_ASKHIGH,                                  // Сортировать по максимальному Ask за день
   SORT_BY_SYMBOL_ASKLOW,                                   // Сортировать по минимальному Ask за день
   SORT_BY_SYMBOL_LAST,                                     // Сортировать по цене, по которой совершена последняя сделка
   SORT_BY_SYMBOL_LASTHIGH,                                 // Сортировать по максимальному Last за день
   SORT_BY_SYMBOL_LASTLOW,                                  // Сортировать по минимальному Last за день
   SORT_BY_SYMBOL_VOLUME_REAL,                              // Сортировать по Volume за день
   SORT_BY_SYMBOL_VOLUMEHIGH_REAL,                          // Сортировать по максимальному Volume за день
   SORT_BY_SYMBOL_VOLUMELOW_REAL,                           // Сортировать по минимальному Volume за день
   SORT_BY_SYMBOL_OPTION_STRIKE,                            // Сортировать по цене исполнения опциона
   SORT_BY_SYMBOL_POINT,                                    // Сортировать по значению одного пункта
   SORT_BY_SYMBOL_TRADE_TICK_VALUE,                         // Сортировать по значению SYMBOL_TRADE_TICK_VALUE_PROFIT
   SORT_BY_SYMBOL_TRADE_TICK_VALUE_PROFIT,                  // Сортировать по рассчитанной стоимости тика для прибыльной позиции
   SORT_BY_SYMBOL_TRADE_TICK_VALUE_LOSS,                    // Сортировать по рассчитанной стоимости тика для убыточной позиции
   SORT_BY_SYMBOL_TRADE_TICK_SIZE,                          // Сортировать по минимальному изменению цены
   SORT_BY_SYMBOL_TRADE_CONTRACT_SIZE,                      // Сортировать по размеру торгового контракта
   SORT_BY_SYMBOL_TRADE_ACCRUED_INTEREST,                   // Сортировать по накопленному купонному доходу
   SORT_BY_SYMBOL_TRADE_FACE_VALUE,                         // Сортировать по номинальной стоимости
   SORT_BY_SYMBOL_TRADE_LIQUIDITY_RATE,                     // Сортировать по коэффициенту ликвидности
   SORT_BY_SYMBOL_VOLUME_MIN,                               // Сортировать по минимальному объему для заключения сделки
   SORT_BY_SYMBOL_VOLUME_MAX,                               // Сортировать по максимальному объему для заключения сделки
   SORT_BY_SYMBOL_VOLUME_STEP,                              // Сортировать по минимальному шагу изменения объема для заключения сделки
   SORT_BY_SYMBOL_VOLUME_LIMIT,                             // Сортировать по максимально допустимому совокупному объему открытой позиции и отложенных ордеров в одном направлении
   SORT_BY_SYMBOL_SWAP_LONG,                                // Сортировать по значению свопа в покупку
   SORT_BY_SYMBOL_SWAP_SHORT,                               // Сортировать по значению свопа в продажу
   SORT_BY_SYMBOL_MARGIN_INITIAL,                           // Сортировать по начальной (инициирующей) марже
   SORT_BY_SYMBOL_MARGIN_MAINTENANCE,                       // Сортировать по поддерживающей марже по инструменту
   SORT_BY_SYMBOL_MARGIN_LONG_INITIAL,                      // Сортировать по коэффициенту взимания начальной маржи по длинным позициям
   SORT_BY_SYMBOL_MARGIN_BUY_STOP_INITIAL,                  // Сортировать по коэффициенту взимания начальной маржи по BuyStop ордерам
   SORT_BY_SYMBOL_MARGIN_BUY_LIMIT_INITIAL,                 // Сортировать по коэффициенту взимания начальной маржи по BuyLimit ордерам
   SORT_BY_SYMBOL_MARGIN_BUY_STOPLIMIT_INITIAL,             // Сортировать по коэффициенту взимания начальной маржи по BuyStopLimit ордерам
   SORT_BY_SYMBOL_MARGIN_LONG_MAINTENANCE,                  // Сортировать по коэффициенту взимания поддерживающей маржи по длинным позициям
   SORT_BY_SYMBOL_MARGIN_BUY_STOP_MAINTENANCE,              // Сортировать по коэффициенту взимания поддерживающей маржи по BuyStop ордерам
   SORT_BY_SYMBOL_MARGIN_BUY_LIMIT_MAINTENANCE,             // Сортировать по коэффициенту взимания поддерживающей маржи по BuyLimit ордерам
   SORT_BY_SYMBOL_MARGIN_BUY_STOPLIMIT_MAINTENANCE,         // Сортировать по коэффициенту взимания поддерживающей маржи по BuyStopLimit ордерам
   SORT_BY_SYMBOL_MARGIN_SHORT_INITIAL,                     // Сортировать по коэффициенту взимания начальной маржи по коротким позициям
   SORT_BY_SYMBOL_MARGIN_SELL_STOP_INITIAL,                 // Сортировать по коэффициенту взимания начальной маржи по SellStop ордерам
   SORT_BY_SYMBOL_MARGIN_SELL_LIMIT_INITIAL,                // Сортировать по коэффициенту взимания начальной маржи по SellLimit ордерам
   SORT_BY_SYMBOL_MARGIN_SELL_STOPLIMIT_INITIAL,            // Сортировать по коэффициенту взимания начальной маржи по SellStopLimit ордерам
   SORT_BY_SYMBOL_MARGIN_SHORT_MAINTENANCE,                 // Сортировать по коэффициенту взимания поддерживающей маржи по коротким позициям
   SORT_BY_SYMBOL_MARGIN_SELL_STOP_MAINTENANCE,             // Сортировать по коэффициенту взимания поддерживающей маржи по SellStop ордерам
   SORT_BY_SYMBOL_MARGIN_SELL_LIMIT_MAINTENANCE,            // Сортировать по коэффициенту взимания поддерживающей маржи по SellLimit ордерам
   SORT_BY_SYMBOL_MARGIN_SELL_STOPLIMIT_MAINTENANCE,        // Сортировать по коэффициенту взимания поддерживающей маржи по SellStopLimit ордерам
   SORT_BY_SYMBOL_SESSION_VOLUME,                           // Сортировать по суммарному объёму сделок в текущую сессию
   SORT_BY_SYMBOL_SESSION_TURNOVER,                         // Сортировать по суммарному обороту в текущую сессию
   SORT_BY_SYMBOL_SESSION_INTEREST,                         // Сортировать по суммарному объёму открытых позиций
   SORT_BY_SYMBOL_SESSION_BUY_ORDERS_VOLUME,                // Сортировать по общему объёму ордеров на покупку в текущий момент
   SORT_BY_SYMBOL_SESSION_SELL_ORDERS_VOLUME,               // Сортировать по общему объёму ордеров на продажу в текущий момент
   SORT_BY_SYMBOL_SESSION_OPEN,                             // Сортировать по цене открытия сессии
   SORT_BY_SYMBOL_SESSION_CLOSE,                            // Сортировать по цене закрытия сессии
   SORT_BY_SYMBOL_SESSION_AW,                               // Сортировать по средневзвешенной цене сессии
   SORT_BY_SYMBOL_SESSION_PRICE_SETTLEMENT,                 // Сортировать по цене поставки на текущую сессию
   SORT_BY_SYMBOL_SESSION_PRICE_LIMIT_MIN,                  // Сортировать по минимально допустимому значению цены на сессию 
   SORT_BY_SYMBOL_SESSION_PRICE_LIMIT_MAX,                  // Сортировать по максимально допустимому значению цены на сессию
   SORT_BY_SYMBOL_MARGIN_HEDGED,                            // Сортировать по размеру контракта или маржи для одного лота перекрытых позиций
   SORT_BY_SYMBOL_PRICE_CHANGE,                             // Сортировать по изменению текущей цены относительно конца предыдущего торгового дня
   SORT_BY_SYMBOL_PRICE_VOLATILITY,                         // Сортировать по волатильности цены в процентах
   SORT_BY_SYMBOL_PRICE_THEORETICAL,                        // Сортировать по теоретической цене опциона
   SORT_BY_SYMBOL_PRICE_DELTA,                              // Сортировать по дельте опциона/варранта
   SORT_BY_SYMBOL_PRICE_THETA,                              // Сортировать по тете опциона/варранта
   SORT_BY_SYMBOL_PRICE_GAMMA,                              // Сортировать по гамме опциона/варранта
   SORT_BY_SYMBOL_PRICE_VEGA,                               // Сортировать по веге опциона/варранта
   SORT_BY_SYMBOL_PRICE_RHO,                                // Сортировать по Ро опциона/варранта
   SORT_BY_SYMBOL_PRICE_OMEGA,                              // Сортировать по омеге опциона/варранта
   SORT_BY_SYMBOL_PRICE_SENSITIVITY,                        // Сортировать по чувствительности опциона/варранта
//--- Сортировка по строковым свойствам
   SORT_BY_SYMBOL_NAME = FIRST_SYM_STR_PROP,                // Сортировать по имени символа
   SORT_BY_SYMBOL_BASIS,                                    // Сортировать по имени базового актива для производного инструмента
   SORT_BY_SYMBOL_CURRENCY_BASE,                            // Сортировать по базовой валюте инструмента
   SORT_BY_SYMBOL_CURRENCY_PROFIT,                          // Сортировать по валюте прибыли
   SORT_BY_SYMBOL_CURRENCY_MARGIN,                          // Сортировать по валюте, в которой вычисляются залоговые средства
   SORT_BY_SYMBOL_BANK,                                     // Сортировать по источнику текущей котировки
   SORT_BY_SYMBOL_DESCRIPTION,                              // Сортировать по строковому описанию символа
   SORT_BY_SYMBOL_FORMULA,                                  // Сортировать по формуле для построения цены пользовательского символа
   SORT_BY_SYMBOL_ISIN,                                     // Сортировать по имени торгового символа в системе международных идентификационных кодов ценных бумаг — ISIN
   SORT_BY_SYMBOL_PAGE,                                     // Сортировать по адресу интернет страницы с информацией по символу
   SORT_BY_SYMBOL_PATH,                                     // Сортировать по пути в дереве символов
   SORT_BY_SYMBOL_CATEGORY,                                 // Сортировать по категории символа
   SORT_BY_SYMBOL_EXCHANGE,                                 // Сортировать по названию биржи или площадки, на которой торгуется символ
   SORT_BY_SYMBOL_COUNTRY,                                  // Сортировать по стране, к которой отнесен финансовый инструмент
   SORT_BY_SYMBOL_SECTOR_NAME,                              // Сортировать по сектору экономики, к которому относится финансовый инструмент
   SORT_BY_SYMBOL_INDUSTRY_NAME,                            // Сортировать по отрасли экономики или виду промышленности, к которой относится финансовый инструмент
  };
//+------------------------------------------------------------------+


Каждый объект-форма теперь будет иметь новое свойство "Взаимодействие с окружением". Если это свойство установлено, то это будет указывать на то, что этот объект должен реагировать на действия мышки в соответствии с её состоянием. При этом все остальные объекты-формы должны иметь этот флаг в сброшенном состоянии. Т.е. это даст нам возможность выбирать ту форму, над которой был курсор и была нажата кнопка мышки. Либо какие-то ещё необходимые действия, которые возможно проводить только с одной формой, и только так, чтобы график на действия мышки не реагировал.

В этом же файле пропишем это свойство в перечислении целочисленных свойств графического элемента на канвасе:

//+------------------------------------------------------------------+
//| Целочисленные свойства графического элемента на канвасе          |
//+------------------------------------------------------------------+
enum ENUM_CANV_ELEMENT_PROP_INTEGER
  {
   CANV_ELEMENT_PROP_ID = 0,                          // Идентификатор элемента
   CANV_ELEMENT_PROP_TYPE,                            // Тип графического элемента
   CANV_ELEMENT_PROP_BELONG,                          // Принадлежность графического элемента
   CANV_ELEMENT_PROP_NUM,                             // Номер элемента в списке
   CANV_ELEMENT_PROP_CHART_ID,                        // Идентификатор графика
   CANV_ELEMENT_PROP_WND_NUM,                         // Номер подокна графика
   CANV_ELEMENT_PROP_COORD_X,                         // X-координата формы на графике
   CANV_ELEMENT_PROP_COORD_Y,                         // Y-координата формы на графике
   CANV_ELEMENT_PROP_WIDTH,                           // Ширина элемента
   CANV_ELEMENT_PROP_HEIGHT,                          // Высота элемента
   CANV_ELEMENT_PROP_RIGHT,                           // Правая граница элемента
   CANV_ELEMENT_PROP_BOTTOM,                          // Нижняя граница элемента
   CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,                  // Отступ активной зоны от левого края элемента
   CANV_ELEMENT_PROP_ACT_SHIFT_TOP,                   // Отступ активной зоны от верхнего края элемента
   CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,                 // Отступ активной зоны от правого края элемента
   CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,                // Отступ активной зоны от нижнего края элемента
   CANV_ELEMENT_PROP_MOVABLE,                         // Флаг перемещаемости элемента
   CANV_ELEMENT_PROP_ACTIVE,                          // Флаг активности элемента
   CANV_ELEMENT_PROP_INTERACTION,                     // Флаг взаимодействия элемента со внешней средой
   CANV_ELEMENT_PROP_COORD_ACT_X,                     // X-координата активной зоны элемента
   CANV_ELEMENT_PROP_COORD_ACT_Y,                     // Y-координата активной зоны элемента
   CANV_ELEMENT_PROP_ACT_RIGHT,                       // Правая граница активной зоны элемента
   CANV_ELEMENT_PROP_ACT_BOTTOM,                      // Нижняя граница активной зоны элемента
  };
#define CANV_ELEMENT_PROP_INTEGER_TOTAL (23)          // Общее количество целочисленных свойств
#define CANV_ELEMENT_PROP_INTEGER_SKIP  (0)           // Количество неиспользуемых в сортировке целочисленных свойств
//+------------------------------------------------------------------+

Соответственно, подправим и количество целочисленных свойств — изменим их с 22 до 23.

И добавим новое свойство в перечисление возможных критериев сортировки графических элементов на канвасе:

//+------------------------------------------------------------------+
//| Возможные критерии сортировки графических элементов на канвасе   |
//+------------------------------------------------------------------+
#define FIRST_CANV_ELEMENT_DBL_PROP  (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP)
#define FIRST_CANV_ELEMENT_STR_PROP  (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP+CANV_ELEMENT_PROP_DOUBLE_TOTAL-CANV_ELEMENT_PROP_DOUBLE_SKIP)
enum ENUM_SORT_CANV_ELEMENT_MODE
  {
//--- Сортировка по целочисленным свойствам
   SORT_BY_CANV_ELEMENT_ID = 0,                       // Сортировать по идентификатору элемента
   SORT_BY_CANV_ELEMENT_TYPE,                         // Сортировать по типу графического элемента
   SORT_BY_CANV_ELEMENT_BELONG,                       // Сортировать по принадлежности графического элемента
   SORT_BY_CANV_ELEMENT_NUM,                          // Сортировать по номеру формы в списке
   SORT_BY_CANV_ELEMENT_CHART_ID,                     // Сортировать по идентификатору графика
   SORT_BY_CANV_ELEMENT_WND_NUM,                      // Сортировать по номеру окна графика
   SORT_BY_CANV_ELEMENT_COORD_X,                      // Сортировать по X-координате элемента на графике
   SORT_BY_CANV_ELEMENT_COORD_Y,                      // Сортировать по Y-координате элемента на графике
   SORT_BY_CANV_ELEMENT_WIDTH,                        // Сортировать по ширине элемента
   SORT_BY_CANV_ELEMENT_HEIGHT,                       // Сортировать по высоте элемента
   SORT_BY_CANV_ELEMENT_RIGHT,                        // Сортировать по правой границе элемента
   SORT_BY_CANV_ELEMENT_BOTTOM,                       // Сортировать по нижней границе элемента
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_LEFT,               // Сортировать по отступу активной зоны от левого края элемента
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_TOP,                // Сортировать по отступу активной зоны от верхнего края элемента
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_RIGHT,              // Сортировать по отступу активной зоны от правого края элемента
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_BOTTOM,             // Сортировать по отступу активной зоны от нижнего края элемента
   SORT_BY_CANV_ELEMENT_MOVABLE,                      // Сортировать по флагу перемещаемости элемента
   SORT_BY_CANV_ELEMENT_ACTIVE,                       // Сортировать по флагу активности элемента
   SORT_BY_CANV_ELEMENT_INTERACTION,                  // Сортировать по флагу взаимодействия элемента со внешней средой
   SORT_BY_CANV_ELEMENT_COORD_ACT_X,                  // Сортировать по X-координате активной зоны элемента
   SORT_BY_CANV_ELEMENT_COORD_ACT_Y,                  // Сортировать по Y-координате активной зоны элемента
   SORT_BY_CANV_ELEMENT_ACT_RIGHT,                    // Сортировать по правой границе активной зоны элемента
   SORT_BY_CANV_ELEMENT_ACT_BOTTOM,                   // Сортировать по нижней границе активной зоны элемента
//--- Сортировка по вещественным свойствам

//--- Сортировка по строковым свойствам
   SORT_BY_CANV_ELEMENT_NAME_OBJ = FIRST_CANV_ELEMENT_STR_PROP,// Сортировать по имени объекта-элемента
   SORT_BY_CANV_ELEMENT_NAME_RES,                     // Сортировать по имени графического ресурса
  };
//+------------------------------------------------------------------+


Внесём все необходимые доработки в файл класса объекта-символа \MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqh.

В публичной секции класса объявим методы, возвращающие описания сектора экономики и вида промышленности или отрасли экономики:

//--- Возвращает описание (1) статуса, (2) типа цены для построения баров, 
//--- (3) способа вычисления залоговых средств, (4) режима торговли по инструменту,
//--- (5) режима заключения сделок по инструменту, (6) модели расчета свопа,
//--- (7) срока действия StopLoss и TakeProfit ордеров, (8) типа опциона, (9) права опциона
//--- флагов (10) разрешенных типов ордеров, (11) разрешённых типов заливки,
//--- (12) разрешенных режимов истечения ордера, (13) сектора экономики,
//--- (14) вида промышленности или отрасли экономики
   string            GetStatusDescription(void)                   const;
   string            GetChartModeDescription(void)                const;
   string            GetCalcModeDescription(void)                 const;
   string            GetTradeModeDescription(void)                const;
   string            GetTradeExecDescription(void)                const;
   string            GetSwapModeDescription(void)                 const;
   string            GetOrderGTCModeDescription(void)             const;
   string            GetOptionTypeDescription(void)               const;
   string            GetOptionRightDescription(void)              const;
   string            GetOrderModeFlagsDescription(void)           const;
   string            GetFillingModeFlagsDescription(void)         const;
   string            GetExpirationModeFlagsDescription(void)      const;
   string            GetSectorDescription(void)                   const;
   string            GetIndustryDescription(void)                 const;
   
//--- Возвращает (1) тип исполнения, (2) тип истечения ордера, равный type, если он доступен на символе, иначе - корректный вариант
   ENUM_ORDER_TYPE_FILLING GetCorrectTypeFilling(const uint type=ORDER_FILLING_RETURN);
   ENUM_ORDER_TYPE_TIME    GetCorrectTypeExpiration(uint expiration=ORDER_TIME_GTC);
//+------------------------------------------------------------------+
//| Описания свойств объекта-символа                                 |
//+------------------------------------------------------------------+


В блоке методов упрощённого доступа к свойствам объекта-символа впишем методы, возвращающие значения новых свойств объекта-символа:

//+------------------------------------------------------------------+
//| Методы упрощённого доступа к свойствам объекта-символа           |
//+------------------------------------------------------------------+
//--- Целочисленные свойства
   long              Status(void)                                 const { return this.GetProperty(SYMBOL_PROP_STATUS);                                      }
   int               IndexInMarketWatch(void)                     const { return (int)this.GetProperty(SYMBOL_PROP_INDEX_MW);                               }
   ENUM_SYMBOL_SECTOR Sector(void)                                const { return (ENUM_SYMBOL_SECTOR)this.GetProperty(SYMBOL_PROP_SECTOR);                  }
   ENUM_SYMBOL_INDUSTRY Industry(void)                            const { return (ENUM_SYMBOL_INDUSTRY)this.GetProperty(SYMBOL_PROP_INDUSTRY);              }
   bool              IsCustom(void)                               const { return (bool)this.GetProperty(SYMBOL_PROP_CUSTOM);                                }
   color             ColorBackground(void)                        const { return (color)this.GetProperty(SYMBOL_PROP_BACKGROUND_COLOR);                     }
   ENUM_SYMBOL_CHART_MODE ChartMode(void)                         const { return (ENUM_SYMBOL_CHART_MODE)this.GetProperty(SYMBOL_PROP_CHART_MODE);          }
   bool              IsExist(void)                                const { return (bool)this.GetProperty(SYMBOL_PROP_EXIST);                                 }
   bool              IsExist(const string name)                   const { return this.SymbolExists(name);                                                   }
   bool              IsSelect(void)                               const { return (bool)this.GetProperty(SYMBOL_PROP_SELECT);                                }
   bool              IsVisible(void)                              const { return (bool)this.GetProperty(SYMBOL_PROP_VISIBLE);                               }
   long              SessionDeals(void)                           const { return this.GetProperty(SYMBOL_PROP_SESSION_DEALS);                               }
   long              SessionBuyOrders(void)                       const { return this.GetProperty(SYMBOL_PROP_SESSION_BUY_ORDERS);                          }
   long              SessionSellOrders(void)                      const { return this.GetProperty(SYMBOL_PROP_SESSION_SELL_ORDERS);                         }
   long              Volume(void)                                 const { return this.GetProperty(SYMBOL_PROP_VOLUME);                                      }
   long              VolumeHigh(void)                             const { return this.GetProperty(SYMBOL_PROP_VOLUMEHIGH);                                  }
   long              VolumeLow(void)                              const { return this.GetProperty(SYMBOL_PROP_VOLUMELOW);                                   }
   long              Time(void)                                   const { return (datetime)this.GetProperty(SYMBOL_PROP_TIME);                              }
   long              TimeMSC(void)                                const { return (long)this.GetProperty(SYMBOL_PROP_TIME_MSC);                              }
   int               Digits(void)                                 const { return (int)this.GetProperty(SYMBOL_PROP_DIGITS);                                 }
   int               DigitsLot(void)                              const { return (int)this.GetProperty(SYMBOL_PROP_DIGITS_LOTS);                            }
   int               Spread(void)                                 const { return (int)this.GetProperty(SYMBOL_PROP_SPREAD);                                 }
   bool              IsSpreadFloat(void)                          const { return (bool)this.GetProperty(SYMBOL_PROP_SPREAD_FLOAT);                          }
   int               TicksBookdepth(void)                         const { return (int)this.GetProperty(SYMBOL_PROP_TICKS_BOOKDEPTH);                        }
   bool              BookdepthSubscription(void)                  const { return (bool)this.GetProperty(SYMBOL_PROP_BOOKDEPTH_STATE);                       }
   ENUM_SYMBOL_CALC_MODE TradeCalcMode(void)                      const { return (ENUM_SYMBOL_CALC_MODE)this.GetProperty(SYMBOL_PROP_TRADE_CALC_MODE);      }
   ENUM_SYMBOL_TRADE_MODE TradeMode(void)                         const { return (ENUM_SYMBOL_TRADE_MODE)this.GetProperty(SYMBOL_PROP_TRADE_MODE);          }
   datetime          StartTime(void)                              const { return (datetime)this.GetProperty(SYMBOL_PROP_START_TIME);                        }
   datetime          ExpirationTime(void)                         const { return (datetime)this.GetProperty(SYMBOL_PROP_EXPIRATION_TIME);                   }
   int               TradeStopLevel(void)                         const { return (int)this.GetProperty(SYMBOL_PROP_TRADE_STOPS_LEVEL);                      }
   int               TradeFreezeLevel(void)                       const { return (int)this.GetProperty(SYMBOL_PROP_TRADE_FREEZE_LEVEL);                     }
   ENUM_SYMBOL_TRADE_EXECUTION TradeExecutionMode(void)           const { return (ENUM_SYMBOL_TRADE_EXECUTION)this.GetProperty(SYMBOL_PROP_TRADE_EXEMODE);  }
   ENUM_SYMBOL_SWAP_MODE SwapMode(void)                           const { return (ENUM_SYMBOL_SWAP_MODE)this.GetProperty(SYMBOL_PROP_SWAP_MODE);            }
   ENUM_DAY_OF_WEEK  SwapRollover3Days(void)                      const { return (ENUM_DAY_OF_WEEK)this.GetProperty(SYMBOL_PROP_SWAP_ROLLOVER3DAYS);        }
   bool              IsMarginHedgedUseLeg(void)                   const { return (bool)this.GetProperty(SYMBOL_PROP_MARGIN_HEDGED_USE_LEG);                 }
   int               ExpirationModeFlags(void)                    const { return (int)this.GetProperty(SYMBOL_PROP_EXPIRATION_MODE);                        }
   int               FillingModeFlags(void)                       const { return (int)this.GetProperty(SYMBOL_PROP_FILLING_MODE);                           }
   int               OrderModeFlags(void)                         const { return (int)this.GetProperty(SYMBOL_PROP_ORDER_MODE);                             }
   ENUM_SYMBOL_ORDER_GTC_MODE OrderModeGTC(void)                  const { return (ENUM_SYMBOL_ORDER_GTC_MODE)this.GetProperty(SYMBOL_PROP_ORDER_GTC_MODE);  }
   ENUM_SYMBOL_OPTION_MODE OptionMode(void)                       const { return (ENUM_SYMBOL_OPTION_MODE)this.GetProperty(SYMBOL_PROP_OPTION_MODE);        }
   ENUM_SYMBOL_OPTION_RIGHT OptionRight(void)                     const { return (ENUM_SYMBOL_OPTION_RIGHT)this.GetProperty(SYMBOL_PROP_OPTION_RIGHT);      }
//--- Вещественные свойства
   double            Bid(void)                                    const { return this.GetProperty(SYMBOL_PROP_BID);                                         }
   double            BidHigh(void)                                const { return this.GetProperty(SYMBOL_PROP_BIDHIGH);                                     }
   double            BidLow(void)                                 const { return this.GetProperty(SYMBOL_PROP_BIDLOW);                                      }
   double            Ask(void)                                    const { return this.GetProperty(SYMBOL_PROP_ASK);                                         }
   double            AskHigh(void)                                const { return this.GetProperty(SYMBOL_PROP_ASKHIGH);                                     }
   double            AskLow(void)                                 const { return this.GetProperty(SYMBOL_PROP_ASKLOW);                                      }
   double            Last(void)                                   const { return this.GetProperty(SYMBOL_PROP_LAST);                                        }
   double            LastHigh(void)                               const { return this.GetProperty(SYMBOL_PROP_LASTHIGH);                                    }
   double            LastLow(void)                                const { return this.GetProperty(SYMBOL_PROP_LASTLOW);                                     }
   double            VolumeReal(void)                             const { return this.GetProperty(SYMBOL_PROP_VOLUME_REAL);                                 }
   double            VolumeHighReal(void)                         const { return this.GetProperty(SYMBOL_PROP_VOLUMEHIGH_REAL);                             }
   double            VolumeLowReal(void)                          const { return this.GetProperty(SYMBOL_PROP_VOLUMELOW_REAL);                              }
   double            OptionStrike(void)                           const { return this.GetProperty(SYMBOL_PROP_OPTION_STRIKE);                               }
   double            Point(void)                                  const { return this.GetProperty(SYMBOL_PROP_POINT);                                       }
   double            TradeTickValue(void)                         const { return this.GetProperty(SYMBOL_PROP_TRADE_TICK_VALUE);                            }
   double            TradeTickValueProfit(void)                   const { return this.GetProperty(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT);                     }
   double            TradeTickValueLoss(void)                     const { return this.GetProperty(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS);                       }
   double            TradeTickSize(void)                          const { return this.GetProperty(SYMBOL_PROP_TRADE_TICK_SIZE);                             }
   double            TradeContractSize(void)                      const { return this.GetProperty(SYMBOL_PROP_TRADE_CONTRACT_SIZE);                         }
   double            TradeAccuredInterest(void)                   const { return this.GetProperty(SYMBOL_PROP_TRADE_ACCRUED_INTEREST);                      }
   double            TradeFaceValue(void)                         const { return this.GetProperty(SYMBOL_PROP_TRADE_FACE_VALUE);                            }
   double            TradeLiquidityRate(void)                     const { return this.GetProperty(SYMBOL_PROP_TRADE_LIQUIDITY_RATE);                        }
   double            LotsMin(void)                                const { return this.GetProperty(SYMBOL_PROP_VOLUME_MIN);                                  }
   double            LotsMax(void)                                const { return this.GetProperty(SYMBOL_PROP_VOLUME_MAX);                                  }
   double            LotsStep(void)                               const { return this.GetProperty(SYMBOL_PROP_VOLUME_STEP);                                 }
   double            VolumeLimit(void)                            const { return this.GetProperty(SYMBOL_PROP_VOLUME_LIMIT);                                }
   double            SwapLong(void)                               const { return this.GetProperty(SYMBOL_PROP_SWAP_LONG);                                   }
   double            SwapShort(void)                              const { return this.GetProperty(SYMBOL_PROP_SWAP_SHORT);                                  }
   double            MarginInitial(void)                          const { return this.GetProperty(SYMBOL_PROP_MARGIN_INITIAL);                              }
   double            MarginMaintenance(void)                      const { return this.GetProperty(SYMBOL_PROP_MARGIN_MAINTENANCE);                          }
   double            MarginLongInitial(void)                      const { return this.GetProperty(SYMBOL_PROP_MARGIN_LONG_INITIAL);                         }
   double            MarginBuyStopInitial(void)                   const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL);                     }
   double            MarginBuyLimitInitial(void)                  const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL);                    }
   double            MarginBuyStopLimitInitial(void)              const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL);                }
   double            MarginLongMaintenance(void)                  const { return this.GetProperty(SYMBOL_PROP_MARGIN_LONG_MAINTENANCE);                     }
   double            MarginBuyStopMaintenance(void)               const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE);                 }
   double            MarginBuyLimitMaintenance(void)              const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE);                }
   double            MarginBuyStopLimitMaintenance(void)          const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE);            }
   double            MarginShortInitial(void)                     const { return this.GetProperty(SYMBOL_PROP_MARGIN_SHORT_INITIAL);                        }
   double            MarginSellStopInitial(void)                  const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL);                    }
   double            MarginSellLimitInitial(void)                 const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL);                   }
   double            MarginSellStopLimitInitial(void)             const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL);               }
   double            MarginShortMaintenance(void)                 const { return this.GetProperty(SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE);                    }
   double            MarginSellStopMaintenance(void)              const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE);                }
   double            MarginSellLimitMaintenance(void)             const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE);               }
   double            MarginSellStopLimitMaintenance(void)         const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE);           }
   double            SessionVolume(void)                          const { return this.GetProperty(SYMBOL_PROP_SESSION_VOLUME);                              }
   double            SessionTurnover(void)                        const { return this.GetProperty(SYMBOL_PROP_SESSION_TURNOVER);                            }
   double            SessionInterest(void)                        const { return this.GetProperty(SYMBOL_PROP_SESSION_INTEREST);                            }
   double            SessionBuyOrdersVolume(void)                 const { return this.GetProperty(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME);                   }
   double            SessionSellOrdersVolume(void)                const { return this.GetProperty(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME);                  }
   double            SessionOpen(void)                            const { return this.GetProperty(SYMBOL_PROP_SESSION_OPEN);                                }
   double            SessionClose(void)                           const { return this.GetProperty(SYMBOL_PROP_SESSION_CLOSE);                               }
   double            SessionAW(void)                              const { return this.GetProperty(SYMBOL_PROP_SESSION_AW);                                  }
   double            SessionPriceSettlement(void)                 const { return this.GetProperty(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT);                    }
   double            SessionPriceLimitMin(void)                   const { return this.GetProperty(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN);                     }
   double            SessionPriceLimitMax(void)                   const { return this.GetProperty(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX);                     }
   double            MarginHedged(void)                           const { return this.GetProperty(SYMBOL_PROP_MARGIN_HEDGED);                               }
   double            PriceChange(void)                            const { return this.GetProperty(SYMBOL_PROP_PRICE_CHANGE);                                }
   double            PriceVolatility(void)                        const { return this.GetProperty(SYMBOL_PROP_PRICE_VOLATILITY);                            }
   double            PriceTheoretical(void)                       const { return this.GetProperty(SYMBOL_PROP_PRICE_THEORETICAL);                           }
   double            PriceDelta(void)                             const { return this.GetProperty(SYMBOL_PROP_PRICE_DELTA);                                 }
   double            PriceTheta(void)                             const { return this.GetProperty(SYMBOL_PROP_PRICE_THETA);                                 }
   double            PriceGamma(void)                             const { return this.GetProperty(SYMBOL_PROP_PRICE_GAMMA);                                 }
   double            PriceVega(void)                              const { return this.GetProperty(SYMBOL_PROP_PRICE_VEGA);                                  }
   double            PriceRho(void)                               const { return this.GetProperty(SYMBOL_PROP_PRICE_RHO);                                   }
   double            PriceOmega(void)                             const { return this.GetProperty(SYMBOL_PROP_PRICE_OMEGA);                                 }
   double            PriceSensitivity(void)                       const { return this.GetProperty(SYMBOL_PROP_PRICE_SENSITIVITY);                           }
   double            NormalizedPrice(const double price)          const;
   double            NormalizedLot(const double volume)           const;
   double            BidLast(void)                                const;
   double            BidLastHigh(void)                            const;
   double            BidLastLow(void)                             const;
   double            AskLast(void)                                const;
   double            AskLastHigh(void)                            const;
   double            AskLastLow(void)                             const;
//--- Строковые свойства
   string            Name(void)                                   const { return this.GetProperty(SYMBOL_PROP_NAME);                                        }
   string            Basis(void)                                  const { return this.GetProperty(SYMBOL_PROP_BASIS);                                       }
   string            CurrencyBase(void)                           const { return this.GetProperty(SYMBOL_PROP_CURRENCY_BASE);                               }
   string            CurrencyProfit(void)                         const { return this.GetProperty(SYMBOL_PROP_CURRENCY_PROFIT);                             }
   string            CurrencyMargin(void)                         const { return this.GetProperty(SYMBOL_PROP_CURRENCY_MARGIN);                             }
   string            Bank(void)                                   const { return this.GetProperty(SYMBOL_PROP_BANK);                                        }
   string            Description(void)                            const { return this.GetProperty(SYMBOL_PROP_DESCRIPTION);                                 }
   string            Formula(void)                                const { return this.GetProperty(SYMBOL_PROP_FORMULA);                                     }
   string            ISIN(void)                                   const { return this.GetProperty(SYMBOL_PROP_ISIN);                                        }
   string            Page(void)                                   const { return this.GetProperty(SYMBOL_PROP_PAGE);                                        }
   string            Path(void)                                   const { return this.GetProperty(SYMBOL_PROP_PATH);                                        }
   string            Category(void)                               const { return this.GetProperty(SYMBOL_PROP_CATEGORY);                                    }
   string            Exchange(void)                               const { return this.GetProperty(SYMBOL_PROP_EXCHANGE);                                    }
   string            Country(void)                                const { return this.GetProperty(SYMBOL_PROP_COUNTRY);                                     }
   string            SectorName(void)                             const { return this.GetProperty(SYMBOL_PROP_SECTOR_NAME);                                 }
   string            IndustryName(void)                           const { return this.GetProperty(SYMBOL_PROP_INDUSTRY_NAME);                               }
//+------------------------------------------------------------------+


В блоке методов получения и установки параметров отслеживаемых изменений свойств впишем необходимые методы для работы со всеми вновь добавленными объекту-символу свойствами:

//+------------------------------------------------------------------+
//| Получение и установка параметров отслеживаемых изменений свойств |
//+------------------------------------------------------------------+
   //--- Исполнение
   //--- Флаг изменения режима торговли для символа
   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);                   }
   //--- Изменение текущей цены относительно конца предыдущего торгового дня
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня изменения текущей цены относительно конца предыдущего торгового дня
   //--- получение (4) величины изменения свойства Изменение текущей цены относительно конца предыдущего торгового дня,
   //--- получение флага изменения свойства Изменение текущей цены относительно конца предыдущего торгового дня больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceChangeInc(const double value)                { this.SetControlledValueINC(SYMBOL_PROP_PRICE_CHANGE,::fabs(value));               }
   void              SetControlPriceChangeDec(const double value)                { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_CHANGE,::fabs(value));               }
   void              SetControlPriceChangeLevel(const double value)              { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_CHANGE,::fabs(value));             }
   double            GetValueChangedPriceChange(void)                      const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_CHANGE);                  }
   bool              IsIncreasedPriceChange(void)                          const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_CHANGE);                 }
   bool              IsDecreasedPriceChange(void)                          const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_CHANGE);                 }
   //--- Волатильность цены в процентах
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня волатильности цены в процентах
   //--- получение (4) величины изменения волатильности цены в процентах,
   //--- получение флага изменения волатильности цены в процентах больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceVolatilityInc(const double value)            { this.SetControlledValueINC(SYMBOL_PROP_PRICE_VOLATILITY,::fabs(value));           }
   void              SetControlPriceVolatilityDec(const double value)            { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_VOLATILITY,::fabs(value));           }
   void              SetControlPriceVolatilityLevel(const double value)          { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_VOLATILITY,::fabs(value));         }
   double            GetValueChangedPriceVolatility(void)                  const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_VOLATILITY);              }
   bool              IsIncreasedPriceVolatility(void)                      const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_VOLATILITY);             }
   bool              IsDecreasedPriceVolatility(void)                      const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_VOLATILITY);             }
   //--- Теоретическая цена опциона
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня теоретической цены опциона
   //--- получение (4) величины изменения теоретической цены опциона,
   //--- получение флага изменения теоретической цены опциона больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceTheoreticalInc(const double value)           { this.SetControlledValueINC(SYMBOL_PROP_PRICE_THEORETICAL,::fabs(value));          }
   void              SetControlPriceTheoreticalDec(const double value)           { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_THEORETICAL,::fabs(value));          }
   void              SetControlPriceTheoreticalLevel(const double value)         { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_THEORETICAL,::fabs(value));        }
   double            GetValueChangedPriceTheoretical(void)                 const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_THEORETICAL);             }
   bool              IsIncreasedPriceTheoretical(void)                     const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_THEORETICAL);            }
   bool              IsDecreasedPriceTheoretical(void)                     const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_THEORETICAL);            }
   //--- Дельта опциона/варранта
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня дельты опциона/варранта
   //--- получение (4) величины изменения дельты опциона/варранта,
   //--- получение флага изменения дельты опциона/варранта больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceDeltaInc(const double value)              { this.SetControlledValueINC(SYMBOL_PROP_PRICE_DELTA,::fabs(value));                   }
   void              SetControlPriceDeltaDec(const double value)              { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_DELTA,::fabs(value));                   }
   void              SetControlPriceDeltaLevel(const double value)            { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_DELTA,::fabs(value));                 }
   double            GetValueChangedPriceDelta(void)                    const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_DELTA);                      }
   bool              IsIncreasedPriceDelta(void)                        const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_DELTA);                     }
   bool              IsDecreasedPriceDelta(void)                        const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_DELTA);                     }
   //--- Тета опциона/варранта
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня теты опциона/варранта
   //--- получение (4) величины изменения теты опциона/варранта,
   //--- получение флага изменения теты опциона/варранта больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceThetaInc(const double value)              { this.SetControlledValueINC(SYMBOL_PROP_PRICE_THETA,::fabs(value));                   }
   void              SetControlPriceThetaDec(const double value)              { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_THETA,::fabs(value));                   }
   void              SetControlPriceThetaLevel(const double value)            { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_THETA,::fabs(value));                 }
   double            GetValueChangedPriceTheta(void)                    const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_THETA);                      }
   bool              IsIncreasedPriceTheta(void)                        const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_THETA);                     }
   bool              IsDecreasedPriceTheta(void)                        const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_THETA);                     }
   //--- Гамма опциона/варранта
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня гаммы опциона/варранта
   //--- получение (4) величины изменения гаммы опциона/варранта,
   //--- получение флага изменения гаммы опциона/варранта больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceGammaInc(const double value)              { this.SetControlledValueINC(SYMBOL_PROP_PRICE_GAMMA,::fabs(value));                   }
   void              SetControlPriceGammaDec(const double value)              { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_GAMMA,::fabs(value));                   }
   void              SetControlPriceGammaLevel(const double value)            { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_GAMMA,::fabs(value));                 }
   double            GetValueChangedPriceGamma(void)                    const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_GAMMA);                      }
   bool              IsIncreasedPriceGamma(void)                        const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_GAMMA);                     }
   bool              IsDecreasedPriceGamma(void)                        const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_GAMMA);                     }
   //--- Вега опциона/варранта
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня веги опциона/варранта
   //--- получение (4) величины изменения средневзвешенной цены сессии,
   //--- получение флага изменения средневзвешенной цены сессии больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceVegaInc(const double value)               { this.SetControlledValueINC(SYMBOL_PROP_PRICE_VEGA,::fabs(value));                    }
   void              SetControlPriceVegaDec(const double value)               { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_VEGA,::fabs(value));                    }
   void              SetControlPriceVegaLevel(const double value)             { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_VEGA,::fabs(value));                  }
   double            GetValueChangedPriceVega(void)                     const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_VEGA);                       }
   bool              IsIncreasedPriceVega(void)                         const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_VEGA);                      }
   bool              IsDecreasedPriceVega(void)                         const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_VEGA);                      }
   //--- Ро опциона/варранта
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня Ро опциона/варранта
   //--- получение (4) величины изменения Ро опциона/варранта,
   //--- получение флага изменения Ро опциона/варранта больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceRhoInc(const double value)                { this.SetControlledValueINC(SYMBOL_PROP_PRICE_RHO,::fabs(value));                     }
   void              SetControlPriceRhoDec(const double value)                { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_RHO,::fabs(value));                     }
   void              SetControlPriceRhoLevel(const double value)              { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_RHO,::fabs(value));                   }
   double            GetValueChangedPriceRho(void)                      const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_RHO);                        }
   bool              IsIncreasedPriceRho(void)                          const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_RHO);                       }
   bool              IsDecreasedPriceRho(void)                          const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_RHO);                       }
   //--- Омега опциона/варранта
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня омеги опциона/варранта
   //--- получение (4) величины изменения омеги опциона/варранта,
   //--- получение флага изменения омеги опциона/варранта больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceOmegaInc(const double value)              { this.SetControlledValueINC(SYMBOL_PROP_PRICE_OMEGA,::fabs(value));                   }
   void              SetControlPriceOmegaDec(const double value)              { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_OMEGA,::fabs(value));                   }
   void              SetControlPriceOmegaLevel(const double value)            { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_OMEGA,::fabs(value));                 }
   double            GetValueChangedPriceOmega(void)                    const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_OMEGA);                      }
   bool              IsIncreasedPriceOmega(void)                        const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_OMEGA);                     }
   bool              IsDecreasedPriceOmega(void)                        const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_OMEGA);                     }
   //--- Чувствительность опциона/варранта
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня чувствительности опциона/варранта
   //--- получение (4) величины изменения чувствительности опциона/варранта,
   //--- получение флага изменения чувствительности опциона/варранта больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlPriceSensitivityInc(const double value)        { this.SetControlledValueINC(SYMBOL_PROP_PRICE_SENSITIVITY,::fabs(value));             }
   void              SetControlPriceSensitivityDec(const double value)        { this.SetControlledValueDEC(SYMBOL_PROP_PRICE_SENSITIVITY,::fabs(value));             }
   void              SetControlPriceSensitivityLevel(const double value)      { this.SetControlledValueLEVEL(SYMBOL_PROP_PRICE_SENSITIVITY,::fabs(value));           }
   double            GetValueChangedPriceSensitivity(void)              const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_PRICE_SENSITIVITY);                }
   bool              IsIncreasedPriceSensitivity(void)                  const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_PRICE_SENSITIVITY);               }
   bool              IsDecreasedPriceSensitivity(void)                  const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_PRICE_SENSITIVITY);               }

//--- Возвращает торговый объект
   CTradeObj        *GetTradeObj(void)                                           { return &this.m_trade; }

  };
//+------------------------------------------------------------------+


В закрытом параметрическом конструкторе пропишем установку в новые свойства объекта-символа его соответствующих значений:

//+------------------------------------------------------------------+
//| Закрытый параметрический конструктор                             |
//+------------------------------------------------------------------+
CSymbol::CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name,const int index)
  {
   this.m_type=OBJECT_DE_TYPE_SYMBOL; 
   this.m_name=name;
   this.m_book_subscribed=false;
   if(!this.Exist())
     {
      ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\"",": ",CMessage::Text(MSG_LIB_SYS_NOT_SYMBOL_ON_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,"\": ",CMessage::Text(MSG_LIB_SYS_FAILED_PUT_SYMBOL),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,"\": ",CMessage::Text(MSG_LIB_SYS_NOT_GET_PRICE),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(),": ",CMessage::Text(MSG_LIB_SYS_NOT_GET_MARGIN_RATES),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_SECTOR]                                             = ::SymbolInfoInteger(this.m_name,SYMBOL_SECTOR);
   this.m_long_prop[SYMBOL_PROP_INDUSTRY]                                           = ::SymbolInfoInteger(this.m_name,SYMBOL_INDUSTRY);
   this.m_long_prop[SYMBOL_PROP_TIME_MSC]                                           = ::SymbolInfoInteger(this.m_name,SYMBOL_TIME_MSC);
   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_long_prop[SYMBOL_PROP_BOOKDEPTH_STATE]                                    = this.m_book_subscribed;
//--- Сохранение вещественных свойств
   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_PRICE_CHANGE)]                     = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_CHANGE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_VOLATILITY)]                 = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_VOLATILITY);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_THEORETICAL)]                = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_THEORETICAL);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_DELTA)]                      = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_DELTA);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_THETA)]                      = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_THETA);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_GAMMA)]                      = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_GAMMA);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_VEGA)]                       = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_VEGA);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_RHO)]                        = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_RHO);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_OMEGA)]                      = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_OMEGA);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_PRICE_SENSITIVITY)]                = ::SymbolInfoDouble(this.m_name,SYMBOL_PRICE_SENSITIVITY);
   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_COUNTRY)]                          = ::SymbolInfoString(this.m_name,SYMBOL_COUNTRY);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_SECTOR_NAME)]                      = ::SymbolInfoString(this.m_name,SYMBOL_SECTOR_NAME);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_INDUSTRY_NAME)]                    = ::SymbolInfoString(this.m_name,SYMBOL_INDUSTRY_NAME);
   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_string_prop[this.IndexProp(SYMBOL_PROP_CATEGORY)]                         = this.SymbolCategory();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_EXCHANGE)]                         = this.SymbolExchange();
//--- Сохранение дополнительных целочисленных свойств
   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];
   
//--- Обновление данных в базовом объекте и поиск изменений
   CBaseObjExt::Refresh();
//---
   if(!select)
      this.RemoveFromMarketWatch();

//--- Инициализация умолчательных значений торгового объекта
   this.m_trade.Init(this.Name(),0,this.LotsMin(),5,0,0,false,this.GetCorrectTypeFilling(),this.GetCorrectTypeExpiration(),LOG_LEVEL_ERROR_MSG);
  }
//+------------------------------------------------------------------+


В методе, возвращающем описание целочисленного свойства символа, пропишем блоки кода для возврата описания новых целочисленных свойств:

//+------------------------------------------------------------------+
//| Возвращает описание целочисленного свойства символа              |
//+------------------------------------------------------------------+
string CSymbol::GetPropertyDescription(ENUM_SYMBOL_PROP_INTEGER property)
  {
   return
     (
      property==SYMBOL_PROP_STATUS              ?  CMessage::Text(MSG_ORD_STATUS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetStatusDescription()
         )  :
      property==SYMBOL_PROP_INDEX_MW            ?  CMessage::Text(MSG_SYM_PROP_INDEX)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_SECTOR              ?  CMessage::Text(MSG_SYM_PROP_SECTOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetSectorDescription()
         )  :
      property==SYMBOL_PROP_INDUSTRY            ?  CMessage::Text(MSG_SYM_PROP_INDUSTRY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetIndustryDescription()
         )  :
      property==SYMBOL_PROP_CUSTOM              ?  CMessage::Text(MSG_SYM_PROP_CUSTOM)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)   ?  CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==SYMBOL_PROP_CHART_MODE          ?  CMessage::Text(MSG_SYM_PROP_CHART_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetChartModeDescription()
         )  :
      property==SYMBOL_PROP_EXIST               ?  CMessage::Text(MSG_SYM_PROP_EXIST)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)   ?  CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==SYMBOL_PROP_SELECT  ?  CMessage::Text(MSG_SYM_PROP_SELECT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)   ?  CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==SYMBOL_PROP_VISIBLE ?  CMessage::Text(MSG_SYM_PROP_VISIBLE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)   ?  CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==SYMBOL_PROP_SESSION_DEALS       ?  CMessage::Text(MSG_SYM_PROP_SESSION_DEALS)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      property==SYMBOL_PROP_SESSION_BUY_ORDERS  ?  CMessage::Text(MSG_SYM_PROP_SESSION_BUY_ORDERS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      property==SYMBOL_PROP_SESSION_SELL_ORDERS ?  CMessage::Text(MSG_SYM_PROP_SESSION_SELL_ORDERS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      property==SYMBOL_PROP_VOLUME              ?  CMessage::Text(MSG_SYM_PROP_VOLUME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      property==SYMBOL_PROP_VOLUMEHIGH          ?  CMessage::Text(MSG_SYM_PROP_VOLUMEHIGH)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      property==SYMBOL_PROP_VOLUMELOW           ?  CMessage::Text(MSG_SYM_PROP_VOLUMELOW)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      property==SYMBOL_PROP_TIME                ?  CMessage::Text(MSG_SYM_PROP_TIME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)==0 ? "("+CMessage::Text(MSG_LIB_SYS_NO_TICKS_YET)+")" : TimeMSCtoString(this.GetProperty(property)))
         )  :
      property==SYMBOL_PROP_TIME_MSC            ?  CMessage::Text(MSG_SYM_PROP_TIME_MSC)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)==0 ? "("+CMessage::Text(MSG_LIB_SYS_NO_TICKS_YET)+")" : TimeMSCtoString(this.GetProperty(property)))
         )  :
      property==SYMBOL_PROP_DIGITS              ?  CMessage::Text(MSG_SYM_PROP_DIGITS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_DIGITS_LOTS         ?  CMessage::Text(MSG_SYM_PROP_DIGITS_LOTS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_SPREAD              ?  CMessage::Text(MSG_SYM_PROP_SPREAD)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_SPREAD_FLOAT        ?  CMessage::Text(MSG_SYM_PROP_SPREAD_FLOAT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)   ?  CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_YES))
         )  :
      property==SYMBOL_PROP_TICKS_BOOKDEPTH     ?  CMessage::Text(MSG_SYM_PROP_TICKS_BOOKDEPTH)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      property==SYMBOL_PROP_BOOKDEPTH_STATE     ?  CMessage::Text(MSG_SYM_SYMBOLS_MODE_BOOK)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ #ifdef __MQL5__
                  (this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) 
                #else 
                  CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) 
                #endif 
         )  :
      property==SYMBOL_PROP_TRADE_CALC_MODE     ?  CMessage::Text(MSG_SYM_PROP_TRADE_CALC_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetCalcModeDescription()
         )  :
      property==SYMBOL_PROP_TRADE_MODE ?  CMessage::Text(MSG_SYM_PROP_TRADE_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetTradeModeDescription()
         )  :
      property==SYMBOL_PROP_START_TIME          ?  CMessage::Text(MSG_SYM_PROP_START_TIME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)==0  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": "+TimeMSCtoString(this.GetProperty(property)*1000))
         )  :
      property==SYMBOL_PROP_EXPIRATION_TIME     ?  CMessage::Text(MSG_SYM_PROP_EXPIRATION_TIME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)==0  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": "+TimeMSCtoString(this.GetProperty(property)*1000))
         )  :
      property==SYMBOL_PROP_TRADE_STOPS_LEVEL   ?  CMessage::Text(MSG_SYM_PROP_TRADE_STOPS_LEVEL)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_TRADE_FREEZE_LEVEL  ?  CMessage::Text(MSG_SYM_PROP_TRADE_FREEZE_LEVEL)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_TRADE_EXEMODE       ?  CMessage::Text(MSG_SYM_PROP_TRADE_EXEMODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetTradeExecDescription()
         )  :
      property==SYMBOL_PROP_SWAP_MODE           ?  CMessage::Text(MSG_SYM_PROP_SWAP_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetSwapModeDescription()
         )  :
      property==SYMBOL_PROP_SWAP_ROLLOVER3DAYS  ?  CMessage::Text(MSG_SYM_PROP_SWAP_ROLLOVER3DAYS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+DayOfWeekDescription(this.SwapRollover3Days())
         )  :
      property==SYMBOL_PROP_MARGIN_HEDGED_USE_LEG  ?  CMessage::Text(MSG_SYM_PROP_MARGIN_HEDGED_USE_LEG)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED)   :
          ": "+(this.GetProperty(property)   ?  CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==SYMBOL_PROP_EXPIRATION_MODE     ?  CMessage::Text(MSG_SYM_PROP_EXPIRATION_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetExpirationModeFlagsDescription()
         )  :
      property==SYMBOL_PROP_FILLING_MODE        ?  CMessage::Text(MSG_SYM_PROP_FILLING_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetFillingModeFlagsDescription()
         )  :
      property==SYMBOL_PROP_ORDER_MODE          ?  CMessage::Text(MSG_SYM_PROP_ORDER_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetOrderModeFlagsDescription()
         )  :
      property==SYMBOL_PROP_ORDER_GTC_MODE      ?  CMessage::Text(MSG_SYM_PROP_ORDER_GTC_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetOrderGTCModeDescription()
         )  :
      property==SYMBOL_PROP_OPTION_MODE         ?  CMessage::Text(MSG_SYM_PROP_OPTION_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetOptionTypeDescription()
         )  :
      property==SYMBOL_PROP_OPTION_RIGHT        ?  CMessage::Text(MSG_SYM_PROP_OPTION_RIGHT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetOptionRightDescription()
         )  :
      property==SYMBOL_PROP_BACKGROUND_COLOR    ?  CMessage::Text(MSG_SYM_PROP_BACKGROUND_COLOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         #ifdef __MQL5__
         (this.GetProperty(property)==CLR_MW_DEFAULT || this.GetProperty(property)==CLR_NONE ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": "+::ColorToString((color)this.GetProperty(property),true))
         #else ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif 
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


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

      property==SYMBOL_PROP_MARGIN_HEDGED    ?  CMessage::Text(MSG_SYM_PROP_MARGIN_HEDGED)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :
      property==SYMBOL_PROP_PRICE_CHANGE     ?  CMessage::Text(MSG_SYM_PROP_PRICE_CHANGE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      property==SYMBOL_PROP_PRICE_VOLATILITY ?  CMessage::Text(MSG_SYM_PROP_PRICE_VOLATILITY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      property==SYMBOL_PROP_PRICE_THEORETICAL ?  CMessage::Text(MSG_SYM_PROP_PRICE_THEORETICAL)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_PRICE_DELTA      ?  CMessage::Text(MSG_SYM_PROP_PRICE_DELTA)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_PRICE_THETA      ?  CMessage::Text(MSG_SYM_PROP_PRICE_THETA)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_PRICE_GAMMA      ?  CMessage::Text(MSG_SYM_PROP_PRICE_GAMMA)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_PRICE_VEGA       ?  CMessage::Text(MSG_SYM_PROP_PRICE_VEGA)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      property==SYMBOL_PROP_PRICE_RHO        ?  CMessage::Text(MSG_SYM_PROP_PRICE_RHO)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      property==SYMBOL_PROP_PRICE_OMEGA      ?  CMessage::Text(MSG_SYM_PROP_PRICE_OMEGA)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_PRICE_SENSITIVITY   ?  CMessage::Text(MSG_SYM_PROP_PRICE_SENSITIVITY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


Добавим аналогичные блоки кода и в метод, возвращающий описание строкового свойства символа:

//+------------------------------------------------------------------+
//| Возвращает описание строкового свойства символа                  |
//+------------------------------------------------------------------+
string CSymbol::GetPropertyDescription(ENUM_SYMBOL_PROP_STRING property)
  {
   return
     (
      property==SYMBOL_PROP_NAME             ?  CMessage::Text(MSG_SYM_PROP_NAME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_BASIS            ?  CMessage::Text(MSG_SYM_PROP_BASIS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_COUNTRY          ?  CMessage::Text(MSG_SYM_PROP_COUNTRY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_SECTOR_NAME      ?  CMessage::Text(MSG_SYM_PROP_SECTOR_NAME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_INDUSTRY_NAME    ?  CMessage::Text(MSG_SYM_PROP_INDUSTRY_NAME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_CURRENCY_BASE    ?  CMessage::Text(MSG_SYM_PROP_CURRENCY_BASE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_CURRENCY_PROFIT  ?  CMessage::Text(MSG_SYM_PROP_CURRENCY_PROFIT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_CURRENCY_MARGIN  ?  CMessage::Text(MSG_SYM_PROP_CURRENCY_MARGIN)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_BANK             ?  CMessage::Text(MSG_SYM_PROP_BANK)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_DESCRIPTION      ?  CMessage::Text(MSG_SYM_PROP_DESCRIPTION)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_FORMULA          ?  CMessage::Text(MSG_SYM_PROP_FORMULA)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_ISIN             ?  CMessage::Text(MSG_SYM_PROP_ISIN)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_PAGE             ?  CMessage::Text(MSG_SYM_PROP_PAGE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_PATH             ?  CMessage::Text(MSG_SYM_PROP_PATH)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_CATEGORY         ?  CMessage::Text(MSG_SYM_PROP_CAYEGORY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_EXCHANGE         ?  CMessage::Text(MSG_SYM_PROP_EXCHANGE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"")
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


Реализация метода, возвращающего описание сектора экономики:

//+------------------------------------------------------------------+
//| Возвращает описание сектора экономики                            |
//+------------------------------------------------------------------+
string CSymbol::GetSectorDescription(void) const
  {
   switch(this.Sector())
     {
      case SECTOR_BASIC_MATERIALS         : return CMessage::Text(MSG_SYM_SECTOR_BASIC_MATERIALS);
      case SECTOR_COMMUNICATION_SERVICES  : return CMessage::Text(MSG_SYM_SECTOR_COMMUNICATION_SERVICES);
      case SECTOR_CONSUMER_CYCLICAL       : return CMessage::Text(MSG_SYM_SECTOR_CONSUMER_CYCLICAL);
      case SECTOR_CONSUMER_DEFENSIVE      : return CMessage::Text(MSG_SYM_SECTOR_CONSUMER_DEFENSIVE);
      case SECTOR_CURRENCY                : return CMessage::Text(MSG_SYM_SECTOR_CURRENCY);
      case SECTOR_CURRENCY_CRYPTO         : return CMessage::Text(MSG_SYM_SECTOR_CURRENCY_CRYPTO);
      case SECTOR_ENERGY                  : return CMessage::Text(MSG_SYM_SECTOR_ENERGY);
      case SECTOR_FINANCIAL               : return CMessage::Text(MSG_SYM_SECTOR_FINANCIAL);
      case SECTOR_HEALTHCARE              : return CMessage::Text(MSG_SYM_SECTOR_HEALTHCARE);
      case SECTOR_INDUSTRIALS             : return CMessage::Text(MSG_SYM_SECTOR_INDUSTRIALS);
      case SECTOR_REAL_ESTATE             : return CMessage::Text(MSG_SYM_SECTOR_REAL_ESTATE);
      case SECTOR_TECHNOLOGY              : return CMessage::Text(MSG_SYM_SECTOR_TECHNOLOGY);
      case SECTOR_UTILITIES               : return CMessage::Text(MSG_SYM_SECTOR_UTILITIES);
      case SECTOR_INDEXES                 : return CMessage::Text(MSG_SYM_SECTOR_INDEXES);
      case SECTOR_COMMODITIES             : return CMessage::Text(MSG_SYM_SECTOR_COMMODITIES);
      default                             : return CMessage::Text(MSG_SYM_SECTOR_UNDEFINED);
     }
  }
//+------------------------------------------------------------------+

В зависимости от значения, возвращаемого методом Sector(), добавленного выше, из метода возвращается соответствующее текстовое описание.

Реализация метода, возвращающего описание вида промышленности или отрасли экономики:

//+------------------------------------------------------------------+
//| Возвращает описание вида промышленности или отрасли экономики    |
//+------------------------------------------------------------------+
string CSymbol::GetIndustryDescription(void) const
  {
   switch(this.Industry())
     {
      case INDUSTRY_AGRICULTURAL_INPUTS            : return CMessage::Text(MSG_SYM_INDUSTRY_AGRICULTURAL_INPUTS);
      case INDUSTRY_ALUMINIUM                      : return CMessage::Text(MSG_SYM_INDUSTRY_ALUMINIUM);
      case INDUSTRY_BUILDING_MATERIALS             : return CMessage::Text(MSG_SYM_INDUSTRY_BUILDING_MATERIALS);
      case INDUSTRY_CHEMICALS                      : return CMessage::Text(MSG_SYM_INDUSTRY_CHEMICALS);
      case INDUSTRY_COKING_COAL                    : return CMessage::Text(MSG_SYM_INDUSTRY_COKING_COAL);
      case INDUSTRY_COPPER                         : return CMessage::Text(MSG_SYM_INDUSTRY_COPPER);
      case INDUSTRY_GOLD                           : return CMessage::Text(MSG_SYM_INDUSTRY_GOLD);
      case INDUSTRY_LUMBER_WOOD                    : return CMessage::Text(MSG_SYM_INDUSTRY_LUMBER_WOOD);
      case INDUSTRY_INDUSTRIAL_METALS              : return CMessage::Text(MSG_SYM_INDUSTRY_INDUSTRIAL_METALS);
      case INDUSTRY_PRECIOUS_METALS                : return CMessage::Text(MSG_SYM_INDUSTRY_PRECIOUS_METALS);
      case INDUSTRY_PAPER                          : return CMessage::Text(MSG_SYM_INDUSTRY_PAPER);
      case INDUSTRY_SILVER                         : return CMessage::Text(MSG_SYM_INDUSTRY_SILVER);
      case INDUSTRY_SPECIALTY_CHEMICALS            : return CMessage::Text(MSG_SYM_INDUSTRY_SPECIALTY_CHEMICALS);
      case INDUSTRY_STEEL                          : return CMessage::Text(MSG_SYM_INDUSTRY_STEEL);
      case INDUSTRY_ADVERTISING                    : return CMessage::Text(MSG_SYM_INDUSTRY_ADVERTISING);
      case INDUSTRY_BROADCASTING                   : return CMessage::Text(MSG_SYM_INDUSTRY_BROADCASTING);
      case INDUSTRY_GAMING_MULTIMEDIA              : return CMessage::Text(MSG_SYM_INDUSTRY_GAMING_MULTIMEDIA);
      case INDUSTRY_ENTERTAINMENT                  : return CMessage::Text(MSG_SYM_INDUSTRY_ENTERTAINMENT);
      case INDUSTRY_INTERNET_CONTENT               : return CMessage::Text(MSG_SYM_INDUSTRY_INTERNET_CONTENT);
      case INDUSTRY_PUBLISHING                     : return CMessage::Text(MSG_SYM_INDUSTRY_PUBLISHING);
      case INDUSTRY_TELECOM                        : return CMessage::Text(MSG_SYM_INDUSTRY_TELECOM);
      case INDUSTRY_APPAREL_MANUFACTURING          : return CMessage::Text(MSG_SYM_INDUSTRY_APPAREL_MANUFACTURING);
      case INDUSTRY_APPAREL_RETAIL                 : return CMessage::Text(MSG_SYM_INDUSTRY_APPAREL_RETAIL);
      case INDUSTRY_AUTO_MANUFACTURERS             : return CMessage::Text(MSG_SYM_INDUSTRY_AUTO_MANUFACTURERS);
      case INDUSTRY_AUTO_PARTS                     : return CMessage::Text(MSG_SYM_INDUSTRY_AUTO_PARTS);
      case INDUSTRY_AUTO_DEALERSHIP                : return CMessage::Text(MSG_SYM_INDUSTRY_AUTO_DEALERSHIP);
      case INDUSTRY_DEPARTMENT_STORES              : return CMessage::Text(MSG_SYM_INDUSTRY_DEPARTMENT_STORES);
      case INDUSTRY_FOOTWEAR_ACCESSORIES           : return CMessage::Text(MSG_SYM_INDUSTRY_FOOTWEAR_ACCESSORIES);
      case INDUSTRY_FURNISHINGS                    : return CMessage::Text(MSG_SYM_INDUSTRY_FURNISHINGS);
      case INDUSTRY_GAMBLING                       : return CMessage::Text(MSG_SYM_INDUSTRY_GAMBLING);
      case INDUSTRY_HOME_IMPROV_RETAIL             : return CMessage::Text(MSG_SYM_INDUSTRY_HOME_IMPROV_RETAIL);
      case INDUSTRY_INTERNET_RETAIL                : return CMessage::Text(MSG_SYM_INDUSTRY_INTERNET_RETAIL);
      case INDUSTRY_LEISURE                        : return CMessage::Text(MSG_SYM_INDUSTRY_LEISURE);
      case INDUSTRY_LODGING                        : return CMessage::Text(MSG_SYM_INDUSTRY_LODGING);
      case INDUSTRY_LUXURY_GOODS                   : return CMessage::Text(MSG_SYM_INDUSTRY_LUXURY_GOODS);
      case INDUSTRY_PACKAGING_CONTAINERS           : return CMessage::Text(MSG_SYM_INDUSTRY_PACKAGING_CONTAINERS);
      case INDUSTRY_PERSONAL_SERVICES              : return CMessage::Text(MSG_SYM_INDUSTRY_PERSONAL_SERVICES);
      case INDUSTRY_RECREATIONAL_VEHICLES          : return CMessage::Text(MSG_SYM_INDUSTRY_RECREATIONAL_VEHICLES);
      case INDUSTRY_RESIDENT_CONSTRUCTION          : return CMessage::Text(MSG_SYM_INDUSTRY_RESIDENT_CONSTRUCTION);
      case INDUSTRY_RESORTS_CASINOS                : return CMessage::Text(MSG_SYM_INDUSTRY_RESORTS_CASINOS);
      case INDUSTRY_RESTAURANTS                    : return CMessage::Text(MSG_SYM_INDUSTRY_RESTAURANTS);
      case INDUSTRY_SPECIALTY_RETAIL               : return CMessage::Text(MSG_SYM_INDUSTRY_SPECIALTY_RETAIL);
      case INDUSTRY_TEXTILE_MANUFACTURING          : return CMessage::Text(MSG_SYM_INDUSTRY_TEXTILE_MANUFACTURING);
      case INDUSTRY_TRAVEL_SERVICES                : return CMessage::Text(MSG_SYM_INDUSTRY_TRAVEL_SERVICES);
      case INDUSTRY_BEVERAGES_BREWERS              : return CMessage::Text(MSG_SYM_INDUSTRY_BEVERAGES_BREWERS);
      case INDUSTRY_BEVERAGES_NON_ALCO             : return CMessage::Text(MSG_SYM_INDUSTRY_BEVERAGES_NON_ALCO);
      case INDUSTRY_BEVERAGES_WINERIES             : return CMessage::Text(MSG_SYM_INDUSTRY_BEVERAGES_WINERIES);
      case INDUSTRY_CONFECTIONERS                  : return CMessage::Text(MSG_SYM_INDUSTRY_CONFECTIONERS);
      case INDUSTRY_DISCOUNT_STORES                : return CMessage::Text(MSG_SYM_INDUSTRY_DISCOUNT_STORES);
      case INDUSTRY_EDUCATION_TRAINIG              : return CMessage::Text(MSG_SYM_INDUSTRY_EDUCATION_TRAINIG);
      case INDUSTRY_FARM_PRODUCTS                  : return CMessage::Text(MSG_SYM_INDUSTRY_FARM_PRODUCTS);
      case INDUSTRY_FOOD_DISTRIBUTION              : return CMessage::Text(MSG_SYM_INDUSTRY_FOOD_DISTRIBUTION);
      case INDUSTRY_GROCERY_STORES                 : return CMessage::Text(MSG_SYM_INDUSTRY_GROCERY_STORES);
      case INDUSTRY_HOUSEHOLD_PRODUCTS             : return CMessage::Text(MSG_SYM_INDUSTRY_HOUSEHOLD_PRODUCTS);
      case INDUSTRY_PACKAGED_FOODS                 : return CMessage::Text(MSG_SYM_INDUSTRY_PACKAGED_FOODS);
      case INDUSTRY_TOBACCO                        : return CMessage::Text(MSG_SYM_INDUSTRY_TOBACCO);
      case INDUSTRY_OIL_GAS_DRILLING               : return CMessage::Text(MSG_SYM_INDUSTRY_OIL_GAS_DRILLING);
      case INDUSTRY_OIL_GAS_EP                     : return CMessage::Text(MSG_SYM_INDUSTRY_OIL_GAS_EP);
      case INDUSTRY_OIL_GAS_EQUIPMENT              : return CMessage::Text(MSG_SYM_INDUSTRY_OIL_GAS_EQUIPMENT);
      case INDUSTRY_OIL_GAS_INTEGRATED             : return CMessage::Text(MSG_SYM_INDUSTRY_OIL_GAS_INTEGRATED);
      case INDUSTRY_OIL_GAS_MIDSTREAM              : return CMessage::Text(MSG_SYM_INDUSTRY_OIL_GAS_MIDSTREAM);
      case INDUSTRY_OIL_GAS_REFINING               : return CMessage::Text(MSG_SYM_INDUSTRY_OIL_GAS_REFINING);
      case INDUSTRY_THERMAL_COAL                   : return CMessage::Text(MSG_SYM_INDUSTRY_THERMAL_COAL);
      case INDUSTRY_URANIUM                        : return CMessage::Text(MSG_SYM_INDUSTRY_URANIUM);
      case INDUSTRY_EXCHANGE_TRADED_FUND           : return CMessage::Text(MSG_SYM_INDUSTRY_EXCHANGE_TRADED_FUND);
      case INDUSTRY_ASSETS_MANAGEMENT              : return CMessage::Text(MSG_SYM_INDUSTRY_ASSETS_MANAGEMENT);
      case INDUSTRY_BANKS_DIVERSIFIED              : return CMessage::Text(MSG_SYM_INDUSTRY_BANKS_DIVERSIFIED);
      case INDUSTRY_BANKS_REGIONAL                 : return CMessage::Text(MSG_SYM_INDUSTRY_BANKS_REGIONAL);
      case INDUSTRY_CAPITAL_MARKETS                : return CMessage::Text(MSG_SYM_INDUSTRY_CAPITAL_MARKETS);
      case INDUSTRY_CLOSE_END_FUND_DEBT            : return CMessage::Text(MSG_SYM_INDUSTRY_CLOSE_END_FUND_DEBT);
      case INDUSTRY_CLOSE_END_FUND_EQUITY          : return CMessage::Text(MSG_SYM_INDUSTRY_CLOSE_END_FUND_EQUITY);
      case INDUSTRY_CLOSE_END_FUND_FOREIGN         : return CMessage::Text(MSG_SYM_INDUSTRY_CLOSE_END_FUND_FOREIGN);
      case INDUSTRY_CREDIT_SERVICES                : return CMessage::Text(MSG_SYM_INDUSTRY_CREDIT_SERVICES);
      case INDUSTRY_FINANCIAL_CONGLOMERATE         : return CMessage::Text(MSG_SYM_INDUSTRY_FINANCIAL_CONGLOMERATE);
      case INDUSTRY_FINANCIAL_DATA_EXCHANGE        : return CMessage::Text(MSG_SYM_INDUSTRY_FINANCIAL_DATA_EXCHANGE);
      case INDUSTRY_INSURANCE_BROKERS              : return CMessage::Text(MSG_SYM_INDUSTRY_INSURANCE_BROKERS);
      case INDUSTRY_INSURANCE_DIVERSIFIED          : return CMessage::Text(MSG_SYM_INDUSTRY_INSURANCE_DIVERSIFIED);
      case INDUSTRY_INSURANCE_LIFE                 : return CMessage::Text(MSG_SYM_INDUSTRY_INSURANCE_LIFE);
      case INDUSTRY_INSURANCE_PROPERTY             : return CMessage::Text(MSG_SYM_INDUSTRY_INSURANCE_PROPERTY);
      case INDUSTRY_INSURANCE_REINSURANCE          : return CMessage::Text(MSG_SYM_INDUSTRY_INSURANCE_REINSURANCE);
      case INDUSTRY_INSURANCE_SPECIALTY            : return CMessage::Text(MSG_SYM_INDUSTRY_INSURANCE_SPECIALTY);
      case INDUSTRY_MORTGAGE_FINANCE               : return CMessage::Text(MSG_SYM_INDUSTRY_MORTGAGE_FINANCE);
      case INDUSTRY_SHELL_COMPANIES                : return CMessage::Text(MSG_SYM_INDUSTRY_SHELL_COMPANIES);
      case INDUSTRY_BIOTECHNOLOGY                  : return CMessage::Text(MSG_SYM_INDUSTRY_BIOTECHNOLOGY);
      case INDUSTRY_DIAGNOSTICS_RESEARCH           : return CMessage::Text(MSG_SYM_INDUSTRY_DIAGNOSTICS_RESEARCH);
      case INDUSTRY_DRUGS_MANUFACTURERS            : return CMessage::Text(MSG_SYM_INDUSTRY_DRUGS_MANUFACTURERS);
      case INDUSTRY_DRUGS_MANUFACTURERS_SPEC       : return CMessage::Text(MSG_SYM_INDUSTRY_DRUGS_MANUFACTURERS_SPEC);
      case INDUSTRY_HEALTHCARE_PLANS               : return CMessage::Text(MSG_SYM_INDUSTRY_HEALTHCARE_PLANS);
      case INDUSTRY_HEALTH_INFORMATION             : return CMessage::Text(MSG_SYM_INDUSTRY_HEALTH_INFORMATION);
      case INDUSTRY_MEDICAL_FACILITIES             : return CMessage::Text(MSG_SYM_INDUSTRY_MEDICAL_FACILITIES);
      case INDUSTRY_MEDICAL_DEVICES                : return CMessage::Text(MSG_SYM_INDUSTRY_MEDICAL_DEVICES);
      case INDUSTRY_MEDICAL_DISTRIBUTION           : return CMessage::Text(MSG_SYM_INDUSTRY_MEDICAL_DISTRIBUTION);
      case INDUSTRY_MEDICAL_INSTRUMENTS            : return CMessage::Text(MSG_SYM_INDUSTRY_MEDICAL_INSTRUMENTS);
      case INDUSTRY_PHARM_RETAILERS                : return CMessage::Text(MSG_SYM_INDUSTRY_PHARM_RETAILERS);
      case INDUSTRY_AEROSPACE_DEFENSE              : return CMessage::Text(MSG_SYM_INDUSTRY_AEROSPACE_DEFENSE);
      case INDUSTRY_AIRLINES                       : return CMessage::Text(MSG_SYM_INDUSTRY_AIRLINES);
      case INDUSTRY_AIRPORTS_SERVICES              : return CMessage::Text(MSG_SYM_INDUSTRY_AIRPORTS_SERVICES);
      case INDUSTRY_BUILDING_PRODUCTS              : return CMessage::Text(MSG_SYM_INDUSTRY_BUILDING_PRODUCTS);
      case INDUSTRY_BUSINESS_EQUIPMENT             : return CMessage::Text(MSG_SYM_INDUSTRY_BUSINESS_EQUIPMENT);
      case INDUSTRY_CONGLOMERATES                  : return CMessage::Text(MSG_SYM_INDUSTRY_CONGLOMERATES);
      case INDUSTRY_CONSULTING_SERVICES            : return CMessage::Text(MSG_SYM_INDUSTRY_CONSULTING_SERVICES);
      case INDUSTRY_ELECTRICAL_EQUIPMENT           : return CMessage::Text(MSG_SYM_INDUSTRY_ELECTRICAL_EQUIPMENT);
      case INDUSTRY_ENGINEERING_CONSTRUCTION       : return CMessage::Text(MSG_SYM_INDUSTRY_ENGINEERING_CONSTRUCTION);
      case INDUSTRY_FARM_HEAVY_MACHINERY           : return CMessage::Text(MSG_SYM_INDUSTRY_FARM_HEAVY_MACHINERY);
      case INDUSTRY_INDUSTRIAL_DISTRIBUTION        : return CMessage::Text(MSG_SYM_INDUSTRY_INDUSTRIAL_DISTRIBUTION);
      case INDUSTRY_INFRASTRUCTURE_OPERATIONS      : return CMessage::Text(MSG_SYM_INDUSTRY_INFRASTRUCTURE_OPERATIONS);
      case INDUSTRY_FREIGHT_LOGISTICS              : return CMessage::Text(MSG_SYM_INDUSTRY_FREIGHT_LOGISTICS);
      case INDUSTRY_MARINE_SHIPPING                : return CMessage::Text(MSG_SYM_INDUSTRY_MARINE_SHIPPING);
      case INDUSTRY_METAL_FABRICATION              : return CMessage::Text(MSG_SYM_INDUSTRY_METAL_FABRICATION);
      case INDUSTRY_POLLUTION_CONTROL              : return CMessage::Text(MSG_SYM_INDUSTRY_POLLUTION_CONTROL);
      case INDUSTRY_RAILROADS                      : return CMessage::Text(MSG_SYM_INDUSTRY_RAILROADS);
      case INDUSTRY_RENTAL_LEASING                 : return CMessage::Text(MSG_SYM_INDUSTRY_RENTAL_LEASING);
      case INDUSTRY_SECURITY_PROTECTION            : return CMessage::Text(MSG_SYM_INDUSTRY_SECURITY_PROTECTION);
      case INDUSTRY_SPEALITY_BUSINESS_SERVICES     : return CMessage::Text(MSG_SYM_INDUSTRY_SPEALITY_BUSINESS_SERVICES);
      case INDUSTRY_SPEALITY_MACHINERY             : return CMessage::Text(MSG_SYM_INDUSTRY_SPEALITY_MACHINERY);
      case INDUSTRY_STUFFING_EMPLOYMENT            : return CMessage::Text(MSG_SYM_INDUSTRY_STUFFING_EMPLOYMENT);
      case INDUSTRY_TOOLS_ACCESSORIES              : return CMessage::Text(MSG_SYM_INDUSTRY_TOOLS_ACCESSORIES);
      case INDUSTRY_TRUCKING                       : return CMessage::Text(MSG_SYM_INDUSTRY_TRUCKING);
      case INDUSTRY_WASTE_MANAGEMENT               : return CMessage::Text(MSG_SYM_INDUSTRY_WASTE_MANAGEMENT);
      case INDUSTRY_REAL_ESTATE_DEVELOPMENT        : return CMessage::Text(MSG_SYM_INDUSTRY_REAL_ESTATE_DEVELOPMENT);
      case INDUSTRY_REAL_ESTATE_DIVERSIFIED        : return CMessage::Text(MSG_SYM_INDUSTRY_REAL_ESTATE_DIVERSIFIED);
      case INDUSTRY_REAL_ESTATE_SERVICES           : return CMessage::Text(MSG_SYM_INDUSTRY_REAL_ESTATE_SERVICES);
      case INDUSTRY_REIT_DIVERSIFIED               : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_DIVERSIFIED);
      case INDUSTRY_REIT_HEALTCARE                 : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_HEALTCARE);
      case INDUSTRY_REIT_HOTEL_MOTEL               : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_HOTEL_MOTEL);
      case INDUSTRY_REIT_INDUSTRIAL                : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_INDUSTRIAL);
      case INDUSTRY_REIT_MORTAGE                   : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_MORTAGE);
      case INDUSTRY_REIT_OFFICE                    : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_OFFICE);
      case INDUSTRY_REIT_RESIDENTAL                : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_RESIDENTAL);
      case INDUSTRY_REIT_RETAIL                    : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_RETAIL);
      case INDUSTRY_REIT_SPECIALITY                : return CMessage::Text(MSG_SYM_INDUSTRY_REIT_SPECIALITY);
      case INDUSTRY_COMMUNICATION_EQUIPMENT        : return CMessage::Text(MSG_SYM_INDUSTRY_COMMUNICATION_EQUIPMENT);
      case INDUSTRY_COMPUTER_HARDWARE              : return CMessage::Text(MSG_SYM_INDUSTRY_COMPUTER_HARDWARE);
      case INDUSTRY_CONSUMER_ELECTRONICS           : return CMessage::Text(MSG_SYM_INDUSTRY_CONSUMER_ELECTRONICS);
      case INDUSTRY_ELECTRONIC_COMPONENTS          : return CMessage::Text(MSG_SYM_INDUSTRY_ELECTRONIC_COMPONENTS);
      case INDUSTRY_ELECTRONIC_DISTRIBUTION        : return CMessage::Text(MSG_SYM_INDUSTRY_ELECTRONIC_DISTRIBUTION);
      case INDUSTRY_IT_SERVICES                    : return CMessage::Text(MSG_SYM_INDUSTRY_IT_SERVICES);
      case INDUSTRY_SCIENTIFIC_INSTRUMENTS         : return CMessage::Text(MSG_SYM_INDUSTRY_SCIENTIFIC_INSTRUMENTS);
      case INDUSTRY_SEMICONDUCTOR_EQUIPMENT        : return CMessage::Text(MSG_SYM_INDUSTRY_SEMICONDUCTOR_EQUIPMENT);
      case INDUSTRY_SEMICONDUCTORS                 : return CMessage::Text(MSG_SYM_INDUSTRY_SEMICONDUCTORS);
      case INDUSTRY_SOFTWARE_APPLICATION           : return CMessage::Text(MSG_SYM_INDUSTRY_SOFTWARE_APPLICATION);
      case INDUSTRY_SOFTWARE_INFRASTRUCTURE        : return CMessage::Text(MSG_SYM_INDUSTRY_SOFTWARE_INFRASTRUCTURE);
      case INDUSTRY_SOLAR                          : return CMessage::Text(MSG_SYM_INDUSTRY_SOLAR);
      case INDUSTRY_UTILITIES_DIVERSIFIED          : return CMessage::Text(MSG_SYM_INDUSTRY_UTILITIES_DIVERSIFIED);
      case INDUSTRY_UTILITIES_POWERPRODUCERS       : return CMessage::Text(MSG_SYM_INDUSTRY_UTILITIES_POWERPRODUCERS);
      case INDUSTRY_UTILITIES_RENEWABLE            : return CMessage::Text(MSG_SYM_INDUSTRY_UTILITIES_RENEWABLE);
      case INDUSTRY_UTILITIES_REGULATED_ELECTRIC   : return CMessage::Text(MSG_SYM_INDUSTRY_UTILITIES_REGULATED_ELECTRIC);
      case INDUSTRY_UTILITIES_REGULATED_GAS        : return CMessage::Text(MSG_SYM_INDUSTRY_UTILITIES_REGULATED_GAS);
      case INDUSTRY_UTILITIES_REGULATED_WATER      : return CMessage::Text(MSG_SYM_INDUSTRY_UTILITIES_REGULATED_WATER);
      default                                      : return CMessage::Text(MSG_SYM_INDUSTRY_UNDEFINED);
     }
  }
//+------------------------------------------------------------------+

Метод аналогичен вышерассмотренному, но проверяется значение, возвращаемое методом Industry(), в соответствии с его значением и возвращается нужная строка текста.

В статье 73 мы написали класс состояния мышки. Просто поправим название метода в файле \MQL5\Include\DoEasy\Services\MouseState.mqh.

ButtKeyState() переименуем в ButtonKeyState():

//--- Возвращает (1-2) кординаты курсора, (3) значение прокрутки колёсика, (4) состояние кнопок мыши и клавиш Shift и Ctrl
   int               CoordX(void)                        const { return this.m_coord_x;            }
   int               CoordY(void)                        const { return this.m_coord_y;            }
   int               DeltaWheel(void)                    const { return this.m_delta_wheel;        }
   ENUM_MOUSE_BUTT_KEY_STATE ButtonKeyState(const int id,const long lparam,const double dparam,const string flags);

...

//+------------------------------------------------------------------+
//| Возвращает состояние кнопок мыши и клавиш Shift и Ctrl           |
//+------------------------------------------------------------------+
ENUM_MOUSE_BUTT_KEY_STATE CMouseState::ButtonKeyState(const int id,const long lparam,const double dparam,const string flags)
  {
   this.SetButtonKeyState(id,lparam,dparam,(ushort)flags);
   return (ENUM_MOUSE_BUTT_KEY_STATE)this.m_state_flags;
  }
//+------------------------------------------------------------------+

В общем-то тут, наверное, просто во мне вдруг возмутился внутренний перфекционист :)

В приватной секции ещё дописал в табличку hex-значения битов, описывающих состояния кнопок мышки:

//+------------------------------------------------------------------+
//| Класс состояний мышки                                            |
//+------------------------------------------------------------------+
class CMouseState
  {
private:
   int               m_coord_x;                             // Координата X
   int               m_coord_y;                             // Координата Y
   int               m_delta_wheel;                         // Значение прокрутки колёсика мыши
   int               m_window_num;                          // Номер подокна
   long              m_chart_id;                            // Идентификатор графика
   ushort            m_state_flags;                         // Флаги состояний
   
//--- Устанавливает состояние кнопок мыши и клавиш Shift и Ctrl
   void              SetButtonKeyState(const int id,const long lparam,const double dparam,const ushort flags);
//--- Устанавливает флаги состояний кнопок мыши и клавиш
   void              SetButtKeyFlags(const short flags);
//--- Расположение данных в ushort-значении состояния кнопок
   //---------------------------------------------------------------------------
   //   bit    |    byte   |            state            |    dec    |   hex   |
   //---------------------------------------------------------------------------
   //    0     |     0     | левая кнопка мыши           |     1     |    1    |
   //---------------------------------------------------------------------------
   //    1     |     0     | правая кнопка мыши          |     2     |    2    |
   //---------------------------------------------------------------------------
   //    2     |     0     | клавиша SHIFT               |     4     |    4    |
   //---------------------------------------------------------------------------
   //    3     |     0     | клавиша CTRL                |     8     |    8    |
   //---------------------------------------------------------------------------
   //    4     |     0     | средняя кнопка мыши         |    16     |   10    |
   //---------------------------------------------------------------------------
   //    5     |     0     | 1 доп. кнопка мыши          |    32     |   20    |
   //---------------------------------------------------------------------------
   //    6     |     0     | 2 доп. кнопка мыши          |    64     |   40    |
   //---------------------------------------------------------------------------
   //    7     |     0     | прокрутка колёсика          |    128    |   80    |
   //---------------------------------------------------------------------------
   //---------------------------------------------------------------------------
   //    0     |     1     | курсор внутри формы         |    256    |   100   |
   //---------------------------------------------------------------------------
   //    1     |     1     | курсор внутри активной зоны |    512    |   200   |
   //---------------------------------------------------------------------------
   //    2     |     1     | курсор в области управления |   1024    |   400   |
   //---------------------------------------------------------------------------
   //    3     |     1     | курсор в области прокрутки  |   2048    |   800   |
   //---------------------------------------------------------------------------
   //    4     |     1     | курсор на левой грани       |   4096    |  1000   |
   //---------------------------------------------------------------------------
   //    5     |     1     | курсор на нижней грани      |   8192    |  2000   |
   //---------------------------------------------------------------------------
   //    6     |     1     | курсор на правой грани      |   16384   |  4000   |
   //---------------------------------------------------------------------------
   //    7     |     1     | курсор на верхней грани     |   32768   |  8000   |
   //---------------------------------------------------------------------------
      
public:


Исправим ошибки в классе базового объекта всех графических объектов библиотеки. При создании такого объекта префикс имени, хранящий в себе наименование программы, ошибочно устанавливался как пустая строка в конструкторе класса:

//+------------------------------------------------------------------+
//| Конструктор                                                      |
//+------------------------------------------------------------------+
CGBaseObj::CGBaseObj() : m_shift_y(0),m_visible(false), m_name_prefix(::MQLInfoString(MQL_PROGRAM_NAME)+"_"),m_belong(GRAPH_OBJ_BELONG_PROGRAM)
  {
   this.m_list_events.Clear();                  // Очистка списка событий
   this.m_list_events.Sort();                   // Флаг сортированного списка
   this.m_type=OBJECT_DE_TYPE_GBASE;            // Тип объекта
   this.m_type_graph_obj=WRONG_VALUE;           // Тип графического объекта
   this.m_type_element=WRONG_VALUE;             // Тип графического элемента
   this.m_belong=WRONG_VALUE;                   // Принадлежность программе/терминалу
   this.m_group=0;                              // Группа графических объектов
   this.m_name_prefix="";                       // Префикс имени объекта
   this.m_name="";                              // Имя объекта
   this.m_chart_id=0;                           // Идентификатор графика объекта
   this.m_object_id=0;                          // Идентификатор объекта
   this.m_zorder=0;                             // Приоритет графического объекта на получение события нажатия мышки
   this.m_subwindow=0;                          // Номер подокна
   this.m_shift_y=0;                            // Смещение координаты Y для подокна
   this.m_timeframes_visible=OBJ_ALL_PERIODS;   // Видимость объекта на таймфреймах (набор флагов)
   this.m_visible=true;                         // Видимость объекта
   this.m_back=false;                           // Флаг "Объект на заднем плане"
   this.m_selected=false;                       // Флаг "Выделенность объекта"
   this.m_selectable=false;                     // Флаг "Доступность объекта"
   this.m_hidden=true;                          // Флаг "Запрет на показ имени графического объекта в списке объектов терминала"
   this.m_create_time=0;                        // Время создания объекта
  }
//+------------------------------------------------------------------+

Сначала здесь в списке инициализации устанавливается для префикса правильное значение, а далее — в теле конструктора это значение устанавливалось как пустая строка, что приводило к некоторым ошибкам идентификации графических объектов при работе с ними.

Удалим эту строку и уберём из списка инициализации установку смещения и флага видимости, так как они устанавливаются в теле конструктора:

//+------------------------------------------------------------------+
//| Конструктор                                                      |
//+------------------------------------------------------------------+
CGBaseObj::CGBaseObj() : m_name_prefix(::MQLInfoString(MQL_PROGRAM_NAME)+"_"),m_belong(GRAPH_OBJ_BELONG_PROGRAM)
  {
   this.m_list_events.Clear();                  // Очистка списка событий
   this.m_list_events.Sort();                   // Флаг сортированного списка
   this.m_type=OBJECT_DE_TYPE_GBASE;            // Тип объекта
   this.m_type_graph_obj=WRONG_VALUE;           // Тип графического объекта
   this.m_type_element=WRONG_VALUE;             // Тип графического элемента
   this.m_belong=WRONG_VALUE;                   // Принадлежность программе/терминалу
   this.m_group=0;                              // Группа графических объектов
   this.m_name="";                              // Имя объекта
   this.m_chart_id=0;                           // Идентификатор графика объекта
   this.m_object_id=0;                          // Идентификатор объекта
   this.m_zorder=0;                             // Приоритет графического объекта на получение события нажатия мышки
   this.m_subwindow=0;                          // Номер подокна
   this.m_shift_y=0;                            // Смещение координаты Y для подокна
   this.m_timeframes_visible=OBJ_ALL_PERIODS;   // Видимость объекта на таймфреймах (набор флагов)
   this.m_visible=true;                         // Видимость объекта
   this.m_back=false;                           // Флаг "Объект на заднем плане"
   this.m_selected=false;                       // Флаг "Выделенность объекта"
   this.m_selectable=false;                     // Флаг "Доступность объекта"
   this.m_hidden=true;                          // Флаг "Запрет на показ имени графического объекта в списке объектов терминала"
   this.m_create_time=0;                        // Время создания объекта
  }
//+------------------------------------------------------------------+


В публичной секции класса напишем метод, возвращающий префикс имени графического объекта:

//--- Добавляет объект события в список событий
   bool              AddEvent(CGBaseEvent *event)              { return this.m_list_events.Add(event);}
//--- Очищает список событий
   void              ClearEventsList(void)                     { this.m_list_events.Clear();          }
//--- Возвращает количество событий в списке
   int               EventsTotal(void)                         { return this.m_list_events.Total();   }

public:
//--- Возвращает префикс имени
   string            NamePrefix(void)                    const { return this.m_name_prefix;           }
//--- Установка значений переменных класса
   void              SetObjectID(const long value)             { this.m_object_id=value;              }
   void              SetBelong(const ENUM_GRAPH_OBJ_BELONG belong){ this.m_belong=belong;             }
   void              SetTypeGraphObject(const ENUM_OBJECT obj) { this.m_type_graph_obj=obj;           }
   void              SetTypeElement(const ENUM_GRAPH_ELEMENT_TYPE type) { this.m_type_element=type;   }
   void              SetSpecies(const ENUM_GRAPH_OBJ_SPECIES species){ this.m_species=species;        }
   void              SetGroup(const int group)                 { this.m_group=group;                  }
   void              SetName(const string name)                { this.m_name=name;                    }
   void              SetChartID(const long chart_id)           { this.m_chart_id=chart_id;            }
   void              SetDigits(const int value)                { this.m_digits=value;                 }


Доработаем класс объекта графического элемента на канвасе в файле \MQL5\Include\DoEasy\Objects\Graph\GCnvElement.mqh.

Здесь тоже были допущены некоторые ошибки, и нам нужно добавить методы для работы с новым свойством "Взаимодействие".

Методы, возвращающие положение курсора относительно всего элемента, либо его активной зоны, переместим из защищённой секции в публичную:

//+------------------------------------------------------------------+
//| Класс объекта графического элемента                              |
//+------------------------------------------------------------------+
class CGCnvElement : public CGBaseObj
  {
protected:
   CCanvas           m_canvas;                                 // Объект класса CCanvas
   CPause            m_pause;                                  // Объект класса "Пауза"
   bool              m_shadow;                                 // Наличие тени
   color             m_chart_color_bg;                         // Цвет фона графика
   uint              m_duplicate_res[];                        // Массив для хранения копии данных ресурса

//--- Возвращает положение курсора относительно (1) всего элемента, (2) активной зоны элемента
   bool              CursorInsideElement(const int x,const int y);
   bool              CursorInsideActiveArea(const int x,const int y);
//--- Создаёт (1) структуру объекта, (2) объект из структуры
   virtual bool      ObjectToStruct(void);
   virtual void      StructToObject(void);
   
private:
//--- (1) Сохраняет графический ресурс в массив, (2) восстанавливает ресурс из массива
   bool              ResourceStamp(const string source);
   virtual bool      Reset(void);
   
//--- Возвращает положение курсора относительно (1) всего элемента, (2) активной зоны элемента
   bool              CursorInsideElement(const int x,const int y);
   bool              CursorInsideActiveArea(const int x,const int y);

//--- Создаёт элемент
   bool              Create(const long chart_id,
                            const int wnd_num,
                            const string name,
                            const int x,
                            const int y,
                            const int w,
                            const int h,
                            const color colour,
                            const uchar opacity,
                            const bool redraw=false);
                                
//--- Возвращает указатель на объект-канвас

Они нам потребуются для управления объектом извне в классе-коллекции графических элементов.

В приватной секции класса в структуру, хранящую в себе свойства объекта для сохранения его на носителе и чтения с него, добавим новое свойство:

//+------------------------------------------------------------------+
//| Класс объекта графического элемента                              |
//+------------------------------------------------------------------+
class CGCnvElement : public CGBaseObj
  {
protected:
   CCanvas           m_canvas;                                 // Объект класса CCanvas
   CPause            m_pause;                                  // Объект класса "Пауза"
   bool              m_shadow;                                 // Наличие тени
   color             m_chart_color_bg;                         // Цвет фона графика
   uint              m_duplicate_res[];                        // Массив для хранения копии данных ресурса

//--- Создаёт (1) структуру объекта, (2) объект из структуры
   virtual bool      ObjectToStruct(void);
   virtual void      StructToObject(void);
   
private:
   struct SData
     {
      //--- Целочисленные свойства объекта
      int            id;                                       // Идентификатор элемента
      int            type;                                     // Тип графического элемента
      int            number;                                   // Номер элемента в списке
      long           chart_id;                                 // Идентификатор графика
      int            subwindow;                                // Номер подокна графика
      int            coord_x;                                  // X-координата формы на графике
      int            coord_y;                                  // Y-координата формы на графике
      int            width;                                    // Ширина элемента
      int            height;                                   // Высота элемента
      int            edge_right;                               // Правая граница элемента
      int            edge_bottom;                              // Нижняя граница элемента
      int            act_shift_left;                           // Отступ активной зоны от левого края элемента
      int            act_shift_top;                            // Отступ активной зоны от верхнего края элемента
      int            act_shift_right;                          // Отступ активной зоны от правого края элемента
      int            act_shift_bottom;                         // Отступ активной зоны от нижнего края элемента
      uchar          opacity;                                  // Непрозрачность элемента
      color          color_bg;                                 // Цвет фона элемента
      bool           movable;                                  // Флаг перемещаемости элемента
      bool           active;                                   // Флаг активности элемента
      bool           interaction;                              // Флаг взаимодействия элемента с внешней средой
      int            coord_act_x;                              // X-координата активной зоны элемента
      int            coord_act_y;                              // Y-координата активной зоны элемента
      int            coord_act_right;                          // Правая граница активной зоны элемента
      int            coord_act_bottom;                         // Нижняя граница активной зоны элемента
      //--- Вещественные свойства объекта

      //--- Строковые свойства объекта
      uchar          name_obj[64];                             // Имя объекта-графического элемента
      uchar          name_res[64];                             // Имя графического ресурса
     };
   SData             m_struct_obj;                             // Структура объекта
   uchar             m_uchar_array[];                          // uchar-массив структуры объекта
   
   long              m_long_prop[ORDER_PROP_INTEGER_TOTAL];    // Целочисленные свойства
   double            m_double_prop[ORDER_PROP_DOUBLE_TOTAL];   // Вещественные свойства
   string            m_string_prop[ORDER_PROP_STRING_TOTAL];   // Строковые свойства


В публичной секции класса объявим виртуальный обработчик событий:

protected:
//--- Защищённый конструктор
                     CGCnvElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                                  const long    chart_id,
                                  const int     wnd_num,
                                  const string  name,
                                  const int     x,
                                  const int     y,
                                  const int     w,
                                  const int     h);
public:
//--- Обработчик событий
   virtual void      OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam);
//--- Параметрический конструктор
                     CGCnvElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                                  const int     element_id,
                                  const int     element_num,
                                  const long    chart_id,
                                  const int     wnd_num,
                                  const string  name,
                                  const int     x,
                                  const int     y,
                                  const int     w,
                                  const int     h,
                                  const color   colour,
                                  const uchar   opacity,
                                  const bool    movable=true,
                                  const bool    activity=true,
                                  const bool    redraw=false);
//--- Конструктор по умолчанию/Деструктор
                     CGCnvElement() : m_shadow(false),m_chart_color_bg((color)::ChartGetInteger(::ChartID(),CHART_COLOR_BACKGROUND))
                        { this.m_type=OBJECT_DE_TYPE_GELEMENT; }
                    ~CGCnvElement()
                        { this.m_canvas.Destroy();             }

Так как от этого объекта далее будут наследоваться другие, в частности — объект-форма, то и обработчик событий нам нужен виртуальный. В списке-коллекции графических элементов будут храниться объекты класса с типом CGCnvElement, но в него так же можно будет помещать и его наследников. Соответственно, при получении из списка объекта класса CForm, при обращении к его обработчику событий будет вызван именно обработчик класса CForm потому, что в нём так же будет виртуальный обработчик событий.

В блоке методов для упрощённого доступа к свойствам объекта напишем два новых метода для работы со свойством "Взаимодействие":

//+------------------------------------------------------------------+
//| Методы упрощённого доступа к свойствам объекта                   |
//+------------------------------------------------------------------+
//--- Устанавливает координату (1) X, (2) Y, (3) ширину, (4) высоту, (5) правый, (6) нижний край элемента,
   bool              SetCoordX(const int coord_x);
   bool              SetCoordY(const int coord_y);
   bool              SetWidth(const int width);
   bool              SetHeight(const int height);
   void              SetRightEdge(void)                        { this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.RightEdge());           }
   void              SetBottomEdge(void)                       { this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.BottomEdge());         }
//--- Устанавливает смещение (1) левого, (2) верхнего, (3) правого, (4) нижнего края активной зоны относительно элемента,
//--- (5) все смещения краёв активной зоны относительно элемента, (6) цвет фона элемента, (7) непрозрачность
   void              SetActiveAreaLeftShift(const int value)   { this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,fabs(value));       }
   void              SetActiveAreaRightShift(const int value)  { this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,fabs(value));      }
   void              SetActiveAreaTopShift(const int value)    { this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,fabs(value));        }
   void              SetActiveAreaBottomShift(const int value) { this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,fabs(value));     }
   void              SetActiveAreaShift(const int left_shift,const int bottom_shift,const int right_shift,const int top_shift);
   void              SetColorBackground(const color colour)    { this.m_color_bg=colour;                                               }
   void              SetOpacity(const uchar value,const bool redraw=false);

//--- Устанавливает флаг (1) перемещаемости, (2) активности объекта, (3) идентификатор элемента, (4) номер элемента в списке, (5) наличие тени
   void              SetMovable(const bool flag)               { this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,flag);                     }
   void              SetActive(const bool flag)                { this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,flag);                      }
   void              SetInteraction(const bool flag)           { this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,flag);                 }
   void              SetID(const int id)                       { this.SetProperty(CANV_ELEMENT_PROP_ID,id);                            }
   void              SetNumber(const int number)               { this.SetProperty(CANV_ELEMENT_PROP_NUM,number);                       }
   void              SetShadow(const bool flag)                { this.m_shadow=flag;                                                   }
   
//--- Возвращает смещение (1) левого, (2) правого, (3) верхнего, (4) нижнего края активной зоны элемента
   int               ActiveAreaLeftShift(void)           const { return (int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT);       }
   int               ActiveAreaRightShift(void)          const { return (int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT);      }
   int               ActiveAreaTopShift(void)            const { return (int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP);        }
   int               ActiveAreaBottomShift(void)         const { return (int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM);     }
//--- Возвращает координату (1) левого, (2) правого, (3) верхнего, (4) нижнего края активной зоны элемента
   int               ActiveAreaLeft(void)                const { return int(this.CoordX()+this.ActiveAreaLeftShift());                 }
   int               ActiveAreaRight(void)               const { return int(this.RightEdge()-this.ActiveAreaRightShift());             }
   int               ActiveAreaTop(void)                 const { return int(this.CoordY()+this.ActiveAreaTopShift());                  }
   int               ActiveAreaBottom(void)              const { return int(this.BottomEdge()-this.ActiveAreaBottomShift());           }
//--- Возвращает (1) цвет фона, (2) непрозрачность, координату (3) правого, (4) нижнего края элемента
   color             ColorBackground(void)               const { return this.m_color_bg;                                               }
   uchar             Opacity(void)                       const { return this.m_opacity;                                                }
   int               RightEdge(void)                     const { return this.CoordX()+this.m_canvas.Width();                           }
   int               BottomEdge(void)                    const { return this.CoordY()+this.m_canvas.Height();                          }
//--- Возвращает координату (1) X, (2) Y, (3) ширину, (4) высоту элемента,
   int               CoordX(void)                        const { return (int)this.GetProperty(CANV_ELEMENT_PROP_COORD_X);              }
   int               CoordY(void)                        const { return (int)this.GetProperty(CANV_ELEMENT_PROP_COORD_Y);              }
   int               Width(void)                         const { return (int)this.GetProperty(CANV_ELEMENT_PROP_WIDTH);                }
   int               Height(void)                        const { return (int)this.GetProperty(CANV_ELEMENT_PROP_HEIGHT);               }
//--- Возвращает флаг (1) перемещаемости, (2) активности элемента
   bool              Movable(void)                       const { return (bool)this.GetProperty(CANV_ELEMENT_PROP_MOVABLE);             }
   bool              Active(void)                        const { return (bool)this.GetProperty(CANV_ELEMENT_PROP_ACTIVE);              }
   bool              Interaction(void)                   const { return (bool)this.GetProperty(CANV_ELEMENT_PROP_INTERACTION);         }
//--- Возвращает (1) имя объекта, (2) имя графического ресурса, (3) идентификатор графика, (4) номер подокна графика
   string            NameObj(void)                       const { return this.GetProperty(CANV_ELEMENT_PROP_NAME_OBJ);                  }
   string            NameRes(void)                       const { return this.GetProperty(CANV_ELEMENT_PROP_NAME_RES);                  }
   long              ChartID(void)                       const { return this.GetProperty(CANV_ELEMENT_PROP_CHART_ID);                  }
   int               WindowNum(void)                     const { return (int)this.GetProperty(CANV_ELEMENT_PROP_WND_NUM);              }
//--- Возвращает (1) идентификатор элемента, (2) номер элемента в списке, (3) флаг наличия тени у формы, (4) цвет фона чарта
   int               ID(void)                            const { return (int)this.GetProperty(CANV_ELEMENT_PROP_ID);                   }
   int               Number(void)                        const { return (int)this.GetProperty(CANV_ELEMENT_PROP_NUM);                  }
   bool              IsShadow(void)                      const { return this.m_shadow;                                                 }
   color             ChartColorBackground(void)          const { return this.m_chart_color_bg;                                         }
//--- Устанавливает объект выше всех
   void              BringToTop(void)                          { CGBaseObj::SetVisible(false,false); CGBaseObj::SetVisible(true,false);}
//--- (1) Показывает, (2) скрывает элемент
   virtual void      Show(void)                                { CGBaseObj::SetVisible(true,false);                                    }
   virtual void      Hide(void)                                { CGBaseObj::SetVisible(false,false);                                   }
   
//+------------------------------------------------------------------+
//| Методы получения растровых данных                                |
//+------------------------------------------------------------------+


В параметрическом конструкторе добавим проверку наличия в строке имени, переданного в параметрах конструктора, подстроки с наименованием программы. Если нет подстроки, то к имени, переданном в метод, прибавляется наименование программы как префикс имени объекта, если же есть, то к имени ничего не прибавляем. Таким образом мы, при создании имени объекта, избежим задвоения префикса имени объекта в случае, если он уже был передан в параметрах конструктора в составе имени в переменной name:

//+------------------------------------------------------------------+
//| Параметрический конструктор                                      |
//+------------------------------------------------------------------+
CGCnvElement::CGCnvElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                           const int      element_id,
                           const int      element_num,
                           const long     chart_id,
                           const int      wnd_num,
                           const string   name,
                           const int      x,
                           const int      y,
                           const int      w,
                           const int      h,
                           const color    colour,
                           const uchar    opacity,
                           const bool     movable=true,
                           const bool     activity=true,
                           const bool     redraw=false) : m_shadow(false)
  {
   this.m_type=OBJECT_DE_TYPE_GELEMENT; 
   this.m_chart_color_bg=(color)::ChartGetInteger(chart_id,CHART_COLOR_BACKGROUND);
   this.m_name=(::StringFind(name,this.m_name_prefix)<0 ? this.m_name_prefix : "")+name;
   this.m_chart_id=chart_id;
   this.m_subwindow=wnd_num;
   this.m_type_element=element_type;
   this.SetFont("Calibri",8);
   this.m_text_anchor=0;
   this.m_text_x=0;
   this.m_text_y=0;
   this.m_color_bg=colour;
   this.m_opacity=opacity;
   if(this.Create(chart_id,wnd_num,this.m_name,x,y,w,h,colour,opacity,redraw))
     {
      this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,this.m_canvas.ResourceName()); // Имя графического ресурса
      this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,CGBaseObj::ChartID());         // Идентификатор графика
      this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,CGBaseObj::SubWindow());        // Номер подокна графика
      this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,CGBaseObj::Name());            // Имя объекта-элемента
      this.SetProperty(CANV_ELEMENT_PROP_TYPE,element_type);                     // Тип графического элемента
      this.SetProperty(CANV_ELEMENT_PROP_ID,element_id);                         // Идентификатор элемента
      this.SetProperty(CANV_ELEMENT_PROP_NUM,element_num);                       // Номер элемента в списке
      this.SetProperty(CANV_ELEMENT_PROP_COORD_X,x);                             // X-координата элемента на графике
      this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,y);                             // Y-координата элемента на графике
      this.SetProperty(CANV_ELEMENT_PROP_WIDTH,w);                               // Ширина элемента
      this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,h);                              // Высота элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,0);                      // Отступ активной зоны от левого края элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,0);                       // Отступ активной зоны от верхнего края элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,0);                     // Отступ активной зоны от правого края элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,0);                    // Отступ активной зоны от нижнего края элемента
      this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,movable);                       // Флаг перемещаемости элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,activity);                       // Флаг активности элемента
      this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,false);                     // Флаг взаимодействия элемента с внешней средой
      this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.RightEdge());                // Правая граница элемента
      this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.BottomEdge());              // Нижняя граница элемента
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.ActiveAreaLeft());     // X-координата активной зоны элемента
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.ActiveAreaTop());      // Y-координата активной зоны элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.ActiveAreaRight());      // Правая граница активной зоны элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.ActiveAreaBottom());    // Нижняя граница активной зоны элемента
     }
   else
     {
      ::Print(CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.m_name);
     }
  }
//+------------------------------------------------------------------+

Здесь же устанавливаем значение по умолчанию для свойства "Взаимодействие" и исправляем ошибочное присвоение типу объекта библиотеки типа графического элемента (ранее мы присваивали тип элемента переменной m_type, что не верно и приводило к ошибкам идентификации объекта):

   this.m_type=element_type;

Всё точно так же поправим и в защищённом конструкторе класса:

//+------------------------------------------------------------------+
//| Защищённый конструктор                                           |
//+------------------------------------------------------------------+
CGCnvElement::CGCnvElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                           const long    chart_id,
                           const int     wnd_num,
                           const string  name,
                           const int     x,
                           const int     y,
                           const int     w,
                           const int     h) : m_shadow(false)
  {
   this.m_type=OBJECT_DE_TYPE_GELEMENT; 
   this.m_chart_color_bg=(color)::ChartGetInteger(chart_id,CHART_COLOR_BACKGROUND);
   this.m_name=(::StringFind(name,this.m_name_prefix)<0 ? this.m_name_prefix : "")+name;
   this.m_chart_id=chart_id;
   this.m_subwindow=wnd_num;
   this.m_type_element=element_type;
   this.SetFont("Calibri",8);
   this.m_text_anchor=0;
   this.m_text_x=0;
   this.m_text_y=0;
   this.m_color_bg=CLR_CANV_NULL;
   this.m_opacity=0;
   if(this.Create(chart_id,wnd_num,this.m_name,x,y,w,h,this.m_color_bg,this.m_opacity,false))
     {
      this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,this.m_canvas.ResourceName()); // Имя графического ресурса
      this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,CGBaseObj::ChartID());         // Идентификатор графика
      this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,CGBaseObj::SubWindow());        // Номер подокна графика
      this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,CGBaseObj::Name());            // Имя объекта-элемента
      this.SetProperty(CANV_ELEMENT_PROP_TYPE,element_type);                     // Тип графического элемента
      this.SetProperty(CANV_ELEMENT_PROP_ID,0);                                  // Идентификатор элемента
      this.SetProperty(CANV_ELEMENT_PROP_NUM,0);                                 // Номер элемента в списке
      this.SetProperty(CANV_ELEMENT_PROP_COORD_X,x);                             // X-координата элемента на графике
      this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,y);                             // Y-координата элемента на графике
      this.SetProperty(CANV_ELEMENT_PROP_WIDTH,w);                               // Ширина элемента
      this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,h);                              // Высота элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,0);                      // Отступ активной зоны от левого края элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,0);                       // Отступ активной зоны от верхнего края элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,0);                     // Отступ активной зоны от правого края элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,0);                    // Отступ активной зоны от нижнего края элемента
      this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,false);                         // Флаг перемещаемости элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,false);                          // Флаг активности элемента
      this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,false);                     // Флаг взаимодействия элемента с внешней средой
      this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.RightEdge());                // Правая граница элемента
      this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.BottomEdge());              // Нижняя граница элемента
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.ActiveAreaLeft());     // X-координата активной зоны элемента
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.ActiveAreaTop());      // Y-координата активной зоны элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.ActiveAreaRight());      // Правая граница активной зоны элемента
      this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.ActiveAreaBottom());    // Нижняя граница активной зоны элемента
     }
   else
     {
      ::Print(CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.m_name);
     }
  }
//+------------------------------------------------------------------+


В методе, создающем структуру объекта, добавим запись нового свойства в переменные структуры:

//+------------------------------------------------------------------+
//| Создаёт структуру объекта                                        |
//+------------------------------------------------------------------+
bool CGCnvElement::ObjectToStruct(void)
  {
//--- Сохранение целочисленных свойств
   this.m_struct_obj.id=(int)this.GetProperty(CANV_ELEMENT_PROP_ID);                            // Идентификатор элемента
   this.m_struct_obj.type=(int)this.GetProperty(CANV_ELEMENT_PROP_TYPE);                        // Тип графического элемента
   this.m_struct_obj.number=(int)this.GetProperty(CANV_ELEMENT_PROP_NUM);                       // Номер элемента в списке
   this.m_struct_obj.chart_id=this.GetProperty(CANV_ELEMENT_PROP_CHART_ID);                     // Идентификатор графика
   this.m_struct_obj.subwindow=(int)this.GetProperty(CANV_ELEMENT_PROP_WND_NUM);                // Номер подокна графика
   this.m_struct_obj.coord_x=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_X);                  // X-координата формы на графике
   this.m_struct_obj.coord_y=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_Y);                  // Y-координата формы на графике
   this.m_struct_obj.width=(int)this.GetProperty(CANV_ELEMENT_PROP_WIDTH);                      // Ширина элемента
   this.m_struct_obj.height=(int)this.GetProperty(CANV_ELEMENT_PROP_HEIGHT);                    // Высота элемента
   this.m_struct_obj.edge_right=(int)this.GetProperty(CANV_ELEMENT_PROP_RIGHT);                 // Правая граница элемента
   this.m_struct_obj.edge_bottom=(int)this.GetProperty(CANV_ELEMENT_PROP_BOTTOM);               // Нижняя граница элемента
   this.m_struct_obj.act_shift_left=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT);    // Отступ активной зоны от левого края элемента
   this.m_struct_obj.act_shift_top=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP);      // Отступ активной зоны от верхнего края элемента
   this.m_struct_obj.act_shift_right=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT);  // Отступ активной зоны от правого края элемента
   this.m_struct_obj.act_shift_bottom=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM);// Отступ активной зоны от нижнего края элемента
   this.m_struct_obj.movable=(bool)this.GetProperty(CANV_ELEMENT_PROP_MOVABLE);                 // Флаг перемещаемости элемента
   this.m_struct_obj.active=(bool)this.GetProperty(CANV_ELEMENT_PROP_ACTIVE);                   // Флаг активности элемента
   this.m_struct_obj.interaction=(bool)this.GetProperty(CANV_ELEMENT_PROP_INTERACTION);         // Флаг взаимодействия элемента с внешней средой
   this.m_struct_obj.coord_act_x=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_ACT_X);          // X-координата активной зоны элемента
   this.m_struct_obj.coord_act_y=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y);          // Y-координата активной зоны элемента
   this.m_struct_obj.coord_act_right=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_RIGHT);        // Правая граница активной зоны элемента
   this.m_struct_obj.coord_act_bottom=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM);      // Нижняя граница активной зоны элемента
   this.m_struct_obj.color_bg=this.m_color_bg;                                                  // Цвет фона элемента
   this.m_struct_obj.opacity=this.m_opacity;                                                    // Непрозрачность элемента
//--- Сохранение вещественных свойств

//--- Сохранение строковых свойств
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_OBJ),this.m_struct_obj.name_obj);// Имя объекта-графического элемента
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_RES),this.m_struct_obj.name_res);// Имя графического ресурса
   //--- Сохранение структуры в uchar-массив
   ::ResetLastError();
   if(!::StructToCharArray(this.m_struct_obj,this.m_uchar_array))
     {
      CMessage::ToLog(DFUN,MSG_LIB_SYS_FAILED_SAVE_OBJ_STRUCT_TO_UARRAY,true);
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+

А в методе, создающем объект из структуры, добавим чтение этого свойства из структуры в объект:

//+------------------------------------------------------------------+
//| Создаёт объект из структуры                                      |
//+------------------------------------------------------------------+
void CGCnvElement::StructToObject(void)
  {
//--- Сохранение целочисленных свойств
   this.SetProperty(CANV_ELEMENT_PROP_ID,this.m_struct_obj.id);                                 // Идентификатор элемента
   this.SetProperty(CANV_ELEMENT_PROP_TYPE,this.m_struct_obj.type);                             // Тип графического элемента
   this.SetProperty(CANV_ELEMENT_PROP_NUM,this.m_struct_obj.number);                            // Номер элемента в списке
   this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,this.m_struct_obj.chart_id);                     // Идентификатор графика
   this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,this.m_struct_obj.subwindow);                     // Номер подокна графика
   this.SetProperty(CANV_ELEMENT_PROP_COORD_X,this.m_struct_obj.coord_x);                       // X-координата формы на графике
   this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,this.m_struct_obj.coord_y);                       // Y-координата формы на графике
   this.SetProperty(CANV_ELEMENT_PROP_WIDTH,this.m_struct_obj.width);                           // Ширина элемента
   this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,this.m_struct_obj.height);                         // Высота элемента
   this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.m_struct_obj.edge_right);                      // Правая граница элемента
   this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.m_struct_obj.edge_bottom);                    // Нижняя граница элемента
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,this.m_struct_obj.act_shift_left);         // Отступ активной зоны от левого края элемента
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,this.m_struct_obj.act_shift_top);           // Отступ активной зоны от верхнего края элемента
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,this.m_struct_obj.act_shift_right);       // Отступ активной зоны от правого края элемента
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,this.m_struct_obj.act_shift_bottom);     // Отступ активной зоны от нижнего края элемента
   this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,this.m_struct_obj.movable);                       // Флаг перемещаемости элемента
   this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,this.m_struct_obj.active);                         // Флаг активности элемента
   this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,this.m_struct_obj.interaction);               // Флаг взаимодействия элемента с внешней средой
   this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.m_struct_obj.coord_act_x);               // X-координата активной зоны элемента
   this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.m_struct_obj.coord_act_y);               // Y-координата активной зоны элемента
   this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.m_struct_obj.coord_act_right);             // Правая граница активной зоны элемента
   this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.m_struct_obj.coord_act_bottom);           // Нижняя граница активной зоны элемента
   this.m_color_bg=this.m_struct_obj.color_bg;                                                  // Цвет фона элемента
   this.m_opacity=this.m_struct_obj.opacity;                                                    // Непрозрачность элемента
//--- Сохранение вещественных свойств

//--- Сохранение строковых свойств
   this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,::CharArrayToString(this.m_struct_obj.name_obj));// Имя объекта-графического элемента
   this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,::CharArrayToString(this.m_struct_obj.name_res));// Имя графического ресурса
  }
//+------------------------------------------------------------------+


В самом конце листинга файла напишем реализацию виртуального обработчика событий:

//+------------------------------------------------------------------+
//| Обработчик событий                                               |
//+------------------------------------------------------------------+
void CGCnvElement::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Если событие изменения графика - пересчитаем смещение по Y для подокна
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      this.m_shift_y=(int)::ChartGetInteger(this.ChartID(),CHART_WINDOW_YDISTANCE,this.WindowNum());
     }
  }
//+------------------------------------------------------------------+

Ну здесь всё просто: при получении события изменения окна графика нам нужно пересчитать значение вертикального смещения координаты для подокна, так как его размер может измениться и, соответственно, нам необходимо изменить и количество пикселей для корректировки координаты Y в пикселях.


Объекты-формы. Разрабатываем функционал для работы с мышкой

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

Для этого к файлу объекта-формы \MQL5\Include\DoEasy\Objects\Graph\Form.mqh подключим файл состояний мышки и в приватной секции класса объявим переменные, необходимые для работы с объектом свойств мыши:

//+------------------------------------------------------------------+
//|                                                         Form.mqh |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict    // Нужно для mql4
//+------------------------------------------------------------------+
//| Включаемые файлы                                                 |
//+------------------------------------------------------------------+
#include "GCnvElement.mqh"
#include "ShadowObj.mqh"
#include "Animations\Animations.mqh"
#include "..\..\Services\MouseState.mqh"
//+------------------------------------------------------------------+
//| Класс объекта "форма"                                            |
//+------------------------------------------------------------------+
class CForm : public CGCnvElement
  {
private:
   CArrayObj         m_list_elements;                          // Список присоединённых элементов
   CAnimations      *m_animations;                             // Указатель на объект анимаций
   CShadowObj       *m_shadow_obj;                             // Указатель на объект тени
   CMouseState       m_mouse;                                  // Объект класса "Состояния мышки"
   ENUM_MOUSE_FORM_STATE m_mouse_form_state;                   // Состояние мышки относительно формы
   ushort            m_mouse_state_flags;                      // Флаги состояния мышки
   color             m_color_frame;                            // Цвет рамки формы
   int               m_frame_width_left;                       // Ширина рамки формы слева
   int               m_frame_width_right;                      // Ширина рамки формы справа
   int               m_frame_width_top;                        // Ширина рамки формы сверху
   int               m_frame_width_bottom;                     // Ширина рамки формы снизу
   int               m_offset_x;                               // Смещение координаты X относительно курсора
   int               m_offset_y;                               // Смещение координаты Y относительно курсора
   
//--- Инициализирует переменные
   void              Initialize(void);
//--- Сбрасывает размер массива (1) текстовых, (2) прямоугольных, (3) геометрических кадров анимаций
   void              ResetArrayFrameT(void);
   void              ResetArrayFrameQ(void);
   void              ResetArrayFrameG(void);
   
//--- Возвращает имя зависимого объекта
   string            CreateNameDependentObject(const string base_name)  const
                       { return ::StringSubstr(this.NameObj(),::StringLen(::MQLInfoString(MQL_PROGRAM_NAME))+1)+"_"+base_name;   }
  
//--- Создаёт новый графический объект
   CGCnvElement     *CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type,
                                      const int element_num,
                                      const string name,
                                      const int x,
                                      const int y,
                                      const int w,
                                      const int h,
                                      const color colour,
                                      const uchar opacity,
                                      const bool movable,
                                      const bool activity);

//--- Создаёт объект для тени
   void              CreateShadowObj(const color colour,const uchar opacity);
   
public:


В публичной секции класса объявим методы для работы с объектом состояния мышки и виртуальный обработчик событий объекта-формы:

public:
//--- Возвращает состояние мышки относительно формы
   ENUM_MOUSE_FORM_STATE MouseFormState(const int id,const long lparam,const double dparam,const string sparam);
//--- Устанавливает для графика флаги прокрутки колёсиком мышки, контекстного меню и инструмента "перекрестие"
   void              SetChartTools(const bool flag);

//--- (1) Устанавливает, (2) возвращает смещение координат X и Y относительно курсора
   void              SetOffsetX(const int value)         { this.m_offset_x=value;         }
   void              SetOffsetY(const int value)         { this.m_offset_y=value;         }
   int               OffsetX(void)                 const { return this.m_offset_x;        }
   int               OffsetY(void)                 const { return this.m_offset_y;        }
//--- Возвращает координату (1) X, (2) Y курсора
   int               MouseCursorX(void)            const { return this.m_mouse.CoordX();  }
   int               MouseCursorY(void)            const { return this.m_mouse.CoordY();  }
   
//--- Обработчик событий
   virtual void      OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam);
//--- Конструкторы
                     CForm(const long chart_id,
                           const int subwindow,
                           const string name,
                           const int x,
                           const int y,
                           const int w,
                           const int h);
                     CForm(const int subwindow,
                           const string name,
                           const int x,
                           const int y,
                           const int w,
                           const int h);
                     CForm(const string name,
                           const int x,
                           const int y,
                           const int w,
                           const int h);
                     CForm() { this.m_type=OBJECT_DE_TYPE_GFORM; this.Initialize(); }
//--- Деструктор
                    ~CForm();


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

//+------------------------------------------------------------------+
//| Инициализирует переменные                                        |
//+------------------------------------------------------------------+
void CForm::Initialize(void)
  {
   this.m_list_elements.Clear();
   this.m_list_elements.Sort();
   this.m_shadow_obj=NULL;
   this.m_shadow=false;
   this.m_frame_width_right=2;
   this.m_frame_width_left=2;
   this.m_frame_width_top=2;
   this.m_frame_width_bottom=2;
   this.m_mouse_state_flags=0;
   this.m_offset_x=0;
   this.m_offset_y=0;
   CGCnvElement::SetInteraction(false);
   this.m_animations=new CAnimations(CGCnvElement::GetObject());
  }
//+------------------------------------------------------------------+


Напишем метод, возвращающий состояние мышки относительно формы:

//+------------------------------------------------------------------+
//| Возвращает состояние мышки относительно формы                    |
//+------------------------------------------------------------------+
ENUM_MOUSE_FORM_STATE CForm::MouseFormState(const int id,const long lparam,const double dparam,const string sparam)
  {
//--- Получаем состояние мышки относительно формы и состояние кнопок мыши и клавиш Shift и Ctrl
   ENUM_MOUSE_FORM_STATE form_state=MOUSE_FORM_STATE_OUTSIDE_NOT_PRESSED;
   ENUM_MOUSE_BUTT_KEY_STATE state=this.m_mouse.ButtonKeyState(id,lparam,dparam,sparam);
//--- Получаем флаги состоянии мышки из объекта класса CMouseState и сохраняем их в переменной
   this.m_mouse_state_flags=this.m_mouse.GetMouseFlags();
//--- Если курсор внутри формы
   if(CGCnvElement::CursorInsideElement(m_mouse.CoordX(),m_mouse.CoordY()))
     {
      //--- Устанавливаем бит 8, отвечающий за флаг "курсор внутри формы"
      this.m_mouse_state_flags |= (0x0001<<8);
      //--- Если курсор внутри активной зоны - устанавливаем бит 9 "курсор внутри активной зоны"
      if(CGCnvElement::CursorInsideActiveArea(m_mouse.CoordX(),m_mouse.CoordY()))
         this.m_mouse_state_flags |= (0x0001<<9);
      //--- иначе - снимаем бит "курсор внутри активной зоны"
      else this.m_mouse_state_flags &=0xFDFF;
      //--- Если нажата одна из трёх кнопок мыши - проверяем расположение курсора в активной области и
      //--- возвращаем соответствующее значение нажатой кнопки (в активной зоне или в области формы)
      if((this.m_mouse_state_flags & 0x0001)!=0 || (this.m_mouse_state_flags & 0x0002)!=0 || (this.m_mouse_state_flags & 0x0010)!=0)
         form_state=((this.m_mouse_state_flags & 0x0200)!=0 ? MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED : MOUSE_FORM_STATE_INSIDE_PRESSED);
      //--- иначе если ни одна кнопка мышки не нажата
      else
        {
         //--- если колесо мышки прокручивается, возвращаем соответствующее значение прокрутки колеса (в активной зоне или в области формы)
         if((this.m_mouse_state_flags & 0x0080)!=0)
            form_state=((this.m_mouse_state_flags & 0x0200)!=0 ? MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_WHEEL : MOUSE_FORM_STATE_INSIDE_WHEEL);
         //--- иначе - возвращаем соответствующее значение ненажатой кнопки (в активной зоне или в области формы)
         else
            form_state=((this.m_mouse_state_flags & 0x0200)!=0 ? MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED : MOUSE_FORM_STATE_INSIDE_NOT_PRESSED);
        } 
     }
//--- Если курсор снаружи формы
   else
     {
      //--- возвращаем соответствующее значение кнопок в неактивной зоне
      form_state=(((this.m_mouse_state_flags & 0x0001)!=0 || (this.m_mouse_state_flags & 0x0002)!=0 || (this.m_mouse_state_flags & 0x0010)!=0) ? MOUSE_FORM_STATE_OUTSIDE_PRESSED : MOUSE_FORM_STATE_OUTSIDE_NOT_PRESSED);
     }
   return form_state;
  }
//+------------------------------------------------------------------+

Этот метод мы подробно рассматривали в статье 73 при создании тестового объекта-формы. Сейчас метод был немного дополнен для отслеживания состояний кнопок мышки при расположении курсора за пределами формы. В листинге метода его логика очень подробно расписана и, надеюсь, вопросов не вызывает. В любом случае всё можно обсудить в обсуждении статьи.

Обработчик событий объекта-формы:

//+------------------------------------------------------------------+
//| Обработчик событий                                               |
//+------------------------------------------------------------------+
void CForm::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   CGCnvElement::OnChartEvent(id,lparam,dparam,sparam);
//--- Получаем состояние кнопок мыши и клавиш Shift и Ctrl
   this.m_mouse_form_state=this.MouseFormState(id,lparam,dparam-this.m_shift_y,sparam);

//--- Проверяем в каком месте графика была нажата и удерживается кнопка мышки (за пределами формы или внутри неё)
//--- Если нажата левая кнопка мышки - считаем её нажатой
   bool pressed=(this.m_mouse.ButtonKeyState(id,lparam,dparam,sparam)==MOUSE_BUTT_KEY_STATE_LEFT ? true : false);
//--- Если нажата левая кнопка мышки за пределами формы - устанавливаем переменную pressed_chart в значение true
   bool pressed_chart=(this.m_mouse_form_state==MOUSE_FORM_STATE_OUTSIDE_PRESSED && this.m_mouse.ButtonKeyState(id,lparam,dparam,sparam)==MOUSE_BUTT_KEY_STATE_LEFT ? true : false);
//--- Если нажата левая кнопка мышки внутри формы - устанавливаем переменную pressed_form в значение true
   bool pressed_form=(pressed_chart ? false : this.m_mouse_form_state==MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED && this.m_mouse.ButtonKeyState(id,lparam,dparam,sparam)==MOUSE_BUTT_KEY_STATE_LEFT ? true : false);
//--- Если кнопка была нажата на чарте для его перемещения
   if(pressed_chart)
     {
      //--- сбрасываем флаг взаимодействия и разрешаем перемотку графика колёсиком мышки, контекстное меню графика и инструмент "Перекрестие"
      this.SetInteraction(false);
      this.SetChartTools(true);
     }
//--- Иначе, если нажата кнопка внутри формы и ещё не установлен флаг взаимодействия
   else if(pressed_form && !this.Interaction())
     {
      //--- перемещаем форму поверх всех остальных, устанавливаем флаг взаимодействия,
      //--- запрещаем перемотку графика колёсиком мышки, контекстное меню графика и инструмент "Перекрестие"
      //--- и записываем величины смещения курсора мышки внутри формы относительно началаеё координат в левом верхнем углу
      this.BringToTop();
      this.SetInteraction(CGCnvElement::Active() ? true : false);
      this.SetChartTools(CGCnvElement::Active() ? false : true);
      this.m_offset_x=this.m_mouse.CoordX()-this.CoordX();
      this.m_offset_y=this.m_mouse.CoordY()-this.CoordY();
     }
//--- Если событие перемещения курсора
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Если для формы установлен флаг взаимодействия
      if(this.Interaction())
        {
         //--- Если состояние мышки - зажата левая кнопка внутри активной зоны формы
         if(this.MouseFormState(id,lparam,dparam,sparam)==MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED)
           {
            //--- Если форма перемещена за курсором
            if(this.Move(this.m_mouse.CoordX()-this.m_offset_x,this.m_mouse.CoordY()-this.m_offset_y,true))
              {
               //--- Запишем новые значения смещения курсора относительно начала координат формы
               this.m_offset_x=this.m_mouse.CoordX()-this.CoordX();
               this.m_offset_y=this.m_mouse.CoordY()-this.CoordY();
              }
           }
        }
      //--- Выведем на график комментарий со значениями переменных для контроля
      Comment
        (
         this.Name(),":\n",
         EnumToString((ENUM_CHART_EVENT)id),"\n",
         EnumToString(this.m_mouse.ButtonKeyState(id,lparam,dparam,sparam)),
         "\n",EnumToString(this.m_mouse_form_state),
         "\npressed=",pressed,", pressed_chart=",pressed_chart,", pressed_form=",pressed_form,", Interaction=",Interaction()
        );
     }
  }
//+------------------------------------------------------------------+

Этот метод так же подробно прокомментирован. При регистрации события графика вызывается данный обработчик, где в первую очередь проверяется состояние кнопок мышки и положение её курсора. После этого устанавливаются флаги общего состояния мышки (левая кнопка нажата на графике или левая кнопка нажата внутри активной области формы). Затем эти флаги используются для ветвления логики обработчика. Расчёт на то, что если кнопка мышки нажата и удерживается за пределами формы, то графику разрешаются его дополнительные инструменты (прокрутка мышкой, контекстное меню и инструмент перекрестие), а у формы сбрасывается флаг взаимодействия с мышкой.
Если же левая кнопка мышки была нажата и удерживается внутри активной области формы, то графику запрещаются его дополнительные инструменты, а форме устанавливается флаг взаимодействия с мышью.

Это должно нам дать в итоге такое поведение: если мы удерживаем форму кнопкой мышки, то мы можем её перемещать, и при этом график перемещаться не должен. Если мы будем прокручивать колёсико мышки внутри формы, то график при этом должен быть неподвижен (ведь в последующем на форме могут быть, и будут, иные элементы, которым необходима прокрутка колёсиком мышки, и при этом график не должен на это реагировать).

В то же время, активной для взаимодействия с мышкой должна быть только одна форма (которую мы удерживаем кнопкой, или над которой находится курсор, и она при этом на переднем плане). Всё это мы постепенно добавим и реализуем.

Метод, устанавливающий для графика флаги прокрутки чарта колёсиком мышки, контекстного меню и инструмента "перекрестие":

//+------------------------------------------------------------------+
//| Устанавливает для графика флаги прокрутки колёсиком мышки,       |
//| контекстного меню и инструмента "перекрестие"                    |
//+------------------------------------------------------------------+
void CForm::SetChartTools(const bool flag)
  {
   ::ChartSetInteger(this.ChartID(),CHART_MOUSE_SCROLL,flag);
   ::ChartSetInteger(this.ChartID(),CHART_CONTEXT_MENU,flag);
   ::ChartSetInteger(this.ChartID(),CHART_CROSSHAIR_TOOL,flag);
  }
//+------------------------------------------------------------------+

В метод передаётся флаг, и для каждого из свойств графика устанавливается значение этого флага.

Так как в составных графических объектах, разработку которых мы недавно начали, тоже присутствуют объекты-формы в качестве объектов управления опорными точками базового графического объекта, то немного доработаем и класс инструментария расширенного стандартного графического объекта в файле \MQL5\Include\DoEasy\Objects\Graph\Extend\CGStdGraphObjExtToolkit.mqh.

В обработчик событий добавим обработку перемещения мышки:

//+------------------------------------------------------------------+
//| Обработчик событий                                               |
//+------------------------------------------------------------------+
void CGStdGraphObjExtToolkit::OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
  {
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      for(int i=0;i<this.m_list_forms.Total();i++)
        {
         CForm *form=this.m_list_forms.At(i);
         if(form==NULL)
            continue;
         int x=0, y=0;
         if(!this.GetControlPointCoordXY(i,x,y))
            continue;
         form.SetCoordX(x-this.m_shift);
         form.SetCoordY(y-this.m_shift);
         form.Update();
        }
      ::ChartRedraw(this.m_base_chart_id);
     }
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      for(int i=0;i<this.m_list_forms.Total();i++)
        {
         CForm *form=this.m_list_forms.At(i);
         if(form==NULL)
            continue;
         form.OnChartEvent(id,lparam,dparam,sparam);
        }
      ::ChartRedraw(this.m_base_chart_id);
     }
  }
//+------------------------------------------------------------------+

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

Объект этого класса входит в состав расширенного стандартного графического объекта. Поэтому, чтобы обратиться к его обработчику событий, рассмотренному выше, нужно в классе объекта стандартного графического объекта доработать его обработчик событий.

Откроем файл класса стандартного графического объекта \MQL5\Include\DoEasy\Objects\Graph\Standard\GStdGraphObj.mqh и внесём в него некоторые доработки.

В защищённом параметрическом конструкторе будем проверять расширенный ли это объект и, если да, то устанавливать для него флаги выделенности и доступности в значение false. А для обычного стандартного графического объекта флаги этих свойств будут браться прямо из графического объекта:

//+------------------------------------------------------------------+
//| Защищённый параметрический конструктор                           |
//+------------------------------------------------------------------+
CGStdGraphObj::CGStdGraphObj(const ENUM_OBJECT_DE_TYPE obj_type,
                             const ENUM_GRAPH_ELEMENT_TYPE elm_type,
                             const ENUM_GRAPH_OBJ_BELONG belong,
                             const ENUM_GRAPH_OBJ_SPECIES species,
                             const long chart_id,const int pivots,
                             const string name)
  {
//--- Создаём объект свойств со значениями по умолчанию
   this.Prop=new CProperties(GRAPH_OBJ_PROP_INTEGER_TOTAL,GRAPH_OBJ_PROP_DOUBLE_TOTAL,GRAPH_OBJ_PROP_STRING_TOTAL);
   this.ExtToolkit=(elm_type==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED ? new CGStdGraphObjExtToolkit() : NULL);
//--- Устанавливаем количество опорных точек и уровней объекта
   this.m_pivots=pivots;
   int levels=(int)::ObjectGetInteger(chart_id,name,OBJPROP_LEVELS);

//--- Устанавливаем размерности массивов свойств в соответствии с количеством опорных точек и уровней
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_TIME,this.m_pivots);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_PRICE,this.m_pivots);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELCOLOR,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELSTYLE,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELWIDTH,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELVALUE,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELTEXT,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_BMPFILE,2);
   
//--- Устанавливаем объекту (1) его тип, тип графического (2) объекта, (3) елемента, (4) принадлежность и (5) номер подокна, (6) Digits символа графика
   this.m_type=obj_type;
   this.SetName(name);
   CGBaseObj::SetChartID(chart_id);
   CGBaseObj::SetTypeGraphObject(CGBaseObj::GraphObjectType(obj_type));
   CGBaseObj::SetTypeElement(elm_type);
   CGBaseObj::SetBelong(belong);
   CGBaseObj::SetSpecies(species);
   CGBaseObj::SetSubwindow(chart_id,name);
   CGBaseObj::SetDigits((int)::SymbolInfoInteger(::ChartSymbol(chart_id),SYMBOL_DIGITS));
   
//--- Сохранение целочисленных свойств, присущих всем графическим объектам, но не имеющиеся у графического объекта
   this.SetProperty(GRAPH_OBJ_PROP_CHART_ID,0,CGBaseObj::ChartID());                // Идентификатор графика
   this.SetProperty(GRAPH_OBJ_PROP_WND_NUM,0,CGBaseObj::SubWindow());               // Номер подокна графика
   this.SetProperty(GRAPH_OBJ_PROP_TYPE,0,CGBaseObj::TypeGraphObject());            // Тип графического объекта (ENUM_OBJECT)
   this.SetProperty(GRAPH_OBJ_PROP_ELEMENT_TYPE,0,CGBaseObj::TypeGraphElement());   // Тип графического элемента (ENUM_GRAPH_ELEMENT_TYPE)
   this.SetProperty(GRAPH_OBJ_PROP_BELONG,0,CGBaseObj::Belong());                   // Принадлежность графического объекта
   this.SetProperty(GRAPH_OBJ_PROP_SPECIES,0,CGBaseObj::Species());                 // Вид графического объекта
   this.SetProperty(GRAPH_OBJ_PROP_GROUP,0,0);                                      // Группа графических объектов
   this.SetProperty(GRAPH_OBJ_PROP_ID,0,0);                                         // Идентификатор объекта
   this.SetProperty(GRAPH_OBJ_PROP_BASE_ID,0,0);                                    // Идентификатор базового объекта
   this.SetProperty(GRAPH_OBJ_PROP_NUM,0,0);                                        // Номер объекта в списке
   this.SetProperty(GRAPH_OBJ_PROP_CHANGE_HISTORY,0,false);                         // Флаг хранения истории изменений
   this.SetProperty(GRAPH_OBJ_PROP_BASE_NAME,0,this.Name());                        // Имя базового объекта
   
//--- Сохранение свойств, присущих всем графическим объектам, имеющимся у графического объекта
   this.PropertiesRefresh();
   
//--- Сохранение базовых свойств в родительском объекте
   this.m_create_time=(datetime)this.GetProperty(GRAPH_OBJ_PROP_CREATETIME,0);
   this.m_back=(bool)this.GetProperty(GRAPH_OBJ_PROP_BACK,0);
   this.m_selected=(bool)(GraphElementType()==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED ? false : this.GetProperty(GRAPH_OBJ_PROP_SELECTED,0));
   this.m_selectable=(bool)(GraphElementType()==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED ? false : this.GetProperty(GRAPH_OBJ_PROP_SELECTABLE,0));
   this.m_hidden=(bool)this.GetProperty(GRAPH_OBJ_PROP_HIDDEN,0);

//--- Инициализация инструментария расширенного графического объекта
   if(this.GraphElementType()==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)
     {
      datetime times[];
      double prices[];
      if(::ArrayResize(times,this.Pivots())!=this.Pivots())
         CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_EXT_FAILED_ARR_RESIZE_TIME_DATA);
      if(::ArrayResize(prices,this.Pivots())!=this.Pivots())
         CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_EXT_FAILED_ARR_RESIZE_PRICE_DATA);
      for(int i=0;i<this.Pivots();i++)
        {
         times[i]=this.Time(i);
         prices[i]=this.Price(i);
        }
      this.ExtToolkit.SetBaseObj(this.TypeGraphObject(),this.Name(),this.ChartID(),this.SubWindow(),this.Pivots(),CTRL_FORM_SIZE,this.XDistance(),this.YDistance(),times,prices);
      this.ExtToolkit.CreateAllControlPointForm();
      this.SetFlagSelected(false,false);
      this.SetFlagSelectable(false,false);
     }

//--- Сохранение текущих свойств в прошлые
   this.PropertiesCopyToPrevData();
  }
//+-------------------------------------------------------------------+


В обработчике событий стандартного графического объекта будем отправлять в обработчик событий объекта-инструментария расширенного графического объекта имя текущего графического объекта в параметре sparam. И добавим обработку события перемещения мышки, которую впоследствии будем тоже обрабатывать:

//+------------------------------------------------------------------+
//| Обработчик событий                                               |
//+------------------------------------------------------------------+
void CGStdGraphObj::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   if(GraphElementType()!=GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)
      return;
   string name=this.Name();
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      if(ExtToolkit==NULL)
         return;
      for(int i=0;i<this.Pivots();i++)
        {
         ExtToolkit.SetBaseObjTimePrice(this.Time(i),this.Price(i),i);
        }
      ExtToolkit.SetBaseObjCoordXY(this.XDistance(),this.YDistance());
      ExtToolkit.OnChartEvent(id,lparam,dparam,name);
     }
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      if(ExtToolkit!=NULL)
         ExtToolkit.OnChartEvent(id,lparam,dparam,name);
     }
  }
//+------------------------------------------------------------------+

Пока это всё черновые изменения, которыми сейчас заниматься не будем, поэтому и рассматривать тут особо и нечего. Всё это будет дорабатываться уже в процессе работы над составными графическими объектами.

Объектами-формами будем управлять из класса-коллекции графических элементов. В нём же у нас уже есть список для хранения указателей на графические элементы, в который будем помещать все создаваемые формы. Пока будем это делать в ручном режиме, а чуть позже создадим для этого функционал, добавляющий объекты в список сразу при их создании.

В файле класса-коллекции графических элементов \MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqh у нас расположен ещё один класс для управления объектами-чартами. Добавим в него перегруженные методы для установки флагов разрешения инструментария графика — прокрутка колёсиком, перемещение мышью, контекстное меню и "Перекрестие":

//+------------------------------------------------------------------+
//| Класс управления объектами чарта                                 |
//+------------------------------------------------------------------+
class CChartObjectsControl : public CObject
  {
private:
   CArrayObj         m_list_new_graph_obj;      // Список добавленных графических объектов
   ENUM_TIMEFRAMES   m_chart_timeframe;         // Период графика
   long              m_chart_id;                // Идентификатор графика
   long              m_chart_id_main;           // Идентификатор графика управляющей программы
   string            m_chart_symbol;            // Символ графика
   bool              m_is_graph_obj_event;      // Флаг события в списке графических объектов
   int               m_total_objects;           // Количество графических объектов
   int               m_last_objects;            // Количество графических объектов на прошлой проверке
   int               m_delta_graph_obj;         // Разница в количестве графических объектов по сравнению с прошлой проверкой
   int               m_handle_ind;              // Хендл индикатора-контроллера событий
   string            m_name_ind;                // Короткое имя индикатора-контроллера событий
   string            m_name_program;            // Название программы
   
//--- Возвращает имя последнего добавленного на график графического объекта
   string            LastAddedGraphObjName(void);
//--- Устанавливает для графика разрешение отслеживания событий мышки и графических объектов
   void              SetMouseEvent(void);

public:
//--- Возврат значений переменных
   ENUM_TIMEFRAMES   Timeframe(void)                           const { return this.m_chart_timeframe;    }
   long              ChartID(void)                             const { return this.m_chart_id;           }
   string            Symbol(void)                              const { return this.m_chart_symbol;       }
   bool              IsEvent(void)                             const { return this.m_is_graph_obj_event; }
   int               TotalObjects(void)                        const { return this.m_total_objects;      }
   int               Delta(void)                               const { return this.m_delta_graph_obj;    }
//--- Устанавливает для графика флаги прокрутки чарта колёсиком мышки, контекстного меню и инструмента "перекрестие"
   void              SetChartTools(const bool flag);
   void              SetChartTools(const bool mouse_scroll,const bool context_menu,const bool crosshair_tool);
//--- Создаёт новый объект стандартного (или расширенного) графического объекта
   CGStdGraphObj    *CreateNewGraphObj(const ENUM_OBJECT obj_type,const string name,const bool extended);
//--- Возвращает список вновь добавленных объектов
   CArrayObj        *GetListNewAddedObj(void)                        { return &this.m_list_new_graph_obj;}
//--- Создаёт индикатор контроля событий
   bool              CreateEventControlInd(const long chart_id_main);
//--- Добавляет на чарт индикатор контроля событий
   bool              AddEventControlInd(void);
//--- Проверяет объекты на чарте
   void              Refresh(void);
//--- Конструкторы
                     CChartObjectsControl(void)
                       { 
                        this.m_name_program=::MQLInfoString(MQL_PROGRAM_NAME);
                        this.m_chart_id=::ChartID();
                        this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(this.m_chart_id);
                        this.m_chart_symbol=::ChartSymbol(this.m_chart_id);
                        this.m_chart_id_main=::ChartID();
                        this.m_list_new_graph_obj.Clear();
                        this.m_list_new_graph_obj.Sort();
                        this.m_is_graph_obj_event=false;
                        this.m_total_objects=0;
                        this.m_last_objects=0;
                        this.m_delta_graph_obj=0;
                        this.m_name_ind="";
                        this.m_handle_ind=INVALID_HANDLE;
                        this.SetMouseEvent();
                       }
                     CChartObjectsControl(const long chart_id)
                       { 
                        this.m_name_program=::MQLInfoString(MQL_PROGRAM_NAME);
                        this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(chart_id);
                        this.m_chart_symbol=::ChartSymbol(chart_id);
                        this.m_chart_id_main=::ChartID();
                        this.m_list_new_graph_obj.Clear();
                        this.m_list_new_graph_obj.Sort();
                        this.m_chart_id=chart_id;
                        this.m_is_graph_obj_event=false;
                        this.m_total_objects=0;
                        this.m_last_objects=0;
                        this.m_delta_graph_obj=0;
                        this.m_name_ind="";
                        this.m_handle_ind=INVALID_HANDLE;
                        this.SetMouseEvent();
                       }
//--- Деструктор
                     ~CChartObjectsControl()
                       {
                        ::ChartIndicatorDelete(this.ChartID(),0,this.m_name_ind);
                        ::IndicatorRelease(this.m_handle_ind);
                       }
                     
//--- Сравнивает объекты CChartObjectsControl между собой по идентификатору графика (для сортировки списка по свойству объекта)
   virtual int       Compare(const CObject *node,const int mode=0) const
                       {
                        const CChartObjectsControl *obj_compared=node;
                        return(this.ChartID()>obj_compared.ChartID() ? 1 : this.ChartID()<obj_compared.ChartID() ? -1 : 0);
                       }

//--- Обработчик событий
   void              OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam);

  };
//+------------------------------------------------------------------+

За пределами тела класса напишем их реализацию:

//+------------------------------------------------------------------+
//| Устанавливает для графика флаги прокрутки колёсиком мышки,       |
//| контекстного меню и инструмента "перекрестие"                    |
//+------------------------------------------------------------------+
void CChartObjectsControl::SetChartTools(const bool flag)
  {
   ::ChartSetInteger(this.ChartID(),CHART_MOUSE_SCROLL,flag);
   ::ChartSetInteger(this.ChartID(),CHART_CONTEXT_MENU,flag);
   ::ChartSetInteger(this.ChartID(),CHART_CROSSHAIR_TOOL,flag);
  }
//+------------------------------------------------------------------+
//| Устанавливает для графика флаги прокрутки колёсиком мышки,       |
//| контекстного меню и инструмента "перекрестие"                    |
//+------------------------------------------------------------------+
void CChartObjectsControl::SetChartTools(const bool mouse_scroll,const bool context_menu,const bool crosshair_tool)
  {
   ::ChartSetInteger(this.ChartID(),CHART_MOUSE_SCROLL,mouse_scroll);
   ::ChartSetInteger(this.ChartID(),CHART_CONTEXT_MENU,context_menu);
   ::ChartSetInteger(this.ChartID(),CHART_CROSSHAIR_TOOL,crosshair_tool);
  }
//+------------------------------------------------------------------+

Аналогичные методы мы уже рассматривали выше. Здесь лишь разница в том, что в один из них передаются раздельно флаги для каждого из инструментов. Эти методы нам в дальнейшем могут пригодиться для управления графиками из класса-коллекции графических элементов, в котором переименуем метод

bool              IsPresentGraphElmInList(const int id,const ENUM_GRAPH_ELEMENT_TYPE type_obj);

на более подходящий по смыслу и с другими параметрами,
и добавим публичный (временно) метод для добавления графических элементов в список-коллекцию:

//+------------------------------------------------------------------+
//| Коллекция графических объектов                                   |
//+------------------------------------------------------------------+
#resource "\\"+PATH_TO_EVENT_CTRL_IND;          // Индикатор контроля событий графических объектов, упакованный в ресурсы программы
class CGraphElementsCollection : public CBaseObj
  {
private:
   CArrayObj         m_list_charts_control;     // Список объектов управления чартами
   CListObj          m_list_all_canv_elm_obj;   // Список всех графических элементов на канвасе
   CListObj          m_list_all_graph_obj;      // Список всех графических объектов
   CArrayObj         m_list_deleted_obj;        // Список удалённых графических объектов
   bool              m_is_graph_obj_event;      // Флаг события в списке графических объектов
   int               m_total_objects;           // Количество графических объектов
   int               m_delta_graph_obj;         // Разница в количестве графических объектов по сравнению с прошлой проверкой
   
//--- Возвращает флаг наличия объекта класса графического элемента в списке-коллекции графических элементов
   bool              IsPresentCanvElmInList(const long chart_id,const string name);
//--- Возвращает флаг наличия объекта класса графического объекта в списке-коллекции графических объектов
   bool              IsPresentGraphObjInList(const long chart_id,const string name);
//--- Возвращает флаг наличия графического объекта на графике по имени
   bool              IsPresentGraphObjOnChart(const long chart_id,const string name);
//--- Возвращает указатель на объект управления объектами указанного чарта
   CChartObjectsControl *GetChartObjectCtrlObj(const long chart_id);
//--- Создаёт новый объект управления графическими объектами указанного чарта и добавляет его в список
   CChartObjectsControl *CreateChartObjectCtrlObj(const long chart_id);
//--- Обновляет список графических объектов по идентификатору чарта
   CChartObjectsControl *RefreshByChartID(const long chart_id);
//--- Проверяет наличие окна графика
   bool              IsPresentChartWindow(const long chart_id);
//--- Обрабатывает удаление окна графика
   void              RefreshForExtraObjects(void);
//--- Возвращает первый свободный идентификатор графического (1) объекта, (2) элемента на канвасе
   long              GetFreeGraphObjID(bool program_object);
   long              GetFreeCanvElmID(void);
//--- Добавляет (1) стандартный графический объект, (2) графический элемент на канвасе в коллекцию
   bool              AddGraphObjToCollection(const string source,CChartObjectsControl *obj_control);
public:
   bool              AddCanvElmToCollection(CGCnvElement *element);
   
private:

Пока этот метод будет публичным. Далее, когда сделаем добавление создаваемых графических элементов на канвасе в список сразу в момент их создания, этот метод сделаем приватным.

В приватной же секции класса объявим метод, устанавливающий уже знакомые нам флаги для графика:

public:
   bool              AddCanvElmToCollection(CGCnvElement *element);
   
private:
//--- Находит объект, имеющийся в коллекции, но отсутствующий на графике
   CGStdGraphObj    *FindMissingObj(const long chart_id);
   CGStdGraphObj    *FindMissingObj(const long chart_id,int &index);
//--- Находит графический объект, имеющийся на графике, но отсутствующий в коллекции
   string            FindExtraObj(const long chart_id);
//--- Удаляет (1) указанный, (2) по идентификатору графика объект класса графического объекта из списка-коллекции графических объектов
   bool              DeleteGraphObjFromList(CGStdGraphObj *obj);
   void              DeleteGraphObjectsFromList(const long chart_id);
//--- Перемещает (1) указанный, (2) по индексу объект класса графического объекта в список удалённых графических объектов
   bool              MoveGraphObjToDeletedObjList(CGStdGraphObj *obj);
   bool              MoveGraphObjToDeletedObjList(const int index);
//--- Перемещает в список удалённых графических объектов все объекты по идентификатору графика
   void              MoveGraphObjectsToDeletedObjList(const long chart_id);
//--- Удаляет объект управления графиками из списка
   bool              DeleteGraphObjCtrlObjFromList(CChartObjectsControl *obj);
//--- Устанавливает для указанного графика флаги прокрутки чарта колёсиком мышки, контекстного меню и инструмента "перекрестие"
   void              SetChartTools(const long chart_id,const bool flag);
public:


В каждом из публичных методов для создания графического объекта установим флаги выделенности и доступности точно таким же способом, как рассматривали немного выше. На примере метода для создания вертикальной линии:

public:
//--- Создаёт графический объект "Вертикальная линия"
   bool              CreateLineVertical(const long chart_id,const string name,const int subwindow,const bool extended,const datetime time)
                       {
                        //--- Задаём имя и тип создаваемого объекта
                        string nm=this.m_name_program+"_"+name;
                        ENUM_OBJECT type_object=OBJ_VLINE;
                        //--- Создаём новый графический объект и получаем указатель на объект управления графиком
                        CChartObjectsControl *ctrl=this.CreateNewStdGraphObjectAndGetCtrlObj(chart_id,nm,subwindow,type_object,time,0);
                        if(ctrl==NULL)
                           return false;
                        //--- Создаём новый объект класса, соответствующий созданному графическому объекту
                        CGStdVLineObj *obj=ctrl.CreateNewGraphObj(type_object,nm,extended);
                        if(obj==NULL)
                          {
                           ::Print(DFUN,CMessage::Text(MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_CLASS_OBJ),StdGraphObjectTypeDescription(type_object));
                           return false;
                          }
                        //--- Устанавливаем объекту необходимые минимальные параметры
                        obj.SetBelong(GRAPH_OBJ_BELONG_PROGRAM);
                        obj.SetFlagSelected(obj.GraphElementType()==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED ? false : obj.Selected(),false);
                        obj.SetFlagSelectable(obj.GraphElementType()==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED ? false : true,false);
                        obj.SetObjectID(this.GetFreeGraphObjID(true));
                        obj.PropertiesCopyToPrevData();
                        //--- Возвращаем результат добавления объекта в список
                        return this.AddCreatedObjToList(DFUN,chart_id,nm,obj);
                       }

Все остальные подобные методы создания графических объектов уже доработаны аналогично, и здесь их рассматривать не будем.

Метод, добавляющий графический элемент на канвасе в коллекцию:

//+------------------------------------------------------------------+
//| Добавляет графический элемент на канвасе в коллекцию             |
//+------------------------------------------------------------------+
bool CGraphElementsCollection::AddCanvElmToCollection(CGCnvElement *element)
  {
   if(element==NULL)
      return false;
   if(this.IsPresentCanvElmInList(element.ChartID(),element.Name()))
     {
      CMessage::ToLog(DFUN+element.Name()+": ",MSG_LIB_SYS_OBJ_ALREADY_IN_LIST);
      return false;
     }
   if(!this.m_list_all_canv_elm_obj.Add(element))
     {
      CMessage::ToLog(DFUN+element.Name()+": ",MSG_LIB_SYS_FAILED_OBJ_ADD_TO_LIST);
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+

В метод передаётся указатель на графический элемент, который необходимо поместить в список.
Если точно такой же объект уже есть в списке — сообщаем об этом и возвращаем false.
Если указатель не удалось поместить в список — сообщаем об этом и возвращаем false.
В итоге, если всё прошло успешно, возвращаем true.

Метод, возвращающий флаг наличия объекта класса графического элемента в списке-коллекции графических элементов:

//+------------------------------------------------------------------+
//| Возвращает флаг наличия объекта класса графического элемента     |
//| в списке-коллекции графических элементов                         |
//+------------------------------------------------------------------+
bool CGraphElementsCollection::IsPresentCanvElmInList(const long chart_id,const string name)
  {
   CArrayObj *list=CSelect::ByGraphCanvElementProperty(this.GetListCanvElm(),CANV_ELEMENT_PROP_CHART_ID,chart_id,EQUAL);
   list=CSelect::ByGraphCanvElementProperty(list,CANV_ELEMENT_PROP_NAME_OBJ,name,EQUAL);
   return(list==NULL || list.Total()==0 ? false : true);
  }
//+------------------------------------------------------------------+

В метод передаются идентификатор графика и имя объекта, наличие которого в списке необходимо проверить.
Далее получаем список объектов с указанным идентификатором графика, а затем фильтруем полученный список по искомому имени.
Если список не был получен, или он пустой, то возвращаем false — объекта нет в списке, иначе — возвращаем true — объект найден.

Обработчик событий. Здесь мы добавим вызов обработчика событий из списка стандартных графических объектов и обработку событий мышки графических элементов на канвасе:

//+------------------------------------------------------------------+
//| Обработчик событий                                               |
//+------------------------------------------------------------------+
void CGraphElementsCollection::OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
   CGStdGraphObj *obj_std=NULL;  // Указатель на стандартный графический объект
   CGCnvElement  *obj_cnv=NULL;  // Указатель на объект графического элемента на канвасе
   ushort idx=ushort(id-CHARTEVENT_CUSTOM);
   if(id==CHARTEVENT_OBJECT_CHANGE  || id==CHARTEVENT_OBJECT_DRAG    || id==CHARTEVENT_OBJECT_CLICK   ||
      idx==CHARTEVENT_OBJECT_CHANGE || idx==CHARTEVENT_OBJECT_DRAG   || idx==CHARTEVENT_OBJECT_CLICK)
     {
      //--- Рассчитаем идентификатор графика
      //--- Если id события соответствует событию с текущего графика, то идентификатор графика получаем от ChartID
      //--- Если id события соответствует пользовательскому событию, то идентификатор графика получаем из lparam
      //--- Иначе - идентификатору графика присваиваем -1
      long param=(id==CHARTEVENT_OBJECT_CLICK ? ::ChartID() : idx==CHARTEVENT_OBJECT_CLICK ? lparam : WRONG_VALUE);
      long chart_id=(param==WRONG_VALUE ? (lparam==0 ? ::ChartID() : lparam) : param);
      //--- Получим объект из списка-коллекции по его имени, записанном в sparam,
      //--- свойства которого изменены, или который был перемещён
      obj_std=this.GetStdGraphObject(sparam,chart_id);
      //--- Если объект не удалось получить по имени - он отсутствует в списке,
      //--- а значит его имя было изменено
      if(obj_std==NULL)
        {
         //--- Найдём в списке объект, которого нет на графике
         obj_std=this.FindMissingObj(chart_id);
         //--- Если и тут не удалось найти объект - уходим
         if(obj_std==NULL)
            return;
         //--- Получим имя переименованного  графического объекта на графике, которого нет в списке-коллекции
         string name_new=this.FindExtraObj(chart_id);
         //--- установим новое имя объекту в списке-коллекции, которому не соответствует ни один графический объект на графике,
         //--- и отправим событие с новым именем объекта на график управляющей программы
         if(obj_std.SetNamePrev(obj_std.Name()) && obj_std.SetName(name_new))
            ::EventChartCustom(this.m_chart_id_main,GRAPH_OBJ_EVENT_RENAME,obj_std.ChartID(),obj_std.TimeCreate(),obj_std.Name());
        }
      //--- Обновим свойства полученного объекта
      //--- и проверим их изменение
      obj_std.PropertiesRefresh();
      obj_std.PropertiesCheckChanged();
     }
//--- Обработка событий стандартных графических объектов в списке-коллекции
   for(int i=0;i<this.m_list_all_graph_obj.Total();i++)
     {
      //--- Получаем очередной графический объект и
      obj_std=this.m_list_all_graph_obj.At(i);
      if(obj_std==NULL)
         continue;
      //--- вызываем его обработчик событий
      obj_std.OnChartEvent((id<CHARTEVENT_CUSTOM ? id : idx),lparam,dparam,sparam);
     }

//--- Обработка событий мышки графических объектов на канвасе
   if(id==CHARTEVENT_MOUSE_MOVE || idx==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Получаем список графических элементов с установленным флагом взаимодействия (должен быть тоько один объект)
      CArrayObj *list=CSelect::ByGraphCanvElementProperty(GetListCanvElm(),CANV_ELEMENT_PROP_INTERACTION,true,EQUAL);
      //--- Если список получить не удалось, или он пустой
      if(list==NULL || list.Total()==0)
        {
         //--- В цикле по списку графических элементов
         for(int i=0;i<this.m_list_all_canv_elm_obj.Total();i++)
           {
            //--- Получаем очередной элемент и вызываем его обработчик событий
            obj_cnv=this.m_list_all_canv_elm_obj.At(i);
            if(obj_cnv==NULL)
               continue;
            //--- В обработчике события будет установлен флаг взаимодействия, если курсор на форме и зажата кнопка мыши
            obj_cnv.OnChartEvent(CHARTEVENT_MOUSE_MOVE,lparam,dparam,sparam);
           }
        }
      //--- Если список получить удалось
      if(list!=NULL)
        {
         //--- Получаем единственный объект из него
         obj_cnv=list.At(0);
         //--- Если объект получен, и это объект-форма
         if(obj_cnv!=NULL && obj_cnv.TypeGraphElement()==GRAPH_ELEMENT_TYPE_FORM)
           {
            //--- Создаём указатель на полученный объект-форму и, если указатель получен
            CForm *form=obj_cnv;
            if(form!=NULL)
              {
               //--- запрещаем перемещение графика мышью и отключаем контекстное меню графика и инструмент "Перекрестие"
               form.SetChartTools(false);
               form.OnChartEvent(CHARTEVENT_MOUSE_MOVE,lparam,dparam,sparam);
              }
           }
        }
     }

//--- Обработка изменения графика для расширенных стандартных объектов
   if(id==CHARTEVENT_CHART_CHANGE || idx==CHARTEVENT_CHART_CHANGE)
     {
      CArrayObj *list=this.GetListStdGraphObjectExt();
      if(list!=NULL)
        {
         for(int i=0;i<list.Total();i++)
           {
            obj_std=list.At(i);
            if(obj_std==NULL)
               continue;
            obj_std.OnChartEvent(CHARTEVENT_CHART_CHANGE,lparam,dparam,sparam);
           }
        }
     }
  }
//+------------------------------------------------------------------+

В листинге блок кода достаточно подробно прокомментирован. Смысл тут в чём... Нам важно иметь только один объект-форму, с которым мы сможем взаимодействовать мышкой. Соответственно, сначала мы проверяем есть ли такой объект, и если окажется, что он есть, то далее работаем только в его обработчике событий.

Метод, устанавливающий для указанного графика флаги прокрутки чарта колёсиком мышки,  контекстного меню и инструмента "перекрестие":

//+------------------------------------------------------------------+
//| Устанавливает для указанного графика флаги прокрутки чарта       |
//| колёсиком мышки,  контекстного меню и инструмента "перекрестие"  |
//+------------------------------------------------------------------+
void CGraphElementsCollection::SetChartTools(const long chart_id,const bool flag)
  {
   ::ChartSetInteger(chart_id,CHART_MOUSE_SCROLL,flag);
   ::ChartSetInteger(chart_id,CHART_CONTEXT_MENU,flag);
   ::ChartSetInteger(chart_id,CHART_CROSSHAIR_TOOL,flag);
  }
//+------------------------------------------------------------------+

Метод нам уже знаком по ранее рассмотренным аналогичным. В этом методе кроме флага передаётся ещё и идентификатор требуемого графика.

Чтобы мы могли работать со списком-коллекцией графических элементов, нам необходимо дать доступ к ним из программы. Делаем мы это всегда в главном классе библиотеки CEngine в файле \MQL5\Include\DoEasy\Engine.mqh.

Пока для тестирования нам достаточно добавить всего два публичных метода:

//--- Возвращает класс объекта расширенного стандартного графического объекта по имени и идентификатору графика
   CGStdGraphObj       *GraphGetStdGraphObjectExt(const string name,const long chart_id)
                          {
                           CArrayObj *list=this.m_graph_objects.GetListStdGraphObjectExt();
                           string nm=(::StringFind(name,this.ProgramName()+"_")==WRONG_VALUE ? this.ProgramName()+"_"+name : name);
                           list=CSelect::ByGraphicStdObjectProperty(list,GRAPH_OBJ_PROP_NAME,0,nm,EQUAL);
                           return(list!=NULL ? list.At(0) : NULL);
                          }

//--- Возвращает список графических элементов на канвасе
   CArrayObj           *GetListCanvElement(void)                           { return this.m_graph_objects.GetListCanvElm();                }
//--- Добавляет графический элемент на канвасе в коллекцию
   bool                 GraphAddCanvElmToCollection(CGCnvElement *element) { return this.m_graph_objects.AddCanvElmToCollection(element); }
   
//--- Заполняет массив идентификаторами графиков, открытых в терминале
   void              GraphGetArrayChartsID(long &array_charts_id[])
                       {
                        CArrayObj *list=this.m_graph_objects.GetListChartsControl();
                        if(list==NULL)
                           return;
                        ::ArrayResize(array_charts_id,list.Total());
                        ::ArrayInitialize(array_charts_id,WRONG_VALUE);
                        for(int i=0;i<list.Total();i++)
                          {
                           CChartObjectsControl *obj=list.At(i);
                           if(obj==NULL)
                              continue;
                           array_charts_id[i]=obj.ChartID();
                          }
                       }

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

И это всё, что нам сегодня необходимо для проверки работоспособности созданного функционала.


Тестирование

Для тестирования возьмём советник из прошлой статьи и сохраним его в новой папке \MQL5\Experts\TestDoEasy\Part96\ под новым именем TestDoEasyPart96.mq5.

Из списка глобальных переменных советника удалим список для хранения объектов-форм:

//--- global variables
CEngine        engine;
CArrayObj      list_forms;  
color          array_clr[];

Список этот нам не нужен потому, что теперь создаваемые формы будем размещать в список-коллекцию библиотеки.

В обработчик OnInit() добавим блок кода с циклом создания двух объектов-форм:

//+------------------------------------------------------------------+
//|                                             TestDoEasyPart96.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
//--- includes
#include <DoEasy\Engine.mqh>
//--- defines
#define        FORMS_TOTAL (4)   // Количество создаваемых форм
#define        START_X     (4)   // Начальная координата X фигуры
#define        START_Y     (4)   // Начальная координата Y фигуры
#define KEY_LEFT           (188) // Влево
#define KEY_RIGHT          (190) // Вправо
#define KEY_ORIGIN         (191) // Изначальные свойства
//--- input parameters
sinput   bool              InpMovable     =  true;          // Movable forms flag
sinput   ENUM_INPUT_YES_NO InpUseColorBG  =  INPUT_YES;     // Use chart background color to calculate shadow color
sinput   color             InpColorForm3  =  clrCadetBlue;  // Third form shadow color (if not background color) 
//--- global variables
CEngine        engine;
color          array_clr[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Установка глобальных переменных советника
   ArrayResize(array_clr,2);        // Массив цветов градиентной заливки
   array_clr[0]=C'26,100,128';      // Исходный ≈Тёмно-лазурный цвет
   array_clr[1]=C'35,133,169';      // Осветлённый исходный цвет
//--- Создадим массив с текущим символом и установим его для использования в библиотеке
   string array[1]={Symbol()};
   engine.SetUsedSymbols(array);
   //--- Создадим объект-таймсерию для текущего символа и периода и выведем его описание в журнал
   engine.SeriesCreate(Symbol(),Period());
   engine.GetTimeSeriesCollection().PrintShort(false); // Краткие описания
//--- Создадим объекты-формы
   for(int i=0;i<2;i++)
     {
      //--- При создании объекта передаём в него все требуемые параметры
      CForm *form=new CForm("Form_0"+string(i+1),30,(i==0 ? 80 : 150),100,30);
      if(form==NULL)
         continue;
      //--- Установим форме флаги активности, и перемещаемости
      form.SetActive(true);
      form.SetMovable(true);
      //--- Установим форме её идентификатор и номер в списке объектов
      form.SetID(i);
      form.SetNumber(0);   // (0 - означает главный объект-форма) К главному объекту могут прикрепляться второстепенные, которыми он будет управлять
      //--- Установим непрозрачность 200
      form.SetOpacity(245);
      //--- Цвет фона формы зададим как первый цвет из массива цветов
      form.SetColorBackground(array_clr[0]);
      //--- Цвет очерчивающей рамки формы
      form.SetColorFrame(clrDarkBlue);
      //--- Установим флаг рисования тени
      form.SetShadow(false);
      //--- Рассчитаем цвет тени как цвет фона графика, преобразованный в монохромный
      color clrS=form.ChangeColorSaturation(form.ColorBackground(),-100);
      //--- Если в настройках задано использовать цвет фона графика, то затемним монохромный цвет на 20 единиц
      //--- Иначе - будем использовать для рисования тени заданный в настройках цвет
      color clr=(InpUseColorBG ? form.ChangeColorLightness(clrS,-20) : InpColorForm3);
      //--- Нарисуем тень формы со смещением от формы вправо-вниз на три пикселя по всем осям
      //--- Непрозрачность тени при этом установим равной 200, а радиус размытия равный 4
      form.DrawShadow(3,3,clr,200,4);
      //--- Зальём фон формы вертикальным градиентом
      form.Erase(array_clr,form.Opacity(),true);
      //--- Нарисуем очерчивающий прямоугольник по краям формы
      form.DrawRectangle(0,0,form.Width()-1,form.Height()-1,form.ColorFrame(),form.Opacity());
      form.Done();
      
      //--- Выведем текст с описанием типа градиента и обновим форму
      //--- Параметры текста: координаты текста в центре формы и точка привязки - тоже по центру
      //--- Создаём новый кадр текстовой анимации с идентификатором 0 и выводим текст на форму
      form.TextOnBG(0,TextByLanguage("Тест 0","Test 0")+string(i+1),form.Width()/2,form.Height()/2,FRAME_ANCHOR_CENTER,C'211,233,149',255,true,true);
      //--- Добавим форму в список
      if(!engine.GraphAddCanvElmToCollection(form))
         delete form;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

Здесь всё подробно прокомментировано, да и мы уже рассматривали такое создание объектов-форм в некоторых предыдущих статьях.
В цикле создаются две формы, устанавливаются для них параметры отображения, и указатели на формы помещаются в список-коллекцию библиотеки.

Скомпилируем советник и запустим его на графике. Будут созданы две формы, которые мы можем перемещать мышкой независимо друг от друга. Каждая текущая форма всегда располагается поверх других объектов — находится на переднем плане, а данные о выбранной форме отображаются в комментариях на графике:


Что мы видим: формы возможно перемещать независимо друг от друга, график при этом не двигается. Каждая активная форма находится всегда на переднем плане. Но есть и существенные недостатки: при перемещении графика мышью, если курсор заходит в область формы, она становится активной и перехватывает управление на себя. Не всегда верно рассчитываются смещения координат курсора от точки начала координат формы после перемещения графика мышью.

Все недостатки будем находить и устранять в процессе дальнейшей разработки.


Что дальше

В следующей статье продолжим работу над событиями и взаимодействием форм и мышки.

Ниже прикреплены все файлы текущей версии библиотеки, файлы тестового советника и индикатора контроля событий графиков для MQL5. Их можно скачать и протестировать всё самостоятельно. При возникновении вопросов, замечаний и пожеланий вы можете озвучить их в комментариях к статье.

К содержанию

*Статьи этой серии:

Графика в библиотеке DoEasy (Часть 93): Готовим функционал для создания составных графических объектов
Графика в библиотеке DoEasy (Часть 94): Составные графические объекты, перемещение и удаление
Графика в библиотеке DoEasy (Часть 95): Элементы управления составными графическими объектами

Прикрепленные файлы |
MQL5.zip (4291.31 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (4)
thebeno
thebeno | 12 февр. 2022 в 19:50

Hi Artyom,

could you please create one ZIP file with all your DoEasy files? Includes and all TestDoEasy indicators and experts?

Usualy it is only one test indicator or expert in ZIP file which belongs to that part. Thanks a lot.

Marcel Fitzner
Marcel Fitzner | 17 февр. 2022 в 13:21
Yes, that would be wonderful!
Artyom Trishkin
Artyom Trishkin | 17 февр. 2022 в 13:57
thebeno #:

Hi Artyom,

could you please create one ZIP file with all your DoEasy files? Includes and all TestDoEasy indicators and experts?

Usualy it is only one test indicator or expert in ZIP file which belongs to that part. Thanks a lot.

Marcel Fitzner #:
Yes, that would be wonderful!

This will not give a result, since each article has its own test program, which will no longer be able to work in the new version of the library. The library is under development, and these stages are described in the articles. Therefore, any versions incompatible with the previous articles are always possible.
Once development is complete, there will be many use cases. That's when it will be possible to collect all the examples in one archive, since they will all be made on the current version of the library.

Marcel Fitzner
Marcel Fitzner | 19 февр. 2022 в 12:58

Ok, mate! Thanks for your reply. So long, we will be learning from what you're developing. Cheers!

Веб-проекты (Часть II): Система авторизации Laravel/Nuxt Веб-проекты (Часть II): Система авторизации Laravel/Nuxt
В этой статье создадим систему авторизации через браузерное приложение и через торговый терминал MetaTrader 5. Можно будет зарегистрироваться в системе, указав свои учётные данные.
Матрицы и векторы в MQL5 Матрицы и векторы в MQL5
Специальные типы данных matrix и vector позволяют писать код, приближенный к математической записи. Это избавляет от необходимости создавать вложенные циклы и помнить о правильной индексации массивов, которые участвуют в вычислении. Таким образом повышается надежность и скорость разработки сложных программ.
Использование класса CCanvas в MQL приложениях Использование класса CCanvas в MQL приложениях
Статья об использовании класса CCanvas в MQL приложениях с подробным разбором и примерами, что даёт пользователю понимание основ работы с данным инструментом
Веб-проекты (Часть I): Создание веб-приложения в схеме Laravel/Nuxt/MetaTrader 5 Веб-проекты (Часть I): Создание веб-приложения в схеме Laravel/Nuxt/MetaTrader 5
Разработчики MetaTrader 5 предоставили MQL-сообществу множество технологических решений, что даёт возможность реализовывать сложные программные комплексы, схемы которых могут выходить даже за рамки «песочницы» локального компьютера.