Русский 中文 Español Deutsch 日本語 Português
Graphics in DoEasy library (Part 96): Graphics in form objects and handling mouse events

Graphics in DoEasy library (Part 96): Graphics in form objects and handling mouse events

MetaTrader 5Examples | 30 March 2022, 12:46
5 913 0
Artyom Trishkin
Artyom Trishkin

Contents


Concept

In the previous article, I added the controls for managing base graphical object anchor points in order to handle composite graphical objects. My idea is that moving such controls will entail relocation of the base graphical object anchor point, thus changing its spatial orientation within a chart. In order to move these control points with a mouse, we need to create mouse event handlers for the canvas objects (graphical element and form object). When hovering the mouse cursor over the form object, it should know about that and change its properties. Additionally, it should be considered whether the user keeps the mouse button pressed. If we press the mouse button within a form object and start moving it, chart scrolling by the mouse should be disabled (together with the crosshairs tool and the chart context menu), while the form itself should follow the cursor.

The remaining form objects should not react when the mouse with the pressed button reaches them. If we press the mouse button outside any form and start moving the cursor, the entire chart is moved (if allowed in the settings), while form objects should not react when the cursor with the pressed button reaches them to avoid relocation of forms.
In the coming articles, I will gradually create the same functionality for form objects and continue the development of composite graphical objects.

Besides, I will improve the symbol object class since the chart symbols now have new properties to be considered and tracked. The new properties are not so numerous, but the content of some properties is pretty considerable in terms of the number of enumeration constants describing these properties (ENUM_SYMBOL_SECTOR, ENUM_SYMBOL_INDUSTRY). Therefore, there will be multiple new message indices for the library message class and the methods returning the property descriptions will be quite large as well.


Improving library classes

In \MQL5\Include\DoEasy\Data.mqh, add the new message indices:

//--- CSymbol
   MSG_SYM_PROP_INDEX,                                // Index in \"Market Watch window\"
   MSG_SYM_PROP_SECTOR,                               // Economic sector
   MSG_SYM_PROP_INDUSTRY,                             // Industry or economy branch
   MSG_SYM_PROP_CUSTOM,                               // Custom symbol
   MSG_SYM_PROP_CHART_MODE,                           // Price type used for generating symbols bars
   MSG_SYM_PROP_EXIST,                                // Symbol with this name exists
   MSG_SYM_PROP_SELECT,                               // Symbol selected in Market Watch
   MSG_SYM_PROP_VISIBLE,                              // Symbol visible in Market Watch
   MSG_SYM_PROP_SESSION_DEALS,                        // Number of deals in the current session
   MSG_SYM_PROP_SESSION_BUY_ORDERS,                   // Number of Buy orders at the moment
   MSG_SYM_PROP_SESSION_SELL_ORDERS,                  // Number of Sell orders at the moment
   MSG_SYM_PROP_VOLUME,                               // Volume of the last deal
   MSG_SYM_PROP_VOLUMEHIGH,                           // Maximal day volume
   MSG_SYM_PROP_VOLUMELOW,                            // Minimal day volume
   MSG_SYM_PROP_TIME,                                 // Latest quote time
   MSG_SYM_PROP_TIME_MSC,                             // Time of the last quote in milliseconds
   MSG_SYM_PROP_DIGITS,                               // Number of decimal places
   MSG_SYM_PROP_DIGITS_LOTS,                          // Digits after a decimal point in the value of the lot

...

   MSG_SYM_PROP_SESSION_PRICE_LIMIT_MAX,              // Maximum session price
   MSG_SYM_PROP_MARGIN_HEDGED,                        // Size of a contract or margin for one lot of hedged positions
   
   MSG_SYM_PROP_PRICE_CHANGE,                         // Change of the current price relative to the end of the previous trading day in %
   MSG_SYM_PROP_PRICE_VOLATILITY,                     // Price volatility in %
   MSG_SYM_PROP_PRICE_THEORETICAL,                    // Theoretical option price
   MSG_SYM_PROP_PRICE_DELTA,                          // Option/warrant delta
   MSG_SYM_PROP_PRICE_THETA,                          // Option/warrant theta
   MSG_SYM_PROP_PRICE_GAMMA,                          // Option/warrant gamma
   MSG_SYM_PROP_PRICE_VEGA,                           // Option/warrant vega
   MSG_SYM_PROP_PRICE_RHO,                            // Option/warrant rho
   MSG_SYM_PROP_PRICE_OMEGA,                          // Option/warrant omega
   MSG_SYM_PROP_PRICE_SENSITIVITY,                    // Option/warrant sensitivity
   //---
   MSG_SYM_PROP_NAME,                                 // Symbol name
   MSG_SYM_PROP_BASIS,                                // Underlying asset of derivative
   MSG_SYM_PROP_COUNTRY,                              // Country
   MSG_SYM_PROP_SECTOR_NAME,                          // Economic sector
   MSG_SYM_PROP_INDUSTRY_NAME,                        // Economy or industry branch
   MSG_SYM_PROP_CURRENCY_BASE,                        // Basic currency of symbol
   MSG_SYM_PROP_CURRENCY_PROFIT,                      // Profit currency
   MSG_SYM_PROP_CURRENCY_MARGIN,                      // Margin currency
   MSG_SYM_PROP_BANK,                                 // Feeder of the current quote
   MSG_SYM_PROP_DESCRIPTION,                          // Symbol description
   MSG_SYM_PROP_FORMULA,                              // Formula used for custom symbol pricing
   MSG_SYM_PROP_ISIN,                                 // Symbol name in ISIN system
   MSG_SYM_PROP_PAGE,                                 // Address of web page containing symbol information
   MSG_SYM_PROP_PATH,                                 // Location in symbol tree
   MSG_SYM_PROP_CAYEGORY,                             // Symbol category
   MSG_SYM_PROP_EXCHANGE,                             // Name of an exchange a symbol is traded on
   //---

...

   //---
   MSG_SYM_EVENT_SYMBOL_ADD,                          // Added symbol to Market Watch window
   MSG_SYM_EVENT_SYMBOL_DEL,                          // Symbol removed from Market Watch window
   MSG_SYM_EVENT_SYMBOL_SORT,                         // Changed location of symbols in Market Watch window
   MSG_SYM_SYMBOLS_MODE_CURRENT,                      // Work with current symbol only
   MSG_SYM_SYMBOLS_MODE_DEFINES,                      // Work with predefined symbol list
   MSG_SYM_SYMBOLS_MODE_MARKET_WATCH,                 // Work with Market Watch window symbols
   MSG_SYM_SYMBOLS_MODE_ALL,                          // Work with full list of all available symbols
   MSG_SYM_SYMBOLS_BOOK_ADD,                          // Subscribed to Depth of Market 
   MSG_SYM_SYMBOLS_BOOK_DEL,                          // Unsubscribed from Depth of Market 
   MSG_SYM_SYMBOLS_MODE_BOOK,                         // Subscription to Depth of Market
   MSG_SYM_SYMBOLS_ERR_BOOK_ADD,                      // Error subscribing to DOM 
   MSG_SYM_SYMBOLS_ERR_BOOK_DEL,                      // Error unsubscribing from DOM
   
   //--- ENUM_SYMBOL_SECTOR
   MSG_SYM_SECTOR_UNDEFINED,                          // Undefined
   MSG_SYM_SECTOR_BASIC_MATERIALS,                    // Basic materials
   MSG_SYM_SECTOR_COMMUNICATION_SERVICES,             // Communication services
   MSG_SYM_SECTOR_CONSUMER_CYCLICAL,                  // Consumer cyclical
   MSG_SYM_SECTOR_CONSUMER_DEFENSIVE,                 // Consumer defensive
   MSG_SYM_SECTOR_CURRENCY,                           // Currencies
   MSG_SYM_SECTOR_CURRENCY_CRYPTO,                    // Cryptocurrencies
   MSG_SYM_SECTOR_ENERGY,                             // Energy
   MSG_SYM_SECTOR_FINANCIAL,                          // Finance
   MSG_SYM_SECTOR_HEALTHCARE,                         // Healthcare
   MSG_SYM_SECTOR_INDUSTRIALS,                        // Industrials
   MSG_SYM_SECTOR_REAL_ESTATE,                        // Real estate
   MSG_SYM_SECTOR_TECHNOLOGY,                         // Technology
   MSG_SYM_SECTOR_UTILITIES,                          // Utilities
   MSG_SYM_SECTOR_INDEXES,                            // Indices
   MSG_SYM_SECTOR_COMMODITIES,                        // Commodities
   
   //--- ENUM_SYMBOL_INDUSTRY
   MSG_SYM_INDUSTRY_UNDEFINED,                        // Undefined
   //--- Basic materials
   MSG_SYM_INDUSTRY_AGRICULTURAL_INPUTS,              // Agricultural inputs
   MSG_SYM_INDUSTRY_ALUMINIUM,                        // Aluminium
   MSG_SYM_INDUSTRY_BUILDING_MATERIALS,               // Building materials
   MSG_SYM_INDUSTRY_CHEMICALS,                        // Chemicals
   MSG_SYM_INDUSTRY_COKING_COAL,                      // Coking coal
   MSG_SYM_INDUSTRY_COPPER,                           // Copper
   MSG_SYM_INDUSTRY_GOLD,                             // Gold
   MSG_SYM_INDUSTRY_LUMBER_WOOD,                      // Lumber and wood production
   MSG_SYM_INDUSTRY_INDUSTRIAL_METALS,                // Other industrial metals and mining
   MSG_SYM_INDUSTRY_PRECIOUS_METALS,                  // Other precious metals and mining
   MSG_SYM_INDUSTRY_PAPER,                            // Paper and paper products
   MSG_SYM_INDUSTRY_SILVER,                           // Silver
   MSG_SYM_INDUSTRY_SPECIALTY_CHEMICALS,              // Specialty chemicals
   MSG_SYM_INDUSTRY_STEEL,                            // Steel
   //--- Communication services
   MSG_SYM_INDUSTRY_ADVERTISING,                      // Advertising agencies
   MSG_SYM_INDUSTRY_BROADCASTING,                     // Broadcasting
   MSG_SYM_INDUSTRY_GAMING_MULTIMEDIA,                // Electronic gaming and multimedia
   MSG_SYM_INDUSTRY_ENTERTAINMENT,                    // Entertainment
   MSG_SYM_INDUSTRY_INTERNET_CONTENT,                 // Internet content and information
   MSG_SYM_INDUSTRY_PUBLISHING,                       // Publishing
   MSG_SYM_INDUSTRY_TELECOM,                          // Telecom services
   //--- Consumer cyclical
   MSG_SYM_INDUSTRY_APPAREL_MANUFACTURING,            // Apparel manufacturing
   MSG_SYM_INDUSTRY_APPAREL_RETAIL,                   // Apparel retail
   MSG_SYM_INDUSTRY_AUTO_MANUFACTURERS,               // Auto manufacturers
   MSG_SYM_INDUSTRY_AUTO_PARTS,                       // Auto parts
   MSG_SYM_INDUSTRY_AUTO_DEALERSHIP,                  // Auto and truck dealerships
   MSG_SYM_INDUSTRY_DEPARTMENT_STORES,                // Department stores
   MSG_SYM_INDUSTRY_FOOTWEAR_ACCESSORIES,             // Footwear and accessories
   MSG_SYM_INDUSTRY_FURNISHINGS,                      // Furnishing, fixtures and appliances
   MSG_SYM_INDUSTRY_GAMBLING,                         // Gambling
   MSG_SYM_INDUSTRY_HOME_IMPROV_RETAIL,               // Home improvement retail
   MSG_SYM_INDUSTRY_INTERNET_RETAIL,                  // Internet retail
   MSG_SYM_INDUSTRY_LEISURE,                          // Leisure
   MSG_SYM_INDUSTRY_LODGING,                          // Lodging
   MSG_SYM_INDUSTRY_LUXURY_GOODS,                     // Luxury goods
   MSG_SYM_INDUSTRY_PACKAGING_CONTAINERS,             // Packaging and containers
   MSG_SYM_INDUSTRY_PERSONAL_SERVICES,                // Personal services
   MSG_SYM_INDUSTRY_RECREATIONAL_VEHICLES,            // Recreational vehicles
   MSG_SYM_INDUSTRY_RESIDENT_CONSTRUCTION,            // Residential construction
   MSG_SYM_INDUSTRY_RESORTS_CASINOS,                  // Resorts and casinos
   MSG_SYM_INDUSTRY_RESTAURANTS,                      // Restaurants
   MSG_SYM_INDUSTRY_SPECIALTY_RETAIL,                 // Specialty retail
   MSG_SYM_INDUSTRY_TEXTILE_MANUFACTURING,            // Textile manufacturing
   MSG_SYM_INDUSTRY_TRAVEL_SERVICES,                  // Travel services
   //--- Consumer defensive
   MSG_SYM_INDUSTRY_BEVERAGES_BREWERS,                // Beverages - Brewers
   MSG_SYM_INDUSTRY_BEVERAGES_NON_ALCO,               // Beverages - Non-alcoholic
   MSG_SYM_INDUSTRY_BEVERAGES_WINERIES,               // Beverages - Wineries and distilleries
   MSG_SYM_INDUSTRY_CONFECTIONERS,                    // Confectioners
   MSG_SYM_INDUSTRY_DISCOUNT_STORES,                  // Discount stores
   MSG_SYM_INDUSTRY_EDUCATION_TRAINIG,                // Education and training services
   MSG_SYM_INDUSTRY_FARM_PRODUCTS,                    // Farm products
   MSG_SYM_INDUSTRY_FOOD_DISTRIBUTION,                // Food distribution
   MSG_SYM_INDUSTRY_GROCERY_STORES,                   // Grocery stores
   MSG_SYM_INDUSTRY_HOUSEHOLD_PRODUCTS,               // Household and personal products
   MSG_SYM_INDUSTRY_PACKAGED_FOODS,                   // Packaged foods
   MSG_SYM_INDUSTRY_TOBACCO,                          // Tobacco
   //--- Energy
   MSG_SYM_INDUSTRY_OIL_GAS_DRILLING,                 // Oil and gas drilling
   MSG_SYM_INDUSTRY_OIL_GAS_EP,                       // Oil and gas extraction and processing
   MSG_SYM_INDUSTRY_OIL_GAS_EQUIPMENT,                // Oil and gas equipment and services
   MSG_SYM_INDUSTRY_OIL_GAS_INTEGRATED,               // Oil and gas integrated
   MSG_SYM_INDUSTRY_OIL_GAS_MIDSTREAM,                // Oil and gas midstream
   MSG_SYM_INDUSTRY_OIL_GAS_REFINING,                 // Oil and gas refining and marketing
   MSG_SYM_INDUSTRY_THERMAL_COAL,                     // Thermal coal
   MSG_SYM_INDUSTRY_URANIUM,                          // Uranium
   //--- Finance
   MSG_SYM_INDUSTRY_EXCHANGE_TRADED_FUND,             // Exchange traded fund
   MSG_SYM_INDUSTRY_ASSETS_MANAGEMENT,                // Assets management
   MSG_SYM_INDUSTRY_BANKS_DIVERSIFIED,                // Banks - Diversified
   MSG_SYM_INDUSTRY_BANKS_REGIONAL,                   // Banks - Regional
   MSG_SYM_INDUSTRY_CAPITAL_MARKETS,                  // Capital markets
   MSG_SYM_INDUSTRY_CLOSE_END_FUND_DEBT,              // Closed-End fund - Debt
   MSG_SYM_INDUSTRY_CLOSE_END_FUND_EQUITY,            // Closed-end fund - Equity
   MSG_SYM_INDUSTRY_CLOSE_END_FUND_FOREIGN,           // Closed-end fund - Foreign
   MSG_SYM_INDUSTRY_CREDIT_SERVICES,                  // Credit services
   MSG_SYM_INDUSTRY_FINANCIAL_CONGLOMERATE,           // Financial conglomerates
   MSG_SYM_INDUSTRY_FINANCIAL_DATA_EXCHANGE,          // Financial data and stock exchange
   MSG_SYM_INDUSTRY_INSURANCE_BROKERS,                // Insurance brokers
   MSG_SYM_INDUSTRY_INSURANCE_DIVERSIFIED,            // Insurance - Diversified
   MSG_SYM_INDUSTRY_INSURANCE_LIFE,                   // Insurance - Life
   MSG_SYM_INDUSTRY_INSURANCE_PROPERTY,               // Insurance - Property and casualty
   MSG_SYM_INDUSTRY_INSURANCE_REINSURANCE,            // Insurance - Reinsurance
   MSG_SYM_INDUSTRY_INSURANCE_SPECIALTY,              // Insurance - Specialty
   MSG_SYM_INDUSTRY_MORTGAGE_FINANCE,                 // Mortgage finance
   MSG_SYM_INDUSTRY_SHELL_COMPANIES,                  // Shell companies
   //--- Healthcare
   MSG_SYM_INDUSTRY_BIOTECHNOLOGY,                    // Biotechnology
   MSG_SYM_INDUSTRY_DIAGNOSTICS_RESEARCH,             // Diagnostics and research
   MSG_SYM_INDUSTRY_DRUGS_MANUFACTURERS,              // Drugs manufacturers - general
   MSG_SYM_INDUSTRY_DRUGS_MANUFACTURERS_SPEC,         // Drugs manufacturers - Specialty and generic
   MSG_SYM_INDUSTRY_HEALTHCARE_PLANS,                 // Healthcare plans
   MSG_SYM_INDUSTRY_HEALTH_INFORMATION,               // Health information services
   MSG_SYM_INDUSTRY_MEDICAL_FACILITIES,               // Medical care facilities
   MSG_SYM_INDUSTRY_MEDICAL_DEVICES,                  // Medical devices
   MSG_SYM_INDUSTRY_MEDICAL_DISTRIBUTION,             // Medical distribution
   MSG_SYM_INDUSTRY_MEDICAL_INSTRUMENTS,              // Medical instruments and supplies
   MSG_SYM_INDUSTRY_PHARM_RETAILERS,                  // Pharmaceutical retailers
   //--- Industrials
   MSG_SYM_INDUSTRY_AEROSPACE_DEFENSE,                // Aerospace and defense
   MSG_SYM_INDUSTRY_AIRLINES,                         // Airlines
   MSG_SYM_INDUSTRY_AIRPORTS_SERVICES,                // Airports and air services
   MSG_SYM_INDUSTRY_BUILDING_PRODUCTS,                // Building products and equipment
   MSG_SYM_INDUSTRY_BUSINESS_EQUIPMENT,               // Business equipment and supplies
   MSG_SYM_INDUSTRY_CONGLOMERATES,                    // Сonglomerates
   MSG_SYM_INDUSTRY_CONSULTING_SERVICES,              // Consulting services
   MSG_SYM_INDUSTRY_ELECTRICAL_EQUIPMENT,             // Electrical equipment and parts
   MSG_SYM_INDUSTRY_ENGINEERING_CONSTRUCTION,         // Engineering and construction
   MSG_SYM_INDUSTRY_FARM_HEAVY_MACHINERY,             // Farm and heavy construction machinery
   MSG_SYM_INDUSTRY_INDUSTRIAL_DISTRIBUTION,          // Industrial distribution
   MSG_SYM_INDUSTRY_INFRASTRUCTURE_OPERATIONS,        // Infrastructure operations
   MSG_SYM_INDUSTRY_FREIGHT_LOGISTICS,                // Integrated freight and logistics
   MSG_SYM_INDUSTRY_MARINE_SHIPPING,                  // Marine shipping
   MSG_SYM_INDUSTRY_METAL_FABRICATION,                // Metal fabrication
   MSG_SYM_INDUSTRY_POLLUTION_CONTROL,                // Pollution and treatment controls
   MSG_SYM_INDUSTRY_RAILROADS,                        // Railroads
   MSG_SYM_INDUSTRY_RENTAL_LEASING,                   // Rental and leasing services
   MSG_SYM_INDUSTRY_SECURITY_PROTECTION,              // Security and protection services
   MSG_SYM_INDUSTRY_SPEALITY_BUSINESS_SERVICES,       // Specialty business services
   MSG_SYM_INDUSTRY_SPEALITY_MACHINERY,               // Specialty industrial machinery
   MSG_SYM_INDUSTRY_STUFFING_EMPLOYMENT,              // Stuffing and employment services
   MSG_SYM_INDUSTRY_TOOLS_ACCESSORIES,                // Tools and accessories
   MSG_SYM_INDUSTRY_TRUCKING,                         // Trucking
   MSG_SYM_INDUSTRY_WASTE_MANAGEMENT,                 // Waste management
   //--- Real estate
   MSG_SYM_INDUSTRY_REAL_ESTATE_DEVELOPMENT,          // Real estate - Development
   MSG_SYM_INDUSTRY_REAL_ESTATE_DIVERSIFIED,          // Real estate - Diversified
   MSG_SYM_INDUSTRY_REAL_ESTATE_SERVICES,             // Real estate services
   MSG_SYM_INDUSTRY_REIT_DIVERSIFIED,                 // REIT - Diversified
   MSG_SYM_INDUSTRY_REIT_HEALTCARE,                   // REIT - Healthcase facilities
   MSG_SYM_INDUSTRY_REIT_HOTEL_MOTEL,                 // REIT - Hotel and motel
   MSG_SYM_INDUSTRY_REIT_INDUSTRIAL,                  // REIT - Industrial
   MSG_SYM_INDUSTRY_REIT_MORTAGE,                     // REIT - Mortgage
   MSG_SYM_INDUSTRY_REIT_OFFICE,                      // REIT - Office
   MSG_SYM_INDUSTRY_REIT_RESIDENTAL,                  // REIT - Residential
   MSG_SYM_INDUSTRY_REIT_RETAIL,                      // REIT - Retail
   MSG_SYM_INDUSTRY_REIT_SPECIALITY,                  // REIT - Specialty
   //--- Technology
   MSG_SYM_INDUSTRY_COMMUNICATION_EQUIPMENT,          // Communication equipment
   MSG_SYM_INDUSTRY_COMPUTER_HARDWARE,                // Computer hardware
   MSG_SYM_INDUSTRY_CONSUMER_ELECTRONICS,             // Consumer electronics
   MSG_SYM_INDUSTRY_ELECTRONIC_COMPONENTS,            // Electronic components
   MSG_SYM_INDUSTRY_ELECTRONIC_DISTRIBUTION,          // Electronics and computer distribution
   MSG_SYM_INDUSTRY_IT_SERVICES,                      // Information technology services
   MSG_SYM_INDUSTRY_SCIENTIFIC_INSTRUMENTS,           // Scientific and technical instruments
   MSG_SYM_INDUSTRY_SEMICONDUCTOR_EQUIPMENT,          // Semiconductor equipment and materials
   MSG_SYM_INDUSTRY_SEMICONDUCTORS,                   // Semiconductors
   MSG_SYM_INDUSTRY_SOFTWARE_APPLICATION,             // Software - Application
   MSG_SYM_INDUSTRY_SOFTWARE_INFRASTRUCTURE,          // Software - Infrastructure
   MSG_SYM_INDUSTRY_SOLAR,                            // Solar
   //--- Utilities
   MSG_SYM_INDUSTRY_UTILITIES_DIVERSIFIED,            // Utilities - Diversified
   MSG_SYM_INDUSTRY_UTILITIES_POWERPRODUCERS,         // Utilities - Independent power producers
   MSG_SYM_INDUSTRY_UTILITIES_RENEWABLE,              // Utilities - Renewable
   MSG_SYM_INDUSTRY_UTILITIES_REGULATED_ELECTRIC,     // Utilities - Regulated electric
   MSG_SYM_INDUSTRY_UTILITIES_REGULATED_GAS,          // Utilities - Regulated gas
   MSG_SYM_INDUSTRY_UTILITIES_REGULATED_WATER,        // Utilities - Regulated water  

//--- CAccount

and the text messages corresponding to the newly added indices:

//--- CSymbol
   {"Индекс в окне \"Обзор рынка\"","Index in \"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 selected in Market Watch"},
   {"Символ отображается в Market Watch","Symbol 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 last quote"},
   {"Время последней котировки в миллисекундах","Time of the last quote in milliseconds"},
   {"Количество знаков после запятой","Digits after decimal point"},
   {"Количество знаков после запятой в значении лота","Digits after decimal point in 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"},
   {"Имя базового актива для производного инструмента","Underlying asset of derivative"},
   {"Страна","Cuntry"},
   {"Сектор экономики","Sector of the economy"},
   {"Отрасль экономики или вид промышленности","Branch of the economy or type of industry"},
   {"Базовая валюта инструмента","Basic currency of symbol"},
   {"Валюта прибыли","Profit currency"},
   {"Валюта залоговых средств","Margin currency"},
   {"Источник текущей котировки","Feeder of the current quote"},
   {"Описание символа","Symbol description"},
   {"Формула для построения цены пользовательского символа","Formula used for custom symbol pricing"},
   {"Имя торгового символа в системе международных идентификационных кодов","Symbol name in ISIN system"},
   {"Адрес интернет страницы с информацией по символу","Address of web page containing symbol information"},
   {"Путь в дереве символов","Path in 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 symbol to \"Market Watch\" window"},
   {"Из окна \"Обзор рынка\" удалён символ","Removed from \"Market Watch\" window"},
   {"Изменено расположение символов в окне \"Обзор рынка\"","Changed arrangement of symbols in \"Market Watch\" window"},
   {"Работа только с текущим символом","Work only with the current symbol"},
   {"Работа с предопределённым списком символов","Work with predefined list of symbols"},
   {"Работа с символами из окна \"Обзор рынка\"","Working with symbols from \"Market Watch\" window"},
   {"Работа с полным списком всех доступных символов","Work with 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"},
   //--- Basic materials
   {"Сельскохозяйственные ресурсы","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"},
   //--- Communication services
   {"Рекламные агентства","Advertising agencies"},
   {"Вещание","Broadcasting"},
   {"Электронные игры и мультимедиа","Electronic gaming and multimedia"},
   {"Развлечения","Entertainment"},
   {"Интернет-контент и информация","Internet content and information"},
   {"Издательство","Publishing"},
   {"Телекоммуникационные услуги","Telecom services"},
   //--- Consumer cyclical
   {"Производство одежды","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"},
   //--- Consumer defensive
   {"Напитки - Пивовары","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"},
   //--- Energy
   {"Бурение нефтяных и газовых скважин","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"},
   //--- Finance
   {"Биржевой фонд","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"},
   //--- Healthcare
   {"Биотехнологии","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"},
   //--- Industrials
   {"Аэрокосмическая и оборонная промышленность","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
   {"Недвижимость - Строительство","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"},
   //--- Technology
   {"Коммуникационное оборудование","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
   {"Коммунальные предприятия - Диверсифицированные","Utilities - Diversified"},
   {"Коммунальные предприятия - Независимые производители энергии","Utilities - Independent power producers"},
   {"Коммунальные предприятия - Возобновляемая энергия","Utilities - Renewable"},
   {"Коммунальные предприятия - Регулируемые электрические компании","Utilities - Regulated electric"},
   {"Коммунальные предприятия - Регулируемые газовые компании","Utilities - Regulated gas"},
   {"Коммунальные предприятия - Регулируемые водоканалы","Utilities - Regulated water"},
   
//--- CAccount


In \MQL5\Include\DoEasy\Defines.mqh, add the new constants to the enumerations of integer, real and string symbol object properties:

//+------------------------------------------------------------------+
//| Symbol integer properties                                        |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_INTEGER
  {
   SYMBOL_PROP_STATUS = 0,                                  // Symbol status
   SYMBOL_PROP_INDEX_MW,                                    // Symbol index in the Market Watch window
   SYMBOL_PROP_SECTOR,                                      // Sector of the economy the asset belongs to
   SYMBOL_PROP_INDUSTRY,                                    // Industry or the economy branch the symbol belongs to
   SYMBOL_PROP_CUSTOM,                                      // Custom symbol flag
   SYMBOL_PROP_CHART_MODE,                                  // The price type used for generating bars – Bid or Last (from the ENUM_SYMBOL_CHART_MODE enumeration)
   SYMBOL_PROP_EXIST,                                       // Flag indicating that the symbol under this name exists
   SYMBOL_PROP_SELECT,                                      // The indication that the symbol is selected in Market Watch
   SYMBOL_PROP_VISIBLE,                                     // The indication that the symbol is displayed in Market Watch
   SYMBOL_PROP_SESSION_DEALS,                               // The number of deals in the current session 
   SYMBOL_PROP_SESSION_BUY_ORDERS,                          // The total number of Buy orders at the moment
   SYMBOL_PROP_SESSION_SELL_ORDERS,                         // The total number of Sell orders at the moment
   SYMBOL_PROP_VOLUME,                                      // Last deal volume
   SYMBOL_PROP_VOLUMEHIGH,                                  // Maximum volume within a day
   SYMBOL_PROP_VOLUMELOW,                                   // Minimum volume within a day
   SYMBOL_PROP_TIME,                                        // Latest quote time
   SYMBOL_PROP_TIME_MSC,                                    // Time of the last quote in milliseconds
   SYMBOL_PROP_DIGITS,                                      // Number of decimal places
   SYMBOL_PROP_DIGITS_LOTS,                                 // Number of decimal places for a lot
   SYMBOL_PROP_SPREAD,                                      // Spread in points
   SYMBOL_PROP_SPREAD_FLOAT,                                // Floating spread flag
   SYMBOL_PROP_TICKS_BOOKDEPTH,                             // Maximum number of orders displayed in the Depth of Market
   SYMBOL_PROP_BOOKDEPTH_STATE,                             // Flag of subscription to DOM
   SYMBOL_PROP_TRADE_CALC_MODE,                             // Contract price calculation method (from the ENUM_SYMBOL_CALC_MODE enumeration)
   SYMBOL_PROP_TRADE_MODE,                                  // Order execution type (from the ENUM_SYMBOL_TRADE_MODE enumeration)
   SYMBOL_PROP_START_TIME,                                  // Symbol trading start date (usually used for futures)
   SYMBOL_PROP_EXPIRATION_TIME,                             // Symbol trading end date (usually used for futures)
   SYMBOL_PROP_TRADE_STOPS_LEVEL,                           // Minimum distance in points from the current close price for setting Stop orders
   SYMBOL_PROP_TRADE_FREEZE_LEVEL,                          // Freeze distance for trading operations (in points)
   SYMBOL_PROP_TRADE_EXEMODE,                               // Deal execution mode (from the ENUM_SYMBOL_TRADE_EXECUTION enumeration)
   SYMBOL_PROP_SWAP_MODE,                                   // Swap calculation model (from the ENUM_SYMBOL_SWAP_MODE enumeration)
   SYMBOL_PROP_SWAP_ROLLOVER3DAYS,                          // Triple-day swap (from the ENUM_DAY_OF_WEEK enumeration)
   SYMBOL_PROP_MARGIN_HEDGED_USE_LEG,                       // Calculating hedging margin using the larger leg (Buy or Sell)
   SYMBOL_PROP_EXPIRATION_MODE,                             // Flags of allowed order expiration modes
   SYMBOL_PROP_FILLING_MODE,                                // Flags of allowed order filling modes
   SYMBOL_PROP_ORDER_MODE,                                  // Flags of allowed order types
   SYMBOL_PROP_ORDER_GTC_MODE,                              // Expiration of Stop Loss and Take Profit orders if SYMBOL_EXPIRATION_MODE=SYMBOL_EXPIRATION_GTC (from the ENUM_SYMBOL_ORDER_GTC_MODE enumeration)
   SYMBOL_PROP_OPTION_MODE,                                 // Option type (from the ENUM_SYMBOL_OPTION_MODE enumeration)
   SYMBOL_PROP_OPTION_RIGHT,                                // Option right (Call/Put) (from the ENUM_SYMBOL_OPTION_RIGHT enumeration)
   //--- skip the property
   SYMBOL_PROP_BACKGROUND_COLOR                             // The color of the background used for the symbol in Market Watch
  }; 
#define SYMBOL_PROP_INTEGER_TOTAL    (40)                   // Total number of integer properties
#define SYMBOL_PROP_INTEGER_SKIP     (1)                    // Number of symbol integer properties not used in sorting
//+------------------------------------------------------------------+
//| Symbol real properties                                           |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_DOUBLE
  {
   SYMBOL_PROP_BID = SYMBOL_PROP_INTEGER_TOTAL,             // Bid - the best price at which a symbol can be sold
   SYMBOL_PROP_BIDHIGH,                                     // The highest Bid price of the day
   SYMBOL_PROP_BIDLOW,                                      // The lowest Bid price of the day
   SYMBOL_PROP_ASK,                                         // Ask - best price, at which an instrument can be bought
   SYMBOL_PROP_ASKHIGH,                                     // The highest Ask price of the day
   SYMBOL_PROP_ASKLOW,                                      // The lowest Ask price of the day
   SYMBOL_PROP_LAST,                                        // The price at which the last deal was executed
   SYMBOL_PROP_LASTHIGH,                                    // The highest Last price of the day
   SYMBOL_PROP_LASTLOW,                                     // The lowest Last price of the day
   SYMBOL_PROP_VOLUME_REAL,                                 // Volume of the day
   SYMBOL_PROP_VOLUMEHIGH_REAL,                             // Maximum Volume within a day
   SYMBOL_PROP_VOLUMELOW_REAL,                              // Minimum Volume within a day
   SYMBOL_PROP_OPTION_STRIKE,                               // Option execution price
   SYMBOL_PROP_POINT,                                       // One point value
   SYMBOL_PROP_TRADE_TICK_VALUE,                            // SYMBOL_TRADE_TICK_VALUE_PROFIT value
   SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT,                     // Calculated tick value for a winning position
   SYMBOL_PROP_TRADE_TICK_VALUE_LOSS,                       // Calculated tick value for a losing position
   SYMBOL_PROP_TRADE_TICK_SIZE,                             // Minimum price change
   SYMBOL_PROP_TRADE_CONTRACT_SIZE,                         // Trade contract size
   SYMBOL_PROP_TRADE_ACCRUED_INTEREST,                      // Accrued interest
   SYMBOL_PROP_TRADE_FACE_VALUE,                            // Face value – initial bond value set by an issuer
   SYMBOL_PROP_TRADE_LIQUIDITY_RATE,                        // Liquidity rate – the share of an asset that can be used for a margin
   SYMBOL_PROP_VOLUME_MIN,                                  // Minimum volume for a deal
   SYMBOL_PROP_VOLUME_MAX,                                  // Maximum volume for a deal
   SYMBOL_PROP_VOLUME_STEP,                                 // Minimum volume change step for deal execution
   SYMBOL_PROP_VOLUME_LIMIT,                                // The maximum allowed total volume of an open position and pending orders in one direction (either buy or sell)
   SYMBOL_PROP_SWAP_LONG,                                   // Long swap value
   SYMBOL_PROP_SWAP_SHORT,                                  // Short swap value
   SYMBOL_PROP_MARGIN_INITIAL,                              // Initial margin
   SYMBOL_PROP_MARGIN_MAINTENANCE,                          // Maintenance margin for an instrument
   SYMBOL_PROP_MARGIN_LONG_INITIAL,                         // Initial margin requirement applicable to long positions
   SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL,                     // Initial margin requirement applicable to BuyStop orders
   SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL,                    // Initial margin requirement applicable to BuyLimit orders
   SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL,                // Initial margin requirement applicable to BuyStopLimit orders
   SYMBOL_PROP_MARGIN_LONG_MAINTENANCE,                     // Maintenance margin requirement applicable to long positions
   SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE,                 // Maintenance margin requirement applicable to BuyStop orders
   SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE,                // Maintenance margin requirement applicable to BuyLimit orders
   SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE,            // Maintenance margin requirement applicable to BuyStopLimit orders
   SYMBOL_PROP_MARGIN_SHORT_INITIAL,                        // Initial margin requirement applicable to short positions
   SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL,                    // Initial margin requirement applicable to SellStop orders
   SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL,                   // Initial margin requirement applicable to SellLimit orders
   SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL,               // Initial margin requirement applicable to SellStopLimit orders
   SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE,                    // Maintenance margin requirement applicable to short positions
   SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE,                // Maintenance margin requirement applicable to SellStop orders
   SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE,               // Maintenance margin requirement applicable to SellLimit orders
   SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE,           // Maintenance margin requirement applicable to SellStopLimit orders
   SYMBOL_PROP_SESSION_VOLUME,                              // The total volume of deals in the current session
   SYMBOL_PROP_SESSION_TURNOVER,                            // The total turnover in the current session
   SYMBOL_PROP_SESSION_INTEREST,                            // The total volume of open positions
   SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,                   // The total volume of Buy orders at the moment
   SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,                  // The total volume of Sell orders at the moment
   SYMBOL_PROP_SESSION_OPEN,                                // Open price of the session
   SYMBOL_PROP_SESSION_CLOSE,                               // Close price of the session
   SYMBOL_PROP_SESSION_AW,                                  // The average weighted price of the session
   SYMBOL_PROP_SESSION_PRICE_SETTLEMENT,                    // The settlement price of the current session
   SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN,                     // Minimum allowable price value for the session 
   SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX,                     // Maximum allowable price value for the session
   SYMBOL_PROP_MARGIN_HEDGED,                               // Size of a contract or margin for one lot of hedged positions (oppositely directed positions at one symbol).
   SYMBOL_PROP_PRICE_CHANGE,                                // Change of the current price relative to the end of the previous trading day in %
   SYMBOL_PROP_PRICE_VOLATILITY,                            // Price volatility in %
   SYMBOL_PROP_PRICE_THEORETICAL,                           // Theoretical option price
   SYMBOL_PROP_PRICE_DELTA,                                 // Option/warrant delta. Shows the value the option price changes by, when the underlying asset price changes by 1
   SYMBOL_PROP_PRICE_THETA,                                 // Option/warrant theta. Number of points the option price is to lose every day due to a temporary breakup, i.e. when the expiration date approaches
   SYMBOL_PROP_PRICE_GAMMA,                                 // Option/warrant gamma. Shows the change rate of delta – how quickly or slowly the option premium changes
   SYMBOL_PROP_PRICE_VEGA,                                  // Option/warrant vega. Shows the number of points the option price changes by when the volatility changes by 1%
   SYMBOL_PROP_PRICE_RHO,                                   // Option/warrant rho. Reflects the sensitivity of the theoretical option price to the interest rate changing by 1%
   SYMBOL_PROP_PRICE_OMEGA,                                 // Option/warrant omega. Option elasticity – a relative percentage change of the option price by the percentage change of the underlying asset price
   SYMBOL_PROP_PRICE_SENSITIVITY,                           // Option/warrant sensitivity.  Shows by how many points the price of the option's underlying asset should change so that the price of the option changes by one point
  
  };
#define SYMBOL_PROP_DOUBLE_TOTAL     (68)                   // Total number of real properties
#define SYMBOL_PROP_DOUBLE_SKIP      (0)                    // Number of real symbol properties not used in sorting
//+------------------------------------------------------------------+
//| Symbol string properties                                         |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_STRING
  {
   SYMBOL_PROP_NAME = (SYMBOL_PROP_INTEGER_TOTAL+SYMBOL_PROP_DOUBLE_TOTAL),   // Symbol name
   SYMBOL_PROP_BASIS,                                       // Name of the underlaying asset for a derivative symbol
   SYMBOL_PROP_CURRENCY_BASE,                               // Instrument base currency
   SYMBOL_PROP_CURRENCY_PROFIT,                             // Profit currency
   SYMBOL_PROP_CURRENCY_MARGIN,                             // Margin currency
   SYMBOL_PROP_BANK,                                        // Source of the current quote
   SYMBOL_PROP_DESCRIPTION,                                 // String description of a symbol
   SYMBOL_PROP_FORMULA,                                     // The formula used for custom symbol pricing
   SYMBOL_PROP_ISIN,                                        // The name of a trading symbol in the international system of securities identification numbers (ISIN)
   SYMBOL_PROP_PAGE,                                        // The web page containing symbol information
   SYMBOL_PROP_PATH,                                        // Location in the symbol tree
   SYMBOL_PROP_CATEGORY,                                    // Symbol category
   SYMBOL_PROP_EXCHANGE,                                    // Name of an exchange a symbol is traded on
   SYMBOL_PROP_COUNTRY,                                     // Country the trading instrument belongs to
   SYMBOL_PROP_SECTOR_NAME,                                 // Economy sector the trading instrument belongs to
   SYMBOL_PROP_INDUSTRY_NAME,                               // Economy or industry branch the trading instrument belongs to
  };
#define SYMBOL_PROP_STRING_TOTAL     (16)                   // Total number of string properties
//+------------------------------------------------------------------+

For each of the enumerations, set new values for macro substitutions specifying the number of properties in each enumeration.


In the enumeration of the symbol sorting criteria, add the new constants corresponding to newly added enumeration constants of all object properties so that we are able to select and sort symbols by the new properties:

//+------------------------------------------------------------------+
//| Possible symbol sorting criteria                                 |
//+------------------------------------------------------------------+
#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 integer properties
   SORT_BY_SYMBOL_STATUS = 0,                               // Sort by symbol status
   SORT_BY_SYMBOL_INDEX_MW,                                 // Sort by index in the Market Watch window
   SORT_BY_SYMBOL_SECTOR,                                   // Sort by economic sector
   SORT_BY_SYMBOL_INDUSTRY,                                 // Sort by industry or economy sector
   SORT_BY_SYMBOL_CUSTOM,                                   // Sort by custom symbol property
   SORT_BY_SYMBOL_CHART_MODE,                               // Sort by price type for constructing bars – Bid or Last (from the ENUM_SYMBOL_CHART_MODE enumeration)
   SORT_BY_SYMBOL_EXIST,                                    // Sort by the flag that a symbol with such a name exists
   SORT_BY_SYMBOL_SELECT,                                   // Sort by the flag indicating that a symbol is selected in Market Watch
   SORT_BY_SYMBOL_VISIBLE,                                  // Sort by the flag indicating that a selected symbol is displayed in Market Watch
   SORT_BY_SYMBOL_SESSION_DEALS,                            // Sort by the number of deals in the current session 
   SORT_BY_SYMBOL_SESSION_BUY_ORDERS,                       // Sort by the total number of current buy orders
   SORT_BY_SYMBOL_SESSION_SELL_ORDERS,                      // Sort by the total number of current sell orders
   SORT_BY_SYMBOL_VOLUME,                                   // Sort by last deal volume
   SORT_BY_SYMBOL_VOLUMEHIGH,                               // Sort by maximum volume for a day
   SORT_BY_SYMBOL_VOLUMELOW,                                // Sort by minimum volume for a day
   SORT_BY_SYMBOL_TIME,                                     // Sort by the last quote time
   SORT_BY_SYMBOL_TIME_MSC,                                 // Sort by the last quote time in milliseconds
   SORT_BY_SYMBOL_DIGITS,                                   // Sort by a number of decimal places
   SORT_BY_SYMBOL_DIGITS_LOT,                               // Sort by a number of decimal places in a lot
   SORT_BY_SYMBOL_SPREAD,                                   // Sort by spread in points
   SORT_BY_SYMBOL_SPREAD_FLOAT,                             // Sort by floating spread
   SORT_BY_SYMBOL_TICKS_BOOKDEPTH,                          // Sort by a maximum number of requests displayed in the market depth
   SORT_BY_SYMBOL_BOOKDEPTH_STATE,                          // Sort by the DOM subscription flag
   SORT_BY_SYMBOL_TRADE_CALC_MODE,                          // Sort by contract price calculation method (from the ENUM_SYMBOL_CALC_MODE enumeration)
   SORT_BY_SYMBOL_TRADE_MODE,                               // Sort by order execution type (from the ENUM_SYMBOL_TRADE_MODE enumeration)
   SORT_BY_SYMBOL_START_TIME,                               // Sort by an instrument trading start date (usually used for futures)
   SORT_BY_SYMBOL_EXPIRATION_TIME,                          // Sort by an instrument trading end date (usually used for futures)
   SORT_BY_SYMBOL_TRADE_STOPS_LEVEL,                        // Sort by the minimum indent from the current close price (in points) for setting Stop orders
   SORT_BY_SYMBOL_TRADE_FREEZE_LEVEL,                       // Sort by trade operation freeze distance (in points)
   SORT_BY_SYMBOL_TRADE_EXEMODE,                            // Sort by trade execution mode (from the ENUM_SYMBOL_TRADE_EXECUTION enumeration)
   SORT_BY_SYMBOL_SWAP_MODE,                                // Sort by swap calculation model (from the ENUM_SYMBOL_SWAP_MODE enumeration)
   SORT_BY_SYMBOL_SWAP_ROLLOVER3DAYS,                       // Sort by week day for accruing a triple swap (from the ENUM_DAY_OF_WEEK enumeration)
   SORT_BY_SYMBOL_MARGIN_HEDGED_USE_LEG,                    // Sort by the calculation mode of a hedged margin using the larger leg (Buy or Sell)
   SORT_BY_SYMBOL_EXPIRATION_MODE,                          // Sort by flags of allowed order expiration modes
   SORT_BY_SYMBOL_FILLING_MODE,                             // Sort by flags of allowed order filling modes
   SORT_BY_SYMBOL_ORDER_MODE,                               // Sort by flags of allowed order types
   SORT_BY_SYMBOL_ORDER_GTC_MODE,                           // Sort by StopLoss and TakeProfit orders lifetime
   SORT_BY_SYMBOL_OPTION_MODE,                              // Sort by option type (from the ENUM_SYMBOL_OPTION_MODE enumeration)
   SORT_BY_SYMBOL_OPTION_RIGHT,                             // Sort by option right (Call/Put) (from the ENUM_SYMBOL_OPTION_RIGHT enumeration)
//--- Sort by real properties
   SORT_BY_SYMBOL_BID = FIRST_SYM_DBL_PROP,                 // Sort by Bid
   SORT_BY_SYMBOL_BIDHIGH,                                  // Sort by maximum Bid for a day
   SORT_BY_SYMBOL_BIDLOW,                                   // Sort by minimum Bid for a day
   SORT_BY_SYMBOL_ASK,                                      // Sort by Ask
   SORT_BY_SYMBOL_ASKHIGH,                                  // Sort by maximum Ask for a day
   SORT_BY_SYMBOL_ASKLOW,                                   // Sort by minimum Ask for a day
   SORT_BY_SYMBOL_LAST,                                     // Sort by the last deal price
   SORT_BY_SYMBOL_LASTHIGH,                                 // Sort by maximum Last for a day
   SORT_BY_SYMBOL_LASTLOW,                                  // Sort by minimum Last for a day
   SORT_BY_SYMBOL_VOLUME_REAL,                              // Sort by Volume for a day
   SORT_BY_SYMBOL_VOLUMEHIGH_REAL,                          // Sort by maximum Volume for a day
   SORT_BY_SYMBOL_VOLUMELOW_REAL,                           // Sort by minimum Volume for a day
   SORT_BY_SYMBOL_OPTION_STRIKE,                            // Sort by an option execution price
   SORT_BY_SYMBOL_POINT,                                    // Sort by a single point value
   SORT_BY_SYMBOL_TRADE_TICK_VALUE,                         // Sort by SYMBOL_TRADE_TICK_VALUE_PROFIT value
   SORT_BY_SYMBOL_TRADE_TICK_VALUE_PROFIT,                  // Sort by a calculated tick price for a profitable position
   SORT_BY_SYMBOL_TRADE_TICK_VALUE_LOSS,                    // Sort by a calculated tick price for a loss-making position
   SORT_BY_SYMBOL_TRADE_TICK_SIZE,                          // Sort by a minimum price change
   SORT_BY_SYMBOL_TRADE_CONTRACT_SIZE,                      // Sort by a trading contract size
   SORT_BY_SYMBOL_TRADE_ACCRUED_INTEREST,                   // Sort by accrued interest
   SORT_BY_SYMBOL_TRADE_FACE_VALUE,                         // Sort by face value
   SORT_BY_SYMBOL_TRADE_LIQUIDITY_RATE,                     // Sort by liquidity rate
   SORT_BY_SYMBOL_VOLUME_MIN,                               // Sort by a minimum volume for performing a deal
   SORT_BY_SYMBOL_VOLUME_MAX,                               // Sort by a maximum volume for performing a deal
   SORT_BY_SYMBOL_VOLUME_STEP,                              // Sort by a minimum volume change step for deal execution
   SORT_BY_SYMBOL_VOLUME_LIMIT,                             // Sort by a maximum allowed aggregate volume of an open position and pending orders in one direction
   SORT_BY_SYMBOL_SWAP_LONG,                                // Sort by a long swap value
   SORT_BY_SYMBOL_SWAP_SHORT,                               // Sort by a short swap value
   SORT_BY_SYMBOL_MARGIN_INITIAL,                           // Sort by an initial margin
   SORT_BY_SYMBOL_MARGIN_MAINTENANCE,                       // Sort by a maintenance margin for an instrument
   SORT_BY_SYMBOL_MARGIN_LONG_INITIAL,                      // Sort by initial margin requirement applicable to Long orders
   SORT_BY_SYMBOL_MARGIN_BUY_STOP_INITIAL,                  // Sort by initial margin requirement applicable to BuyStop orders
   SORT_BY_SYMBOL_MARGIN_BUY_LIMIT_INITIAL,                 // Sort by initial margin requirement applicable to BuyLimit orders
   SORT_BY_SYMBOL_MARGIN_BUY_STOPLIMIT_INITIAL,             // Sort by initial margin requirement applicable to BuyStopLimit orders
   SORT_BY_SYMBOL_MARGIN_LONG_MAINTENANCE,                  // Sort by maintenance margin requirement applicable to Long orders
   SORT_BY_SYMBOL_MARGIN_BUY_STOP_MAINTENANCE,              // Sort by maintenance margin requirement applicable to BuyStop orders
   SORT_BY_SYMBOL_MARGIN_BUY_LIMIT_MAINTENANCE,             // Sort by maintenance margin requirement applicable to BuyLimit orders
   SORT_BY_SYMBOL_MARGIN_BUY_STOPLIMIT_MAINTENANCE,         // Sort by maintenance margin requirement applicable to BuyStopLimit orders
   SORT_BY_SYMBOL_MARGIN_SHORT_INITIAL,                     // Sort by initial margin requirement applicable to Short orders
   SORT_BY_SYMBOL_MARGIN_SELL_STOP_INITIAL,                 // Sort by initial margin requirement applicable to SellStop orders
   SORT_BY_SYMBOL_MARGIN_SELL_LIMIT_INITIAL,                // Sort by initial margin requirement applicable to SellLimit orders
   SORT_BY_SYMBOL_MARGIN_SELL_STOPLIMIT_INITIAL,            // Sort by initial margin requirement applicable to SellStopLimit orders
   SORT_BY_SYMBOL_MARGIN_SHORT_MAINTENANCE,                 // Sort by maintenance margin requirement applicable to Short orders
   SORT_BY_SYMBOL_MARGIN_SELL_STOP_MAINTENANCE,             // Sort by maintenance margin requirement applicable to SellStop orders
   SORT_BY_SYMBOL_MARGIN_SELL_LIMIT_MAINTENANCE,            // Sort by maintenance margin requirement applicable to SellLimit orders
   SORT_BY_SYMBOL_MARGIN_SELL_STOPLIMIT_MAINTENANCE,        // Sort by maintenance margin requirement applicable to SellStopLimit orders
   SORT_BY_SYMBOL_SESSION_VOLUME,                           // Sort by summary volume of the current session deals
   SORT_BY_SYMBOL_SESSION_TURNOVER,                         // Sort by the summary turnover of the current session
   SORT_BY_SYMBOL_SESSION_INTEREST,                         // Sort by the summary open interest
   SORT_BY_SYMBOL_SESSION_BUY_ORDERS_VOLUME,                // Sort by the current volume of Buy orders
   SORT_BY_SYMBOL_SESSION_SELL_ORDERS_VOLUME,               // Sort by the current volume of Sell orders
   SORT_BY_SYMBOL_SESSION_OPEN,                             // Sort by a session Open price
   SORT_BY_SYMBOL_SESSION_CLOSE,                            // Sort by a session Close price
   SORT_BY_SYMBOL_SESSION_AW,                               // Sort by an average weighted price of the current session
   SORT_BY_SYMBOL_SESSION_PRICE_SETTLEMENT,                 // Sort by a settlement price of the current session
   SORT_BY_SYMBOL_SESSION_PRICE_LIMIT_MIN,                  // Sort by a minimum price of the current session 
   SORT_BY_SYMBOL_SESSION_PRICE_LIMIT_MAX,                  // Sort by a maximum price of the current session
   SORT_BY_SYMBOL_MARGIN_HEDGED,                            // Sort by a contract size or a margin value per one lot of hedged positions
   SORT_BY_SYMBOL_PRICE_CHANGE,                             // Sort by change of the current price relative to the end of the previous trading day
   SORT_BY_SYMBOL_PRICE_VOLATILITY,                         // Sort by price volatility in %
   SORT_BY_SYMBOL_PRICE_THEORETICAL,                        // Sort by theoretical option price
   SORT_BY_SYMBOL_PRICE_DELTA,                              // Sort by option/warrant delta
   SORT_BY_SYMBOL_PRICE_THETA,                              // Sort by option/warrant theta
   SORT_BY_SYMBOL_PRICE_GAMMA,                              // Sort by option/warrant gamma
   SORT_BY_SYMBOL_PRICE_VEGA,                               // Sort by option/warrant vega
   SORT_BY_SYMBOL_PRICE_RHO,                                // Sort by option/warrant rho
   SORT_BY_SYMBOL_PRICE_OMEGA,                              // Sort by option/warrant omega
   SORT_BY_SYMBOL_PRICE_SENSITIVITY,                        // Sort by option/warrant sensitivity
//--- Sort by string properties
   SORT_BY_SYMBOL_NAME = FIRST_SYM_STR_PROP,                // Sort by a symbol name
   SORT_BY_SYMBOL_BASIS,                                    // Sort by an underlying asset of a derivative
   SORT_BY_SYMBOL_CURRENCY_BASE,                            // Sort by a base currency of a symbol
   SORT_BY_SYMBOL_CURRENCY_PROFIT,                          // Sort by a profit currency
   SORT_BY_SYMBOL_CURRENCY_MARGIN,                          // Sort by a margin currency
   SORT_BY_SYMBOL_BANK,                                     // Sort by a feeder of the current quote
   SORT_BY_SYMBOL_DESCRIPTION,                              // Sort by a symbol string description
   SORT_BY_SYMBOL_FORMULA,                                  // Sort by the formula used for custom symbol pricing
   SORT_BY_SYMBOL_ISIN,                                     // Sort by the name of a symbol in the ISIN system
   SORT_BY_SYMBOL_PAGE,                                     // Sort by an address of the web page containing symbol information
   SORT_BY_SYMBOL_PATH,                                     // Sort by a path in the symbol tree
   SORT_BY_SYMBOL_CATEGORY,                                 // Sort by symbol category
   SORT_BY_SYMBOL_EXCHANGE,                                 // Sort by name of an exchange a symbol is traded on
   SORT_BY_SYMBOL_COUNTRY,                                  // Sort by country the trading instrument belongs to
   SORT_BY_SYMBOL_SECTOR_NAME,                              // Sort by economy sector the trading instrument belongs to
   SORT_BY_SYMBOL_INDUSTRY_NAME,                            // Sort by economy or industry branch the trading instrument belongs to
  };
//+------------------------------------------------------------------+


Each form object is now to have a new "Interaction with environment" property. If the property is set, this indicates that the object should respond to mouse actions according to its status. The remaining form objects should have the flag in a reset form. This allows us to select the form, over which the cursor hovered with the pressed button, as well as any other necessary actions that can be performed with a single form only so that the chart does not respond to mouse actions.

In the same file, set the property in the enumeration of integer properties of the graphical element on the canvas:

//+------------------------------------------------------------------+
//| Integer properties of the graphical element on the canvas        |
//+------------------------------------------------------------------+
enum ENUM_CANV_ELEMENT_PROP_INTEGER
  {
   CANV_ELEMENT_PROP_ID = 0,                          // Element ID
   CANV_ELEMENT_PROP_TYPE,                            // Graphical element type
   CANV_ELEMENT_PROP_BELONG,                          // Graphical element affiliation
   CANV_ELEMENT_PROP_NUM,                             // Element index in the list
   CANV_ELEMENT_PROP_CHART_ID,                        // Chart ID
   CANV_ELEMENT_PROP_WND_NUM,                         // Chart subwindow index
   CANV_ELEMENT_PROP_COORD_X,                         // Form's X coordinate on the chart
   CANV_ELEMENT_PROP_COORD_Y,                         // Form's Y coordinate on the chart
   CANV_ELEMENT_PROP_WIDTH,                           // Element width
   CANV_ELEMENT_PROP_HEIGHT,                          // Element height
   CANV_ELEMENT_PROP_RIGHT,                           // Element right border
   CANV_ELEMENT_PROP_BOTTOM,                          // Element bottom border
   CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,                  // Active area offset from the left edge of the element
   CANV_ELEMENT_PROP_ACT_SHIFT_TOP,                   // Active area offset from the upper edge of the element
   CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,                 // Active area offset from the right edge of the element
   CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,                // Active area offset from the bottom edge of the element
   CANV_ELEMENT_PROP_MOVABLE,                         // Element moveability flag
   CANV_ELEMENT_PROP_ACTIVE,                          // Element activity flag
   CANV_ELEMENT_PROP_INTERACTION,                     // Flag of interaction with the outside environment
   CANV_ELEMENT_PROP_COORD_ACT_X,                     // X coordinate of the element active area
   CANV_ELEMENT_PROP_COORD_ACT_Y,                     // Y coordinate of the element active area
   CANV_ELEMENT_PROP_ACT_RIGHT,                       // Right border of the element active area
   CANV_ELEMENT_PROP_ACT_BOTTOM,                      // Bottom border of the element active area
  };
#define CANV_ELEMENT_PROP_INTEGER_TOTAL (23)          // Total number of integer properties
#define CANV_ELEMENT_PROP_INTEGER_SKIP  (0)           // Number of integer properties not used in sorting
//+------------------------------------------------------------------+

In addition, let's fix the number of integer properties changing it from 22 to 23.

Add the new property to the enumeration of possible criteria of sorting graphical elements on the canvas:

//+------------------------------------------------------------------+
//| Possible sorting criteria of graphical elements on the canvas    |
//+------------------------------------------------------------------+
#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 integer properties
   SORT_BY_CANV_ELEMENT_ID = 0,                       // Sort by element ID
   SORT_BY_CANV_ELEMENT_TYPE,                         // Sort by graphical element type
   SORT_BY_CANV_ELEMENT_BELONG,                       // Sort by a graphical element affiliation
   SORT_BY_CANV_ELEMENT_NUM,                          // Sort by form index in the list
   SORT_BY_CANV_ELEMENT_CHART_ID,                     // Sort by chart ID
   SORT_BY_CANV_ELEMENT_WND_NUM,                      // Sort by chart window index
   SORT_BY_CANV_ELEMENT_COORD_X,                      // Sort by the element X coordinate on the chart
   SORT_BY_CANV_ELEMENT_COORD_Y,                      // Sort by the element Y coordinate on the chart
   SORT_BY_CANV_ELEMENT_WIDTH,                        // Sort by the element width
   SORT_BY_CANV_ELEMENT_HEIGHT,                       // Sort by the element height
   SORT_BY_CANV_ELEMENT_RIGHT,                        // Sort by the element right border
   SORT_BY_CANV_ELEMENT_BOTTOM,                       // Sort by the element bottom border
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_LEFT,               // Sort by the active area offset from the left edge of the element
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_TOP,                // Sort by the active area offset from the top edge of the element
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_RIGHT,              // Sort by the active area offset from the right edge of the element
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_BOTTOM,             // Sort by the active area offset from the bottom edge of the element
   SORT_BY_CANV_ELEMENT_MOVABLE,                      // Sort by the element moveability flag
   SORT_BY_CANV_ELEMENT_ACTIVE,                       // Sort by the element activity flag
   SORT_BY_CANV_ELEMENT_INTERACTION,                  // Sort by the flag of interaction with the outside environment
   SORT_BY_CANV_ELEMENT_COORD_ACT_X,                  // Sort by X coordinate of the element active area
   SORT_BY_CANV_ELEMENT_COORD_ACT_Y,                  // Sort by Y coordinate of the element active area
   SORT_BY_CANV_ELEMENT_ACT_RIGHT,                    // Sort by the right border of the element active area
   SORT_BY_CANV_ELEMENT_ACT_BOTTOM,                   // Sort by the bottom border of the element active area
//--- Sort by real properties

//--- Sort by string properties
   SORT_BY_CANV_ELEMENT_NAME_OBJ = FIRST_CANV_ELEMENT_STR_PROP,// Sort by an element object name
   SORT_BY_CANV_ELEMENT_NAME_RES,                     // Sort by the graphical resource name
  };
//+------------------------------------------------------------------+


Let's make all the necessary improvements to \MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqh symbol object class file.

In the public section of the class, declare the methods returning the descriptions of the economy sector and industry or economy branch:

//--- Return the description of the (1) status, (2) price type for constructing bars, 
//--- (3) method of calculating margin, (4) instrument trading mode,
//--- (5) deal execution mode for a symbol, (6) swap calculation mode,
//--- (7) StopLoss and TakeProfit lifetime, (8) option type, (9) option rights
//--- flags of (10) allowed order types, (11) allowed filling types,
//--- (12) allowed order expiration modes, (13) economy sector,
//--- (14) industry or economy branch
   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;
   
//--- Return (1) execution type, (2) order expiration type equal to 'type' if it is available on a symbol, otherwise - the correct option
   ENUM_ORDER_TYPE_FILLING GetCorrectTypeFilling(const uint type=ORDER_FILLING_RETURN);
   ENUM_ORDER_TYPE_TIME    GetCorrectTypeExpiration(uint expiration=ORDER_TIME_GTC);
//+------------------------------------------------------------------+
//| Description of symbol object properties                          |
//+------------------------------------------------------------------+


In the block of methods for a simplified access to symbol object properties, add the methods returning the values of new symbol object properties:

//+------------------------------------------------------------------+
//| Methods of a simplified access to the order object properties    |
//+------------------------------------------------------------------+
//--- Integer properties
   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);      }
//--- Real properties
   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 properties
   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);                               }
//+------------------------------------------------------------------+


In the block of methods for receiving and setting the parameters of tracked property changes, add the necessary methods for handling all properties newly added to a symbol object:

//+------------------------------------------------------------------+
//| Get and set the parameters of tracked property changes           |
//+------------------------------------------------------------------+
   //--- Execution
   //--- Flag of changing the trading mode for a symbol
   bool              IsChangedTradeMode(void)                              const { return this.m_is_change_trade_mode;                                               } 
   //--- Current session deals
   //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the number of deals during the current session
   //--- getting (3) the number of deals change value during the current session,
   //--- getting the flag of the number of deals change during the current session exceeding the (4) increase, (5) decrease value
   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 orders of the current session
   //--- setting the controlled value of (1) increase, (2) decrease and (3) control level of the current number of Buy orders
   //--- getting (4) the current number of Buy orders change value,
   //--- getting the flag of the current Buy orders' number change exceeding the (5) increase, (6) decrease value
   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 orders of the current session
   //--- setting the controlled value of (1) increase, (2) decrease and (3) control level of the current number of Sell orders
   //--- getting (4) the current number of Sell orders change value,
   //--- getting the flag of the current Sell orders' number change exceeding the (5) increase, (6) decrease value
   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);            }
   //--- Volume of the last deal
   //--- setting the last deal volume controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) volume change values in the last deal,
   //--- getting the flag of the volume change in the last deal exceeding the (5) increase, (6) decrease value
   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);                         }
   //--- Maximum volume within a day
   //--- setting the maximum day volume controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) the maximum volume change value within a day,
   //--- getting the flag of the maximum day volume change exceeding the (5) increase, (6) decrease value
   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);                     }
   //--- Minimum volume within a day
   //--- setting the minimum day volume controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) the minimum volume change value within a day,
   //--- getting the flag of the minimum day volume change exceeding the (5) increase, (6) decrease value
   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);                      }
   //--- Spread
   //--- setting the controlled spread (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) spread change value in points,
   //--- getting the flag of the spread change in points exceeding the (5) increase, (6) decrease value
   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
   //--- setting the controlled StopLevel (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) StopLevel change value in points,
   //--- getting the flag of StopLevel change in points exceeding the (5) increase, (6) decrease value
   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);              }
   //--- Freeze distance
   //--- setting the controlled FreezeLevel (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) FreezeLevel change value in points,
   //--- getting the flag of FreezeLevel change in points exceeding the (5) increase, (6) decrease value
   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
   //--- setting the controlled Bid price (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) Bid or Last price change value,
   //--- getting the flag of the Bid or Last price change exceeding the (5) increase, (6) decrease value
   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);                          }
   //--- The highest Bid price of the day
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) control level in points
   //--- getting the (4) maximum Bid or Last price change value,
   //--- getting the flag of the maximum Bid or Last price change exceeding the (5) increase, (6) decrease value
   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);                      }
   //--- The lowest Bid price of the day
   //--- setting the controlled minimum Bid price (1) increase, (2) decrease value and (3) control level in points
   //--- getting the (4) minimum Bid or Last price change value,
   //--- getting the flag of the minimum Bid or Last price change exceeding the (5) increase, (6) decrease value
   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
   //--- setting the controlled Last price (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) Bid or Last price change value,
   //--- getting the flag of the Bid or Last price change exceeding the (5) increase, (6) decrease value
   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);                         }
   //--- The highest Last price of the day
   //--- setting the controlled maximum Last price (1) increase, (2) decrease value and (3) control level in points
   //--- getting the (4) maximum Bid or Last price change value,
   //--- getting the flag of the maximum Bid or Last price change exceeding the (5) increase, (6) decrease value
   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);                     }
   //--- The lowest Last price of the day
   //--- setting the controlled minimum Last price (1) increase, (2) decrease value and (3) control level in points
   //--- getting the (4) minimum Bid or Last price change value,
   //--- getting the flag of the minimum Bid or Last price change exceeding the (5) increase, (6) decrease value
   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
   //--- setting the controlled Bid or Last price (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) Bid or Last price change value,
   //--- getting the flag of the Bid or Last price change exceeding the (5) increase, (6) decrease value
   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;
   //--- Maximum Bid/Last of the day
   //--- setting the controlled maximum Bid or Last price (1) increase, (2) decrease value and (3) control level in points
   //--- getting the (4) maximum Bid or Last price change value,
   //--- getting the flag of the maximum Bid or Last price change exceeding the (5) increase, (6) decrease value
   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;
   //--- Minimum Bid/Last of the day
   //--- setting the controlled minimum Bid or Last price (1) increase, (2) decrease value and (3) control level in points
   //--- getting the (4) minimum Bid or Last price change value,
   //--- getting the flag of the minimum Bid or Last price change exceeding the (5) increase, (6) decrease value
   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
   //--- setting the controlled Ask price (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) Ask price change value,
   //--- getting the flag of the Ask price change exceeding the (5) increase, (6) decrease value
   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);                          }
   //--- Maximum Ask price for the day
   //--- setting the maximum day Ask controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) the maximum Ask change value within a day,
   //--- getting the flag of the maximum day Ask change exceeding the (5) increase, (6) decrease value
   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);                      }
   //--- Minimum Ask price for the day
   //--- setting the minimum day Ask controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) the minimum Ask change value within a day,
   //--- getting the flag of the minimum day Ask change exceeding the (5) increase, (6) decrease value
   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);                       }
   //--- Real Volume for the day
   //--- setting the real day volume controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) the change value of the real day volume,
   //--- getting the flag of the real day volume change exceeding the (5) increase, (6) decrease value
   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);                  }
   //--- Maximum real volume for the day
   //--- setting the maximum real day volume controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) the change value of the maximum real day volume,
   //--- getting the flag of the maximum real day volume change exceeding the (5) increase, (6) decrease value
   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);              }
   //--- Minimum real volume for the day
   //--- setting the minimum real day volume controlled (1) increase, (2) decrease and (3) control level
   //--- getting (4) the change value of the minimum real day volume,
   //--- getting the flag of the minimum real day volume change exceeding the (5) increase, (6) decrease value
   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);               }
   //--- Strike price
   //--- setting the controlled strike price (1) increase, (2) decrease value and (3) control level in points
   //--- getting (4) the change value of the strike price,
   //--- getting the flag of the strike price change exceeding the (5) increase, (6) decrease value
   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);                }
   //--- Maximum allowed total volume of unidirectional positions and orders
   //--- (1) Setting the control level
   //--- (2) getting the change value of the maximum allowed total volume of unidirectional positions and orders,
   //--- getting the flag of (3) increasing, (4) decreasing the maximum allowed total volume of unidirectional positions and orders
   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);                 }
   //---  Swap long
   //--- (1) Setting the control level
   //--- (2) getting the swap long change value,
   //--- getting the flag of (3) increasing, (4) decreasing the swap long
   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);                    }
   //---  Swap short
   //--- (1) Setting the control level
   //--- (2) getting the swap short change value,
   //--- getting the flag of (3) increasing, (4) decreasing the swap short
   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);                   }
   //--- The total volume of deals in the current session
   //--- setting the controlled value of (1) increase, (2) decrease and (3) control level of the total volume of deals during the current session
   //--- getting (4) the total deal volume change value in the current session,
   //--- getting the flag of the total deal volume change during the current session exceeding the (5) increase, (6) decrease value
   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);               }
   //--- The total turnover in the current session
   //--- setting the controlled value of (1) increase, (2) decrease and (3) control level of the total turnover during the current session
   //--- getting (4) the total turnover change value in the current session,
   //--- getting the flag of the total turnover change during the current session exceeding the (5) increase, (6) decrease value
   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);             }
   //--- The total volume of open positions
   //--- setting the controlled value of (1) increase, (2) decrease and (3) control level of the total volume of open positions during the current session
   //--- getting (4) the change value of the open positions total volume in the current session,
   //--- getting the flag of the open positions total volume change during the current session exceeding the (5) increase, (6) decrease value
   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);             }
   //--- The total volume of Buy orders at the moment
   //--- setting the controlled value of (1) increase, (2) decrease and (3) control level of the current total buy order volume
   //--- getting (4) the change value of the current total buy order volume,
   //--- getting the flag of the current total buy orders' volume change exceeding the (5) increase, (6) decrease value
   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);    }
   //--- The total volume of Sell orders at the moment
   //--- setting the controlled value of (1) increase, (2) decrease and (3) control level of the current total sell order volume
   //--- getting (4) the change value of the current total sell order volume,
   //--- getting the flag of the current total sell orders' volume change exceeding the (5) increase, (6) decrease value
   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);   }
   //--- Session open price
   //--- setting the controlled session open price (1) increase, (2) decrease and (3) control value
   //--- getting (4) the change value of the session open price,
   //--- getting the flag of the session open price change exceeding the (5) increase, (6) decrease value
   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);                 }
   //--- Session close price
   //--- setting the controlled session close price (1) increase, (2) decrease and (3) control value
   //--- getting (4) the change value of the session close price,
   //--- getting the flag of the session close price change exceeding the (5) increase, (6) decrease value
   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);                }
   //--- The average weighted session price
   //--- setting the controlled session average weighted price (1) increase, (2) decrease and (3) control value
   //--- getting (4) the change value of the average weighted session price,
   //--- getting the flag of the average weighted session price change exceeding the (5) increase, (6) decrease value
   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);                   }
   //--- Change of the current price relative to the end of the previous trading day
   //--- setting the controlled Bid or Last price (1) increase, (2) decrease value and (3) control level of the current price dynamics relative to the end of the previous trading day
   //--- getting (4) the value of the change of the current price relative to the end of the previous trading day,
   //--- getting the flag indicating the Change of the current price relative to the end of the previous trading day property change by the value exceeding the (5) growth, (6) decrease
   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);                 }
   //--- Price volatility in %
   //--- setting the controlled session average weighted price (1) increase, (2) decrease and (3) price volatility control in %
   //--- getting (4) the value of the price volatility change in %,
   //--- getting the flag of the price volatility change in % exceeding the (5) growth and (6) decrease value
   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);             }
   //--- Theoretical option price
   //--- setting the controlled strike price (1) increase, (2) decrease value and (3) theoretical option price control level
   //--- getting (4) the change value of the theoretical option price,
   //--- getting the flag of the theoretical option price change exceeding the (5) increase, (6) decrease value
   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);            }
   //--- Option/warrant delta
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) option/warrant delta control level in points
   //--- getting (4) option/warrant delta change value in points,
   //--- getting the flag of the option/warrant delta change exceeding the (5) increase, (6) decrease value
   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);                     }
   //--- Option/warrant theta
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) option/warrant theta control level in points
   //--- getting (4) option/warrant theta change value in points,
   //--- getting the flag of the option/warrant theta change exceeding the (5) increase, (6) decrease value
   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);                     }
   //--- Option/warrant gamma
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) option/warrant gamma control level in points
   //--- getting (4) option/warrant gamma change value in points,
   //--- getting the flag of the option/warrant gamma change exceeding the (5) increase, (6) decrease value
   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);                     }
   //--- Option/warrant vega
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) option/warrant vega control level in points
   //--- getting (4) the change value of the average weighted session price,
   //--- getting the flag of the average weighted session price change exceeding the (5) increase, (6) decrease value
   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);                      }
   //--- Option/warrant rho
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) option/warrant rho control level in points
   //--- getting (4) option/warrant rho change value in points,
   //--- getting the flag of the option/warrant rho change exceeding the (5) increase, (6) decrease value
   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);                       }
   //--- Option/warrant omega
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) option/warrant omega control level in points
   //--- getting (4) option/warrant omega change value in points,
   //--- getting the flag of the option/warrant omega change exceeding the (5) increase, (6) decrease value
   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);                     }
   //--- Option/warrant sensitivity
   //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) option/warrant sensitivity control level in points
   //--- getting (4) option/warrant sensitivity change value in points,
   //--- getting the flag of the option/warrant sensitivity change exceeding the (5) increase, (6) decrease value
   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);               }

//--- Return a trading object
   CTradeObj        *GetTradeObj(void)                                           { return &this.m_trade; }

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


In the closed parametric constructor, set adding the appropriate symbol object values to its new properties:

//+------------------------------------------------------------------+
//| Closed parametric constructor                                    |
//+------------------------------------------------------------------+
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);
     }
//--- Initialize base object data arrays
   this.SetControlDataArraySizeLong(SYMBOL_PROP_INTEGER_TOTAL);
   this.SetControlDataArraySizeDouble(SYMBOL_PROP_DOUBLE_TOTAL);
   this.ResetChangesParams();
   this.ResetControlsParams();
   
//--- Initialize symbol data
   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 
   
//--- Save integer properties
   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;
//--- Save real properties
   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;
//--- Save string properties
   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();
//--- Save additional integer properties
   this.m_long_prop[SYMBOL_PROP_DIGITS_LOTS]                                        = this.SymbolDigitsLot();
   
//--- Fill in the symbol current data
   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];
   
//--- Update the base object data and search for changes
   CBaseObjExt::Refresh();
//---
   if(!select)
      this.RemoveFromMarketWatch();

//--- Initializing default values of a trading object
   this.m_trade.Init(this.Name(),0,this.LotsMin(),5,0,0,false,this.GetCorrectTypeFilling(),this.GetCorrectTypeExpiration(),LOG_LEVEL_ERROR_MSG);
  }
//+------------------------------------------------------------------+


Add code blocks for returning the description of integer properties in the method returning the description of a symbol integer property:

//+------------------------------------------------------------------+
//| Return the description of the symbol integer property            |
//+------------------------------------------------------------------+
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 
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


To avoid displaying a lengthy list of similar code blocks in the method returning the description of a symbol real property, let's consider the code added at the very end of the method:

      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)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


Add similar code blocks to the method returning the description of a symbol string property:

//+------------------------------------------------------------------+
//| Return the description of a symbol string property               |
//+------------------------------------------------------------------+
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)+"\"")
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


Implementing the method returning the economy sector description:

//+------------------------------------------------------------------+
//| Return the economy sector description                            |
//+------------------------------------------------------------------+
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);
     }
  }
//+------------------------------------------------------------------+

Depending on the value returned by the Sector() method added above, the appropriate text description is returned from the method.

Implementing the method returning the industry or economy branch description:

//+------------------------------------------------------------------+
//| Return the industry or economy branch description                |
//+------------------------------------------------------------------+
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);
     }
  }
//+------------------------------------------------------------------+

The method is similar to the one considered above but the value returned by the Industry() method is checked and the necessary text string is returned according to its value.

In the article 73, I implemented the mouse status class. Let's change the method name in \MQL5\Include\DoEasy\Services\MouseState.mqh.

Rename ButtKeyState() to ButtonKeyState():

//--- Return (1-2) the cursor coordinates, (3) scroll wheel value, (4) status of the mouse buttons and Shift/Ctrl keys
   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);

...

//+------------------------------------------------------------------+
//| Return the mouse buttons and Shift/Ctrl keys states              |
//+------------------------------------------------------------------+
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;
  }
//+------------------------------------------------------------------+


In the private section, I have added hex values of bits, describing mouse button states, to the table:

//+------------------------------------------------------------------+
//| Mouse status class                                               |
//+------------------------------------------------------------------+
class CMouseState
  {
private:
   int               m_coord_x;                             // X coordinate
   int               m_coord_y;                             // Y coordinate
   int               m_delta_wheel;                         // Mouse wheel scroll value
   int               m_window_num;                          // Subwindow index
   long              m_chart_id;                            // Chart ID
   ushort            m_state_flags;                         // Status flags
   
//--- Set the status of mouse buttons, as well as of Shift and Ctrl keys
   void              SetButtonKeyState(const int id,const long lparam,const double dparam,const ushort flags);
//--- Set the mouse buttons and keys status flags
   void              SetButtKeyFlags(const short flags);
//--- Data location in the ushort value of the button status
   //---------------------------------------------------------------------------
   //   bit    |    byte   |            state            |    dec    |   hex   |
   //---------------------------------------------------------------------------
   //    0     |     0     | left mouse button           |     1     |    1    |
   //---------------------------------------------------------------------------
   //    1     |     0     | right mouse button          |     2     |    2    |
   //---------------------------------------------------------------------------
   //    2     |     0     | SHIFT key                   |     4     |    4    |
   //---------------------------------------------------------------------------
   //    3     |     0     | CTRL key                    |     8     |    8    |
   //---------------------------------------------------------------------------
   //    4     |     0     | middle mouse button         |    16     |   10    |
   //---------------------------------------------------------------------------
   //    5     |     0     | 1 add. mouse button         |    32     |   20    |
   //---------------------------------------------------------------------------
   //    6     |     0     | 2 add. mouse button         |    64     |   40    |
   //---------------------------------------------------------------------------
   //    7     |     0     | scrolling the wheel         |    128    |   80    |
   //---------------------------------------------------------------------------
   //---------------------------------------------------------------------------
   //    0     |     1     | cursor inside the form      |    256    |   100   |
   //---------------------------------------------------------------------------
   //    1     |     1     | cursor inside active area   |    512    |   200   |
   //---------------------------------------------------------------------------
   //    2     |     1     | cursor in the control area  |   1024    |   400   |
   //---------------------------------------------------------------------------
   //    3     |     1     | cursor in the scrolling area|   2048    |   800   |
   //---------------------------------------------------------------------------
   //    4     |     1     | cursor at the left edge     |   4096    |  1000   |
   //---------------------------------------------------------------------------
   //    5     |     1     | cursor at the bottom edge   |   8192    |  2000   |
   //---------------------------------------------------------------------------
   //    6     |     1     | cursor at the right edge    |   16384   |  4000   |
   //---------------------------------------------------------------------------
   //    7     |     1     | cursor at the top edge      |   32768   |  8000   |
   //---------------------------------------------------------------------------
      
public:


Let's fix the errors in the base object class of all library graphical objects. When creating such an object, the name prefix storing a program name was erroneously set as an empty string in the class constructor:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
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();                  // Clear the event list
   this.m_list_events.Sort();                   // Sorted list flag
   this.m_type=OBJECT_DE_TYPE_GBASE;            // Object type
   this.m_type_graph_obj=WRONG_VALUE;           // Graphical object type
   this.m_type_element=WRONG_VALUE;             // Graphical object type
   this.m_belong=WRONG_VALUE;                   // Program/terminal affiliation
   this.m_group=0;                              // Graphical object group
   this.m_name_prefix="";                       // Object name prefix
   this.m_name="";                              // Object name
   this.m_chart_id=0;                           // Object chart ID
   this.m_object_id=0;                          // Object ID
   this.m_zorder=0;                             // Priority of a graphical object for receiving the mouse click event
   this.m_subwindow=0;                          // Subwindow index
   this.m_shift_y=0;                            // Subwindow Y coordinate shift
   this.m_timeframes_visible=OBJ_ALL_PERIODS;   // Visibility of an object on timeframes (a set of flags)
   this.m_visible=true;                         // Object visibility
   this.m_back=false;                           // "Background object" flag
   this.m_selected=false;                       // "Object selection" flag
   this.m_selectable=false;                     // "Object availability" flag
   this.m_hidden=true;                          // "Disable displaying the name of a graphical object in the terminal object list" flag
   this.m_create_time=0;                        // Object creation time
  }
//+------------------------------------------------------------------+

First, the valid prefix value is set here, in the initialization list. Further on, in the constructor body, the value was set as an empty string, which caused some errors when identifying graphical objects while handling them.

Delete the string and remove setting the shift and visibility flag from the initialization list since they are set in the constructor body:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CGBaseObj::CGBaseObj() : m_name_prefix(::MQLInfoString(MQL_PROGRAM_NAME)+"_"),m_belong(GRAPH_OBJ_BELONG_PROGRAM)
  {
   this.m_list_events.Clear();                  // Clear the event list
   this.m_list_events.Sort();                   // Sorted list flag
   this.m_type=OBJECT_DE_TYPE_GBASE;            // Object type
   this.m_type_graph_obj=WRONG_VALUE;           // Graphical object type
   this.m_type_element=WRONG_VALUE;             // Graphical object type
   this.m_belong=WRONG_VALUE;                   // Program/terminal affiliation
   this.m_group=0;                              // Graphical object group
   this.m_name="";                              // Object name
   this.m_chart_id=0;                           // Object chart ID
   this.m_object_id=0;                          // Object ID
   this.m_zorder=0;                             // Priority of a graphical object for receiving the mouse click event
   this.m_subwindow=0;                          // Subwindow index
   this.m_shift_y=0;                            // Subwindow Y coordinate shift
   this.m_timeframes_visible=OBJ_ALL_PERIODS;   // Visibility of an object on timeframes (a set of flags)
   this.m_visible=true;                         // Object visibility
   this.m_back=false;                           // "Background object" flag
   this.m_selected=false;                       // "Object selection" flag
   this.m_selectable=false;                     // "Object availability" flag
   this.m_hidden=true;                          // "Disable displaying the name of a graphical object in the terminal object list" flag
   this.m_create_time=0;                        // Object creation time
  }
//+------------------------------------------------------------------+


In the public section of the class, write the method returning the graphical object name prefix:

//--- Add an event object to the event list
   bool              AddEvent(CGBaseEvent *event)              { return this.m_list_events.Add(event);}
//--- Clear the event list
   void              ClearEventsList(void)                     { this.m_list_events.Clear();          }
//--- Return the number of events in the list
   int               EventsTotal(void)                         { return this.m_list_events.Total();   }

public:
//--- Return the prefix name
   string            NamePrefix(void)                    const { return this.m_name_prefix;           }
//--- Set the values of the class variables
   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;                 }


Let's improve the graphical element object class on canvas in \MQL5\Include\DoEasy\Objects\Graph\GCnvElement.mqh.

Previously, I have made here some errors as well. So we need to add the methods for handling the new "Interaction" property.

Move the methods returning the cursor position relative to the entire element or its active area from the protected section to the public one:

//+------------------------------------------------------------------+
//| Class of the graphical element object                            |
//+------------------------------------------------------------------+
class CGCnvElement : public CGBaseObj
  {
protected:
   CCanvas           m_canvas;                                 // CCanvas class object
   CPause            m_pause;                                  // Pause class object
   bool              m_shadow;                                 // Shadow presence
   color             m_chart_color_bg;                         // Chart background color
   uint              m_duplicate_res[];                        // Array for storing resource data copy

//--- Return the cursor position relative to the (1) entire element and (2) the element's active area
   bool              CursorInsideElement(const int x,const int y);
   bool              CursorInsideActiveArea(const int x,const int y);
//--- Create (1) the object structure and (2) the object from the structure
   virtual bool      ObjectToStruct(void);
   virtual void      StructToObject(void);
   
private:

//--- (1) Save the graphical resource to the array and (2) restore the resource from the array
   bool              ResourceStamp(const string source);
   virtual bool      Reset(void);
   
//--- Return the cursor position relative to the (1) entire element and (2) the element's active area
   bool              CursorInsideElement(const int x,const int y);
   bool              CursorInsideActiveArea(const int x,const int y);

//--- Create the element
   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);
                                
//--- Return the pointer to a canvas object

We will need them to manage an outside object in the graphical element collection class.

In the private section of the class, the structure storing the object properties for saving the object and reading from it receives the new property:

//+------------------------------------------------------------------+
//| Class of the graphical element object                            |
//+------------------------------------------------------------------+
class CGCnvElement : public CGBaseObj
  {
protected:
   CCanvas           m_canvas;                                 // CCanvas class object
   CPause            m_pause;                                  // Pause class object
   bool              m_shadow;                                 // Shadow presence
   color             m_chart_color_bg;                         // Chart background color
   uint              m_duplicate_res[];                        // Array for storing resource data copy

//--- Create (1) the object structure and (2) the object from the structure
   virtual bool      ObjectToStruct(void);
   virtual void      StructToObject(void);
   
private:
   struct SData
     {
      //--- Object integer properties
      int            id;                                       // Element ID
      int            type;                                     // Graphical element type
      int            number;                                   // Element index in the list
      long           chart_id;                                 // Chart ID
      int            subwindow;                                // Chart subwindow index
      int            coord_x;                                  // Form's X coordinate on the chart
      int            coord_y;                                  // Form's Y coordinate on the chart
      int            width;                                    // Element width
      int            height;                                   // Element height
      int            edge_right;                               // Element right border
      int            edge_bottom;                              // Element bottom border
      int            act_shift_left;                           // Active area offset from the left edge of the element
      int            act_shift_top;                            // Active area offset from the top edge of the element
      int            act_shift_right;                          // Active area offset from the right edge of the element
      int            act_shift_bottom;                         // Active area offset from the bottom edge of the element
      uchar          opacity;                                  // Element opacity
      color          color_bg;                                 // Element background color
      bool           movable;                                  // Element moveability flag
      bool           active;                                   // Element activity flag
      bool           interaction;                              // Flag of interaction with the outside environment
      int            coord_act_x;                              // X coordinate of the element active area
      int            coord_act_y;                              // Y coordinate of the element active area
      int            coord_act_right;                          // Right border of the element active area
      int            coord_act_bottom;                         // Bottom border of the element active area
      //--- Object real properties

      //--- Object string properties
      uchar          name_obj[64];                             // Graphical element object name
      uchar          name_res[64];                             // Graphical resource name
     };
   SData             m_struct_obj;                             // Object structure
   uchar             m_uchar_array[];                          // uchar array of the object structure
   
   long              m_long_prop[ORDER_PROP_INTEGER_TOTAL];    // Integer properties
   double            m_double_prop[ORDER_PROP_DOUBLE_TOTAL];   // Real properties
   string            m_string_prop[ORDER_PROP_STRING_TOTAL];   // String properties


In the public section of the class, declare the virtual event handler:

protected:
//--- Protected constructor
                     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:
//--- Event handler
   virtual void      OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam);
//--- Parametric constructor
                     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);
//--- Default constructor/Destructor
                     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();             }

Since other objects, including the form object, are to be derived from it, we need a virtual event handler. The collection list of graphical elements stores the objects of the CGCnvElement type class. However, its descendants can be placed there as well. Thus, when obtaining the CForm class object from the list, the CForm class handler is called when accessing the object event handler since it also features the virtual event handler.

In the block of methods for a simplified access to the object properties, set two new methods for handling the "Interaction" property:

//+------------------------------------------------------------------+
//| Methods of simplified access to object properties                |
//+------------------------------------------------------------------+
//--- Set the (1) X, (2) Y coordinates, (3) element width, (4) height, (5) right (6) and bottom edge,
   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());         }
//--- Set the shift of the (1) left, (2) top, (3) right, (4) bottom edge of the active area relative to the element,
//--- (5) all shifts of the active area edges relative to the element, (6) the element background color and (7) the element opacity
   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);

//--- Set the flag of (1) object moveability, (2) activity, (3) element ID, (4) element index in the list and (5) shadow presence
   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;                                                   }
   
//--- Return the shift (1) of the left, (2) right, (3) top and (4) bottom edge of the element active area
   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);     }
//--- Return the coordinate (1) of the left, (2) right, (3) top and (4) bottom edge of the element active area
   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());           }
//--- Return (1) the background color, (2) the opacity, coordinate (3) of the right and (4) bottom element edge
   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();                          }
//--- Return the (1) X, (2) Y coordinates, (3) element width and (4) height,
   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);               }
//--- Return the element (1) moveability and (2) activity flag
   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);         }
//--- Return (1) the object name, (2) the graphical resource name, (3) the chart ID and (4) the chart subwindow index
   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);              }
//--- Return (1) the element ID, (2) element index in the list, (3) flag of the form shadow presence and (4) the chart background color
   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;                                         }
//--- Set the object above all
   void              BringToTop(void)                          { CGBaseObj::SetVisible(false,false); CGBaseObj::SetVisible(true,false);}
//--- (1) Show and (2) hide the element
   virtual void      Show(void)                                { CGBaseObj::SetVisible(true,false);                                    }
   virtual void      Hide(void)                                { CGBaseObj::SetVisible(false,false);                                   }
   
//+------------------------------------------------------------------+
//| The methods of receiving raster data                             |
//+------------------------------------------------------------------+


In the parametric constructor, add checking the presence of a substring with the program name in the string of the name passed in the constructor parameters. If there is no substring, the name passed to the method receives the program name as an object name prefix. If the substring is present, nothing is added. This allows us to avoid doubling the object name prefix if it has already been passed in the constructor parameters within the name in the name variable:

//+------------------------------------------------------------------+
//| Parametric constructor                                           |
//+------------------------------------------------------------------+
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()); // Graphical resource name
      this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,CGBaseObj::ChartID());         // Chart ID
      this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,CGBaseObj::SubWindow());        // Chart subwindow index
      this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,CGBaseObj::Name());            // Element object name
      this.SetProperty(CANV_ELEMENT_PROP_TYPE,element_type);                     // Graphical element type
      this.SetProperty(CANV_ELEMENT_PROP_ID,element_id);                         // Element ID
      this.SetProperty(CANV_ELEMENT_PROP_NUM,element_num);                       // Element index in the list
      this.SetProperty(CANV_ELEMENT_PROP_COORD_X,x);                             // Element's X coordinate on the chart
      this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,y);                             // Element's Y coordinate on the chart
      this.SetProperty(CANV_ELEMENT_PROP_WIDTH,w);                               // Element width
      this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,h);                              // Element height
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,0);                      // Active area offset from the left edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,0);                       // Active area offset from the upper edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,0);                     // Active area offset from the right edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,0);                    // Active area offset from the bottom edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,movable);                       // Element moveability flag
      this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,activity);                       // Element activity flag
      this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,false);                     // Flag of interaction with the outside environment
      this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.RightEdge());                // Element right border
      this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.BottomEdge());              // Element bottom border
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.ActiveAreaLeft());     // X coordinate of the element active area
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.ActiveAreaTop());      // Y coordinate of the element active area
      this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.ActiveAreaRight());      // Right border of the element active area
      this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.ActiveAreaBottom());    // Bottom border of the element active area
     }
   else
     {
      ::Print(CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.m_name);
     }
  }
//+------------------------------------------------------------------+

Here we also set the default value for the "Interaction" property and fix the erroneous assignment of the graphical element type to the library object type (previously, we assigned the element type to the m_type variable which is incorrect and causes object identification errors):

   this.m_type=element_type;

Similar corrections are made in the protected class constructor:

//+------------------------------------------------------------------+
//| Protected constructor                                            |
//+------------------------------------------------------------------+
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()); // Graphical resource name
      this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,CGBaseObj::ChartID());         // Chart ID
      this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,CGBaseObj::SubWindow());        // Chart subwindow index
      this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,CGBaseObj::Name());            // Element object name
      this.SetProperty(CANV_ELEMENT_PROP_TYPE,element_type);                     // Graphical element type
      this.SetProperty(CANV_ELEMENT_PROP_ID,0);                                  // Element ID
      this.SetProperty(CANV_ELEMENT_PROP_NUM,0);                                 // Element index in the list
      this.SetProperty(CANV_ELEMENT_PROP_COORD_X,x);                             // Element's X coordinate on the chart
      this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,y);                             // Element's Y coordinate on the chart
      this.SetProperty(CANV_ELEMENT_PROP_WIDTH,w);                               // Element width
      this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,h);                              // Element height
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,0);                      // Active area offset from the left edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,0);                       // Active area offset from the upper edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,0);                     // Active area offset from the right edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,0);                    // Active area offset from the bottom edge of the element
      this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,false);                         // Element moveability flag
      this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,false);                          // Element activity flag
      this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,false);                     // Flag of interaction with the outside environment
      this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.RightEdge());                // Element right border
      this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.BottomEdge());              // Element bottom border
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.ActiveAreaLeft());     // X coordinate of the element active area
      this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.ActiveAreaTop());      // Y coordinate of the element active area
      this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.ActiveAreaRight());      // Right border of the element active area
      this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.ActiveAreaBottom());    // Bottom border of the element active area
     }
   else
     {
      ::Print(CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.m_name);
     }
  }
//+------------------------------------------------------------------+


In the method creating the object structure, add writing the new property to the structure variables:

//+------------------------------------------------------------------+
//| Create the object structure                                      |
//+------------------------------------------------------------------+
bool CGCnvElement::ObjectToStruct(void)
  {
//--- Save integer properties
   this.m_struct_obj.id=(int)this.GetProperty(CANV_ELEMENT_PROP_ID);                            // Element ID
   this.m_struct_obj.type=(int)this.GetProperty(CANV_ELEMENT_PROP_TYPE);                        // Graphical element type
   this.m_struct_obj.number=(int)this.GetProperty(CANV_ELEMENT_PROP_NUM);                       // Eleemnt ID in the list
   this.m_struct_obj.chart_id=this.GetProperty(CANV_ELEMENT_PROP_CHART_ID);                     // Chart ID
   this.m_struct_obj.subwindow=(int)this.GetProperty(CANV_ELEMENT_PROP_WND_NUM);                // Chart subwindow index
   this.m_struct_obj.coord_x=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_X);                  // Form's X coordinate on the chart
   this.m_struct_obj.coord_y=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_Y);                  // Form's Y coordinate on the chart
   this.m_struct_obj.width=(int)this.GetProperty(CANV_ELEMENT_PROP_WIDTH);                      // Element width
   this.m_struct_obj.height=(int)this.GetProperty(CANV_ELEMENT_PROP_HEIGHT);                    // Element height
   this.m_struct_obj.edge_right=(int)this.GetProperty(CANV_ELEMENT_PROP_RIGHT);                 // Element right edge
   this.m_struct_obj.edge_bottom=(int)this.GetProperty(CANV_ELEMENT_PROP_BOTTOM);               // Element bottom edge
   this.m_struct_obj.act_shift_left=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT);    // Active area offset from the left edge of the element
   this.m_struct_obj.act_shift_top=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP);      // Active area offset from the top edge of the element
   this.m_struct_obj.act_shift_right=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT);  // Active area offset from the right edge of the element
   this.m_struct_obj.act_shift_bottom=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM);// Active area offset from the bottom edge of the element
   this.m_struct_obj.movable=(bool)this.GetProperty(CANV_ELEMENT_PROP_MOVABLE);                 // Element moveability flag
   this.m_struct_obj.active=(bool)this.GetProperty(CANV_ELEMENT_PROP_ACTIVE);                   // Element activity flag
   this.m_struct_obj.interaction=(bool)this.GetProperty(CANV_ELEMENT_PROP_INTERACTION);         // Flag of interaction with the outside environment
   this.m_struct_obj.coord_act_x=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_ACT_X);          // X coordinate of the element active area
   this.m_struct_obj.coord_act_y=(int)this.GetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y);          // Y coordinate of the element active area
   this.m_struct_obj.coord_act_right=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_RIGHT);        // Right border of the element active area
   this.m_struct_obj.coord_act_bottom=(int)this.GetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM);      // Bottom border of the element active area
   this.m_struct_obj.color_bg=this.m_color_bg;                                                  // Element background color
   this.m_struct_obj.opacity=this.m_opacity;                                                    // Element opacity
//--- Save real properties

//--- Save string properties
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_OBJ),this.m_struct_obj.name_obj);// Graphical element object name
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_RES),this.m_struct_obj.name_res);// Graphical resource name
   //--- Save the structure to the uchar array
   ::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;
  }
//+------------------------------------------------------------------+

In the method creating an object out of the structure, add reading the property from the structure to the object:

//+------------------------------------------------------------------+
//| Create the object from the structure                             |
//+------------------------------------------------------------------+
void CGCnvElement::StructToObject(void)
  {
//--- Save integer properties
   this.SetProperty(CANV_ELEMENT_PROP_ID,this.m_struct_obj.id);                                 // Element ID
   this.SetProperty(CANV_ELEMENT_PROP_TYPE,this.m_struct_obj.type);                             // Graphical element type
   this.SetProperty(CANV_ELEMENT_PROP_NUM,this.m_struct_obj.number);                            // Element index in the list
   this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,this.m_struct_obj.chart_id);                     // Chart ID
   this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,this.m_struct_obj.subwindow);                     // Chart subwindow index
   this.SetProperty(CANV_ELEMENT_PROP_COORD_X,this.m_struct_obj.coord_x);                       // Form's X coordinate on the chart
   this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,this.m_struct_obj.coord_y);                       // Form's Y coordinate on the chart
   this.SetProperty(CANV_ELEMENT_PROP_WIDTH,this.m_struct_obj.width);                           // Element width
   this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,this.m_struct_obj.height);                         // Element height
   this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.m_struct_obj.edge_right);                      // Element right edge
   this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.m_struct_obj.edge_bottom);                    // Element bottom edge
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,this.m_struct_obj.act_shift_left);         // Active area offset from the left edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,this.m_struct_obj.act_shift_top);           // Active area offset from the upper edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,this.m_struct_obj.act_shift_right);       // Active area offset from the right edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,this.m_struct_obj.act_shift_bottom);     // Active area offset from the bottom edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,this.m_struct_obj.movable);                       // Element moveability flag
   this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,this.m_struct_obj.active);                         // Element activity flag
   this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,this.m_struct_obj.interaction);               // Flag of interaction with the outside environment
   this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.m_struct_obj.coord_act_x);               // X coordinate of the element active area
   this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.m_struct_obj.coord_act_y);               // Y coordinate of the element active area
   this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.m_struct_obj.coord_act_right);             // Right border of the element active area
   this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.m_struct_obj.coord_act_bottom);           // Bottom border of the element active area
   this.m_color_bg=this.m_struct_obj.color_bg;                                                  // Element background color
   this.m_opacity=this.m_struct_obj.opacity;                                                    // Element opacity
//--- Save real properties

//--- Save string properties
   this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,::CharArrayToString(this.m_struct_obj.name_obj));// Graphical element object name
   this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,::CharArrayToString(this.m_struct_obj.name_res));// Graphical resource name
  }
//+------------------------------------------------------------------+


At the very end of the file listing, implement the virtual event handler:

//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CGCnvElement::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- In case of a chart change event, recalculate the shift by Y for the subwindow
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      this.m_shift_y=(int)::ChartGetInteger(this.ChartID(),CHART_WINDOW_YDISTANCE,this.WindowNum());
     }
  }
//+------------------------------------------------------------------+

Here all is simple. When receiving the chart window change event, we need to recalculate the value of the vertical shift of the subwindow coordinate since its size may change. This means we should change the number of pixels for adjusting the Y coordinate accordingly.


Form objects. Developing the functionality for handling mouse

Being a separate element of graphical constructions, the form object should have access to the mouse cursor parameters and its own event handler setting some form properties when it interacts with the mouse in various ways.

To achieve this, \MQL5\Include\DoEasy\Objects\Graph\Form.mqh form object file includes the mouse status file, while in the private class section, declare the variables necessary for handling the object of mouse properties:

//+------------------------------------------------------------------+
//|                                                         Form.mqh |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "GCnvElement.mqh"
#include "ShadowObj.mqh"
#include "Animations\Animations.mqh"
#include "..\..\Services\MouseState.mqh"
//+------------------------------------------------------------------+
//| Form object class                                                |
//+------------------------------------------------------------------+
class CForm : public CGCnvElement
  {
private:
   CArrayObj         m_list_elements;                          // List of attached elements
   CAnimations      *m_animations;                             // Pointer to the animation object
   CShadowObj       *m_shadow_obj;                             // Pointer to the shadow object
   CMouseState       m_mouse;                                  // "Mouse status" class object
   ENUM_MOUSE_FORM_STATE m_mouse_form_state;                   // Mouse status relative to the form
   ushort            m_mouse_state_flags;                      // Mouse status flags
   color             m_color_frame;                            // Form frame color
   int               m_frame_width_left;                       // Form frame width to the left
   int               m_frame_width_right;                      // Form frame width to the right
   int               m_frame_width_top;                        // Form frame width at the top
   int               m_frame_width_bottom;                     // Form frame width at the bottom
   int               m_offset_x;                               // Offset of the X coordinate relative to the cursor
   int               m_offset_y;                               // Offset of the Y coordinate relative to the cursor
   
//--- Initialize the variables
   void              Initialize(void);
//--- Reset the array size of (1) text, (2) rectangular and (3) geometric animation frames
   void              ResetArrayFrameT(void);
   void              ResetArrayFrameQ(void);
   void              ResetArrayFrameG(void);
   
//--- Return the name of the dependent object
   string            CreateNameDependentObject(const string base_name)  const
                       { return ::StringSubstr(this.NameObj(),::StringLen(::MQLInfoString(MQL_PROGRAM_NAME))+1)+"_"+base_name;   }
  
//--- Create a new graphical object
   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);

//--- Create a shadow object
   void              CreateShadowObj(const color colour,const uchar opacity);
   
public:


In the public section of the class, declare the methods for handling the mouse status object and the virtual event handler of the form object:

public:
//--- Return the mouse status relative to the form
   ENUM_MOUSE_FORM_STATE MouseFormState(const int id,const long lparam,const double dparam,const string sparam);
//--- Set the flags of mouse scrolling, context menu and the crosshairs tool for the chart
   void              SetChartTools(const bool flag);

//--- (1) Set and (2) return the shift of X and Y coordinates relative to the cursor
   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;        }
//--- Return the (1) X and (2) Y coordinate of the cursor
   int               MouseCursorX(void)            const { return this.m_mouse.CoordX();  }
   int               MouseCursorY(void)            const { return this.m_mouse.CoordY();  }
   
//--- Event handler
   virtual void      OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam);
//--- Constructors
                     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(); }
//--- Destructor
                    ~CForm();


In the method for initializing the class variables, set the default variables for the mouse button and cursor movement flags and call the parent class method for setting the flag of interaction between the form and the mouse:

//+------------------------------------------------------------------+
//| Initialize the variables                                         |
//+------------------------------------------------------------------+
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());
  }
//+------------------------------------------------------------------+


Write the method returning the mouse status relative to the form:

//+------------------------------------------------------------------+
//| Return the mouse status relative to the form                     |
//+------------------------------------------------------------------+
ENUM_MOUSE_FORM_STATE CForm::MouseFormState(const int id,const long lparam,const double dparam,const string sparam)
  {
//--- Get the mouse status relative to the form, as well as the states of mouse buttons and Shift/Ctrl keys
   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);
//--- Get the mouse status flags from the CMouseState class object and save them in the variable
   this.m_mouse_state_flags=this.m_mouse.GetMouseFlags();
//--- If the cursor is inside the form
   if(CGCnvElement::CursorInsideElement(m_mouse.CoordX(),m_mouse.CoordY()))
     {
      //--- Set bit 8 responsible for the "cursor inside the form" flag
      this.m_mouse_state_flags |= (0x0001<<8);
      //--- If the cursor is inside the active area, set bit 9 "cursor inside the active area"
      if(CGCnvElement::CursorInsideActiveArea(m_mouse.CoordX(),m_mouse.CoordY()))
         this.m_mouse_state_flags |= (0x0001<<9);
      //--- otherwise, release the bit "cursor inside the active area"
      else this.m_mouse_state_flags &=0xFDFF;
      //--- If one of the mouse buttons is clicked, check the cursor location in the active area and
      //--- return the appropriate value of the pressed key (in the active area or the form area)
      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);
      //--- otherwise, if not a single mouse button is pressed
      else
        {
         //--- if the mouse wheel is scrolled, return the appropriate wheel scrolling value (in the active area or the form area)
         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);
         //--- otherwise, return the appropriate value of the unpressed key (in the active area or the form area)
         else
            form_state=((this.m_mouse_state_flags & 0x0200)!=0 ? MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED : MOUSE_FORM_STATE_INSIDE_NOT_PRESSED);
        } 
     }
//--- If the cursor is outside the form
   else
     {
      //--- return the appropriate button value in an inactive area
      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;
  }
//+------------------------------------------------------------------+

We have considered this method in details in the article 73 when creating a test form object. Now, the method has been slightly enhanced for tracking mouse button states when placing the cursor outside the form. The method logic has been described in detail in the listing. In any case, you are welcome to use the comments section.

The form object event handler:

//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CForm::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   CGCnvElement::OnChartEvent(id,lparam,dparam,sparam);
//--- Get the status of mouse buttons, as well as of Shift and Ctrl keys
   this.m_mouse_form_state=this.MouseFormState(id,lparam,dparam-this.m_shift_y,sparam);

//--- Check, at which chart location the mouse button has been (and is still) pressed – outside the form or inside it
//--- If the left mouse button is pressed, consider it pressed
   bool pressed=(this.m_mouse.ButtonKeyState(id,lparam,dparam,sparam)==MOUSE_BUTT_KEY_STATE_LEFT ? true : false);
//--- If the left mouse button is pressed outside the form, set its pressed_chart variable to '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);
//--- If the left mouse button is pressed inside the form, set the pressed_form variable to '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 the button was pressed on the chart for its relocation,
   if(pressed_chart)
     {
      //--- reset the interaction flag and allow scrolling the chart using the mouse wheel, the context menu and the Crosshairs tool
      this.SetInteraction(false);
      this.SetChartTools(true);
     }
//--- Otherwise, if the button inside the form is pressed and the interaction flag is not set yet,
   else if(pressed_form && !this.Interaction())
     {
      //--- move the form above all the rest, set the interaction flag,
      //--- disable scrolling the chart with the mouse wheel, the chart context menu and the Crosshairs tool,
      //--- and set the mouse cursor shift values inside the form relative to its coordinate origin in the upper left corner
      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();
     }
//--- In case of the cursor movement event
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- If the interaction flag is set for the form
      if(this.Interaction())
        {
         //--- If the left mouse button is pressed inside the form active area
         if(this.MouseFormState(id,lparam,dparam,sparam)==MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED)
           {
            //--- If the form follows the cursor
            if(this.Move(this.m_mouse.CoordX()-this.m_offset_x,this.m_mouse.CoordY()-this.m_offset_y,true))
              {
               //--- Set the new cursor movement values relative to the form coordinate origin
               this.m_offset_x=this.m_mouse.CoordX()-this.CoordX();
               this.m_offset_y=this.m_mouse.CoordY()-this.CoordY();
              }
           }
        }
      //--- Display the comment with the control variable values on the chart
      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()
        );
     }
  }
//+------------------------------------------------------------------+

The method also has detailed comments. In case of a chart event, the handler first checks the mouse button status and the cursor position. The flags of the overall mouse status are set after that (left mouse button is pressed on the chart or inside the active form area). Then the flags are used for the handler logic branching. The idea is that if the mouse button is pressed outside the form, additional tools are allowed for the chart (mouse scrolling, context menu and crosshairs), while the flag of form's interaction with the mouse is reset.
If the left mouse button is pressed inside the active form area, additional tools are disabled for the chart, while the flag of interacting with the mouse is set for the form.

This should eventually lead to the following behavior: if we hold the form using the mouse button, we can move it without moving the entire chart. If we start scrolling the mouse wheel inside the form, the chart should remain fixed (since the form is to contain other elements supporting the mouse wheel scrolling, while the chart should not react to it).

At the same time, only one form should remain active for interacting with the mouse (the form on the foreground held by the button or with the mouse cursor hovering over it). I will gradually implement all this later.

The method setting the flags of scrolling the chart with the mouse, context menu and crosshairs tool for the chart:

//+------------------------------------------------------------------+
//| Set the flags of mouse scrolling,                                |
//| context menu and crosshairs for the chart                        |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+

The method receives the flag. The flag value is set for each chart property.

Since the composite graphical objects also contain form objects as control objects for the base graphical object anchor points, let's slightly improve the extended standard graphical object toolkit class in \MQL5\Include\DoEasy\Objects\Graph\Extend\CGStdGraphObjExtToolkit.mqh.

In the event handler, add handling mouse movements:

//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
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);
     }
  }
//+------------------------------------------------------------------+

Here we call the event handler of each subsequent form object in a loop by the list of form objects of a composite graphical object. The method will be improved when I continue my work on the composite graphical objects.

The object of the class is included into the extended standard graphical object. In order to access the event handler considered above, I will improve the appropriate event handler in the standard graphical object class.

Open the standard graphical object class file \MQL5\Include\DoEasy\Objects\Graph\Standard\GStdGraphObj.mqh and add some improvements to it.

In the protected parametric constructor, check whether the object is extended. If yes, set selection and availability flags for it to false. In case of an ordinary standard graphical object, the flags of these properties are taken directly from the graphical object:

//+------------------------------------------------------------------+
//| Protected parametric constructor                                 |
//+------------------------------------------------------------------+
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)
  {
//--- Create the property object with the default values
   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);
//--- Set the number of pivot points and object levels
   this.m_pivots=pivots;
   int levels=(int)::ObjectGetInteger(chart_id,name,OBJPROP_LEVELS);

//--- Set the property array dimensionalities according to the number of pivot points and 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);
   
//--- Set the object (1) type, type of graphical (2) object, (3) element, (4) subwindow affiliation and (5) index, as well as (6) chart symbol 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));
   
//--- Save the integer properties inherent in all graphical objects but not present in the current one
   this.SetProperty(GRAPH_OBJ_PROP_CHART_ID,0,CGBaseObj::ChartID());                // Chart ID
   this.SetProperty(GRAPH_OBJ_PROP_WND_NUM,0,CGBaseObj::SubWindow());               // Chart subwindow index
   this.SetProperty(GRAPH_OBJ_PROP_TYPE,0,CGBaseObj::TypeGraphObject());            // Graphical object type (ENUM_OBJECT)
   this.SetProperty(GRAPH_OBJ_PROP_ELEMENT_TYPE,0,CGBaseObj::TypeGraphElement());   // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE)
   this.SetProperty(GRAPH_OBJ_PROP_BELONG,0,CGBaseObj::Belong());                   // Graphical object affiliation
   this.SetProperty(GRAPH_OBJ_PROP_SPECIES,0,CGBaseObj::Species());                 // Graphical object species
   this.SetProperty(GRAPH_OBJ_PROP_GROUP,0,0);                                      // Graphical object group
   this.SetProperty(GRAPH_OBJ_PROP_ID,0,0);                                         // Object ID
   this.SetProperty(GRAPH_OBJ_PROP_BASE_ID,0,0);                                    // Base object ID
   this.SetProperty(GRAPH_OBJ_PROP_NUM,0,0);                                        // Object index in the list
   this.SetProperty(GRAPH_OBJ_PROP_CHANGE_HISTORY,0,false);                         // Flag of storing the change history
   this.SetProperty(GRAPH_OBJ_PROP_BASE_NAME,0,this.Name());                        // Base object name
   
//--- Save the properties inherent in all graphical objects and present in a graphical object
   this.PropertiesRefresh();
   
//--- Save basic properties in the parent object
   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);

//--- Initialize the extended graphical object toolkit
   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);
     }

//--- Save the current properties to the previous ones
   this.PropertiesCopyToPrevData();
  }
//+-------------------------------------------------------------------+


In the event handler of the standard graphical object, send the name of the current graphical object in the sparam parameter to the event handler of the extended graphical object toolkit object. Also, add handling mouse movement events:

//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
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);
     }
  }
//+------------------------------------------------------------------+

These are all draft changes I am not going to dwell into right now. I will look into them when working on composite graphical objects.

The form objects will be managed from the graphical element collection class. The same class features the list for storing the pointers to graphical elements. The list is to receive all created forms. Currently, we will do this manually. Later, I will implement the functionality adding the objects to the list immediately upon their creation.

The graphical element collection class file \MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqh features yet another class for managing chart objects. Let's add the overloaded methods for setting the flags allowing the chart toolkit to it — wheel scrolling, mouse movement, context menu and crosshairs:

//+------------------------------------------------------------------+
//| Chart object management class                                    |
//+------------------------------------------------------------------+
class CChartObjectsControl : public CObject
  {
private:
   CArrayObj         m_list_new_graph_obj;      // List of added graphical objects
   ENUM_TIMEFRAMES   m_chart_timeframe;         // Chart timeframe
   long              m_chart_id;                // Chart ID
   long              m_chart_id_main;           // Control program chart ID
   string            m_chart_symbol;            // Chart symbol
   bool              m_is_graph_obj_event;      // Event flag in the list of graphical objects
   int               m_total_objects;           // Number of graphical objects
   int               m_last_objects;            // Number of graphical objects during the previous check
   int               m_delta_graph_obj;         // Difference in the number of graphical objects compared to the previous check
   int               m_handle_ind;              // Event controller indicator handle
   string            m_name_ind;                // Short name of the event controller indicator
   string            m_name_program;            // Program name
   
//--- Return the name of the last graphical object added to the chart
   string            LastAddedGraphObjName(void);
//--- Set the permission to track mouse events and graphical objects
   void              SetMouseEvent(void);

public:
//--- Return the variable values
   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;    }
//--- Set the flags of scrolling the chart with the mouse, context menu and crosshairs tool for the chart
   void              SetChartTools(const bool flag);
   void              SetChartTools(const bool mouse_scroll,const bool context_menu,const bool crosshair_tool);
//--- Create a new standard (or extended) graphical object
   CGStdGraphObj    *CreateNewGraphObj(const ENUM_OBJECT obj_type,const string name,const bool extended);
//--- Return the list of newly added objects
   CArrayObj        *GetListNewAddedObj(void)                        { return &this.m_list_new_graph_obj;}
//--- Create the event control indicator
   bool              CreateEventControlInd(const long chart_id_main);
//--- Add the event control indicator to the chart
   bool              AddEventControlInd(void);
//--- Check the chart objects
   void              Refresh(void);
//--- Constructors
                     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();
                       }
//--- Destructor
                     ~CChartObjectsControl()
                       {
                        ::ChartIndicatorDelete(this.ChartID(),0,this.m_name_ind);
                        ::IndicatorRelease(this.m_handle_ind);
                       }
                     
//--- Compare CChartObjectsControl objects by a chart ID (for sorting the list by an object property)
   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);
                       }

//--- Event handler
   void              OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam);

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

Let's write their implementation outside the class body:

//+------------------------------------------------------------------+
//| Set the flags of mouse scrolling,                                |
//| context menu and crosshairs for the chart                        |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Set the flags of mouse scrolling,                                |
//| context menu and crosshairs for the chart                        |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+

Similar methods have already been considered above. Here the difference is that one of them receives the flags for each instrument separately. These methods may be of use later for managing charts from the graphical element collection class, in which the method is renamed

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

into something more suitable in terms of underlying idea and with different parameters.
Also, let's add the (temporarily) public method for adding graphical elements to the collection list:

//+------------------------------------------------------------------+
//| Collection of graphical objects                                  |
//+------------------------------------------------------------------+
#resource "\\"+PATH_TO_EVENT_CTRL_IND;          // Indicator for controlling graphical object events packed into the program resources
class CGraphElementsCollection : public CBaseObj
  {
private:
   CArrayObj         m_list_charts_control;     // List of chart management objects
   CListObj          m_list_all_canv_elm_obj;   // List of all graphical elements on canvas
   CListObj          m_list_all_graph_obj;      // List of all graphical objects
   CArrayObj         m_list_deleted_obj;        // List of removed graphical objects
   bool              m_is_graph_obj_event;      // Event flag in the list of graphical objects
   int               m_total_objects;           // Number of graphical objects
   int               m_delta_graph_obj;         // Difference in the number of graphical objects compared to the previous check
   
//--- Return the flag indicating the graphical element class object presence in the collection list of graphical elements
   bool              IsPresentCanvElmInList(const long chart_id,const string name);
//--- Return the flag indicating the presence of the graphical object class in the graphical object collection list
   bool              IsPresentGraphObjInList(const long chart_id,const string name);
//--- Return the flag indicating the presence of a graphical object on a chart by name
   bool              IsPresentGraphObjOnChart(const long chart_id,const string name);
//--- Return the pointer to the object of managing objects of the specified chart
   CChartObjectsControl *GetChartObjectCtrlObj(const long chart_id);
//--- Create a new object of managing graphical objects of a specified chart and add it to the list
   CChartObjectsControl *CreateChartObjectCtrlObj(const long chart_id);
//--- Update the list of graphical objects by chart ID
   CChartObjectsControl *RefreshByChartID(const long chart_id);
//--- Check if the chart window is present
   bool              IsPresentChartWindow(const long chart_id);
//--- Handle removing the chart window
   void              RefreshForExtraObjects(void);
//--- Return the first free ID of the graphical (1) object and (2) element on canvas
   long              GetFreeGraphObjID(bool program_object);
   long              GetFreeCanvElmID(void);
//--- Add (1) the standard graphical object and (2) the graphical element on canvas to the collection
   bool              AddGraphObjToCollection(const string source,CChartObjectsControl *obj_control);
public:
   bool              AddCanvElmToCollection(CGCnvElement *element);
   
private:

For now, the method remains public. Later, when I implement adding newly created graphical elements on canvas to the list immediately after their creation, I will make the method private.

In the private section of the class, declare the method setting the already familiar chart flags:

public:
   bool              AddCanvElmToCollection(CGCnvElement *element);
   
private:
//--- Find an object present in the collection but not on a chart
   CGStdGraphObj    *FindMissingObj(const long chart_id);
   CGStdGraphObj    *FindMissingObj(const long chart_id,int &index);
//--- Find the graphical object present on a chart but not in the collection
   string            FindExtraObj(const long chart_id);
//--- Remove the graphical object class object from the graphical object collection list: (1) specified object, (2) by chart ID
   bool              DeleteGraphObjFromList(CGStdGraphObj *obj);
   void              DeleteGraphObjectsFromList(const long chart_id);
//--- Move the graphical object class object to the list of removed graphical objects: (1) specified object, (2) by index
   bool              MoveGraphObjToDeletedObjList(CGStdGraphObj *obj);
   bool              MoveGraphObjToDeletedObjList(const int index);
//--- Move all objects by chart ID to the list of removed graphical objects
   void              MoveGraphObjectsToDeletedObjList(const long chart_id);
//--- Remove the object of managing charts from the list
   bool              DeleteGraphObjCtrlObjFromList(CChartObjectsControl *obj);
//--- Set the flags of scrolling the chart with the mouse, context menu and crosshairs tool for the specified chart
   void              SetChartTools(const long chart_id,const bool flag);
public:


In each of the public methods for creating the graphical object, set the selection and availability flags the same way as considered above. Let's use the method for creating a vertical line as an example:

public:
//--- Create the "Vertical line" graphical object
   bool              CreateLineVertical(const long chart_id,const string name,const int subwindow,const bool extended,const datetime time)
                       {
                        //--- Set the name and type of a created object
                        string nm=this.m_name_program+"_"+name;
                        ENUM_OBJECT type_object=OBJ_VLINE;
                        //--- Create a new graphical object and get the pointer to the chart management object
                        CChartObjectsControl *ctrl=this.CreateNewStdGraphObjectAndGetCtrlObj(chart_id,nm,subwindow,type_object,time,0);
                        if(ctrl==NULL)
                           return false;
                        //--- Create a new class object corresponding to the newly created graphical object
                        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;
                          }
                        //--- Set the necessary minimal parameters for an object
                        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 the result of adding the object to the list
                        return this.AddCreatedObjToList(DFUN,chart_id,nm,obj);
                       }

All other similar methods for creating graphical objects have already been improved in a similar way. There is no point in considering them here.

The method adding the graphical element on canvas to the collection:

//+------------------------------------------------------------------+
//| Add the graphical element on canvas to the collection            |
//+------------------------------------------------------------------+
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;
  }
//+------------------------------------------------------------------+

The method receives the pointer to the graphical element to be placed to the list.
If the same object is already present in the list, — inform of that and return false.
If failed to place the pointer to the list, inform of that and return false.
If successful, return true.

The method returning the flag indicating the graphical element class object presence in the collection list of graphical elements:

//+-------------------------------------------------------------------------------+
//| Return the flag indicating the presence of the graphical element class object |
//| in the graphical element collection list                                      |
//+-------------------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+

A chart ID and the name of the object whose presence in the list should be checked are passed to the method.
Next, get the list of objects with the specified chart ID and sort the obtained list by the necessary name.
If failed to obtain the list or the list is empty, return false — the object is not in the list, otherwise return true — the object is found.

Event handler. Here we add calling the event handler from the list of standard graphical objects and handling mouse events related to graphical elements on canvas:

//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CGraphElementsCollection::OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
   CGStdGraphObj *obj_std=NULL;  // Pointer to the standard graphical object
   CGCnvElement  *obj_cnv=NULL;  // Pointer to the graphical element object on canvas
   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)
     {
      //--- Calculate the chart ID
      //--- If the event ID corresponds to an event from the current chart, the chart ID is received from ChartID
      //--- If the event ID corresponds to a user event, the chart ID is received from lparam
      //--- Otherwise, the chart ID is assigned to -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);
      //--- Get the object, whose properties were changed or which was relocated,
      //--- from the collection list by its name set in sparam
      obj_std=this.GetStdGraphObject(sparam,chart_id);
      //--- If failed to get the object by its name, it is not on the list,
      //--- which means its name has been changed
      if(obj_std==NULL)
        {
         //--- Let's search the list for the object that is not on the chart
         obj_std=this.FindMissingObj(chart_id);
         //--- If failed to find the object here as well, exit
         if(obj_std==NULL)
            return;
         //--- Get the name of the renamed graphical object on the chart, which is not in the collection list
         string name_new=this.FindExtraObj(chart_id);
         //--- set a new name for the collection list object, which does not correspond to any graphical object on the chart,
         //--- and send an event with the new name of the object to the control program chart
         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());
        }
      //--- Update the properties of the obtained object
      //--- and check their change
      obj_std.PropertiesRefresh();
      obj_std.PropertiesCheckChanged();
     }
//--- Handle standard graphical object events in the collection list
   for(int i=0;i<this.m_list_all_graph_obj.Total();i++)
     {
      //--- Get the next graphical object and
      obj_std=this.m_list_all_graph_obj.At(i);
      if(obj_std==NULL)
         continue;
      //--- call its event handler
      obj_std.OnChartEvent((id<CHARTEVENT_CUSTOM ? id : idx),lparam,dparam,sparam);
     }

//--- Handling mouse events of graphical objects on canvas
   if(id==CHARTEVENT_MOUSE_MOVE || idx==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Get the list of graphical elements with a specified interaction flag (there should be only one object)
      CArrayObj *list=CSelect::ByGraphCanvElementProperty(GetListCanvElm(),CANV_ELEMENT_PROP_INTERACTION,true,EQUAL);
      //--- If failed to obtain the list or it is empty
      if(list==NULL || list.Total()==0)
        {
         //--- In the loop by the list of graphical elements
         for(int i=0;i<this.m_list_all_canv_elm_obj.Total();i++)
           {
            //--- Get the next element and call its event handler
            obj_cnv=this.m_list_all_canv_elm_obj.At(i);
            if(obj_cnv==NULL)
               continue;
            //--- In the event handler, set the interaction flag if the cursor hovers over the form with the pressed mouse button
            obj_cnv.OnChartEvent(CHARTEVENT_MOUSE_MOVE,lparam,dparam,sparam);
           }
        }
      //--- If the list is received
      if(list!=NULL)
        {
         //--- Get the only object from it
         obj_cnv=list.At(0);
         //--- If the object has been received and it is a form object
         if(obj_cnv!=NULL && obj_cnv.TypeGraphElement()==GRAPH_ELEMENT_TYPE_FORM)
           {
            //--- Create the pointer to the obtained form object. If the pointer is received,
            CForm *form=obj_cnv;
            if(form!=NULL)
              {
               //--- disable moving the chart with a mouse, the chart context menu and the crosshairs tool
               form.SetChartTools(false);
               form.OnChartEvent(CHARTEVENT_MOUSE_MOVE,lparam,dparam,sparam);
              }
           }
        }
     }

//--- Handle chart changes for extended standard objects
   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);
           }
        }
     }
  }
//+------------------------------------------------------------------+

The code block has been thoroughly commented in the listing. The idea here is that we should have only one form object the mouse is able to interact with. Thus, we first check if the object is present. If it is, work strictly in its event handler.

The method setting the flags of scrolling the chart with the mouse, context menu and the crosshairs tool for the specified chart:

//+------------------------------------------------------------------+
//| Set the flags of scrolling a chart                               |
//| context menu and crosshairs for the chart                        |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+

We already know this method via the similar methods considered earlier. In addition to the flag, it also receives the ID of the required chart.

In order to handle the collection list of graphical elements, we also need to provide access to them from the program. This is always done in the main class of the CEngine library in \MQL5\Include\DoEasy\Engine.mqh.

Currently, two public methods are sufficient for testing:

//--- Return the class of the object of the extended standard graphical object by chart name and ID
   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);
                          }

//--- Return the list of graphical elements on canvas
   CArrayObj           *GetListCanvElement(void)                           { return this.m_graph_objects.GetListCanvElm();                }
//--- Add the graphical element on canvas to the collection
   bool                 GraphAddCanvElmToCollection(CGCnvElement *element) { return this.m_graph_objects.AddCanvElmToCollection(element); }
   
//--- Fill in the array with IDs of the charts opened in the terminal
   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();
                          }
                       }

One of the methods returns the list of graphical elements to the collection, while the second one adds a newly created graphical element to the collection.

This is all that we currently need in order to check the new functionality.


Test

To perform the test, let's use the EA from the previous article and save it to \MQL5\Experts\TestDoEasy\Part96\ as TestDoEasyPart96.mq5.

Remove the form object list from the list of global EA variables:

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

We do not need the list because the newly created forms will now be located in the library collection list.

In the OnInit() handler, add the code block with the loop of creating two form objects:

//+------------------------------------------------------------------+
//|                                             TestDoEasyPart96.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//--- includes
#include <DoEasy\Engine.mqh>
//--- defines
#define        FORMS_TOTAL (4)   // Number of created forms
#define        START_X     (4)   // Initial X coordinate of the shape
#define        START_Y     (4)   // Initial Y coordinate of the shape
#define KEY_LEFT           (188) // Left
#define KEY_RIGHT          (190) // Right
#define KEY_ORIGIN         (191) // Initial properties
//--- 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()
  {
//--- Set EA global variables
   ArrayResize(array_clr,2);        // Array of gradient filling colors
   array_clr[0]=C'26,100,128';      // Original ≈Dark-azure color
   array_clr[1]=C'35,133,169';      // Lightened original color
//--- Create the array with the current symbol and set it to be used in the library
   string array[1]={Symbol()};
   engine.SetUsedSymbols(array);
   //--- Create the timeseries object for the current symbol and period, and show its description in the journal
   engine.SeriesCreate(Symbol(),Period());
   engine.GetTimeSeriesCollection().PrintShort(false); // Short descriptions
//--- Create form objects
   for(int i=0;i<2;i++)
     {
      //--- When creating an object, pass all the required parameters to it
      CForm *form=new CForm("Form_0"+string(i+1),30,(i==0 ? 80 : 150),100,30);
      if(form==NULL)
         continue;
      //--- Set activity and moveability flags for the form
      form.SetActive(true);
      form.SetMovable(true);
      //--- Set the form ID and the index in the list of objects
      form.SetID(i);
      form.SetNumber(0);   // (0 - main form object) Auxiliary objects may be attached to the main one. The main object is able to manage them
      //--- Set the opacity of 200
      form.SetOpacity(245);
      //--- The form background color is set as the first color from the color array
      form.SetColorBackground(array_clr[0]);
      //--- Form outlining frame color
      form.SetColorFrame(clrDarkBlue);
      //--- Draw the shadow drawing flag
      form.SetShadow(false);
      //--- Calculate the shadow color as the chart background color converted to the monochrome one
      color clrS=form.ChangeColorSaturation(form.ColorBackground(),-100);
      //--- If the settings specify the usage of the chart background color, replace the monochrome color with 20 units
      //--- Otherwise, use the color specified in the settings for drawing the shadow
      color clr=(InpUseColorBG ? form.ChangeColorLightness(clrS,-20) : InpColorForm3);
      //--- Draw the form shadow with the right-downwards offset from the form by three pixels along all axes
      //--- Set the shadow opacity to 200, while the blur radius is equal to 4
      form.DrawShadow(3,3,clr,200,4);
      //--- Fill the form background with a vertical gradient
      form.Erase(array_clr,form.Opacity(),true);
      //--- Draw an outlining rectangle at the edges of the form
      form.DrawRectangle(0,0,form.Width()-1,form.Height()-1,form.ColorFrame(),form.Opacity());
      form.Done();
      
      //--- Display the text describing the gradient type and update the form
      //--- Text parameters: the text coordinates and the anchor point in the form center
      //--- Create a new text animation frame with the ID of 0 and display the text on the form
      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);
      //--- Add the form to the list
      if(!engine.GraphAddCanvElmToCollection(form))
         delete form;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

Everything is thoroughly commented here. Besides, I have already considered a similar creation of form objects in some previous articles.
Two forms are created in the loop. Display parameters are set for them, while the pointers to the forms are placed into the library collection list.

Compile the EA and launch it on the chart. Two forms with the ability to drag them with a mouse independently of each other are created. Each current form is always located above other objects — on the foreground, while data on a selected form is displayed in the chart comments:


We can see that the forms can be relocated independently of each other, while the chart remains fixed. Each active form is always located on the foreground. However, there are considerable drawbacks as well: if we move the chart with the mouse and the cursor touches the form area, it becomes active and can be managed. Cursor coordinate changes relative to the form reference point can occasionally be calculated incorrectly after the chart is dragged by the mouse.

I will detect and fix all these drawbacks during the further development.


What's next?

In the next article, I will continue my work on events and interactions between the forms and mouse.

All files of the current library version, test EA and chart event control indicator for MQL5 are attached below for you to test and download. Leave your questions, comments and suggestions in the comments.

Back to contents

*Previous articles within the series:

Graphics in DoEasy library (Part 93): Preparing functionality for creating composite graphical objects
Graphics in DoEasy library (Part 94): Moving and deleting composite graphical objects
Graphics in DoEasy library (Part 95): Composite graphical object controls

Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/10417

Attached files |
MQL5.zip (4226.84 KB)
Mathematics in trading: Sharpe and Sortino ratios Mathematics in trading: Sharpe and Sortino ratios
Return on investments is the most obvious indicator which investors and novice traders use for the analysis of trading efficiency. Professional traders use more reliable tools to analyze strategies, such as Sharpe and Sortino ratios, among others.
MVC design pattern and its application (Part 2): Diagram of interaction between the three components MVC design pattern and its application (Part 2): Diagram of interaction between the three components
This article is a continuation and completion of the topic discussed in the previous article: the MVC pattern in MQL programs. In this article, we will consider a diagram of possible interaction between the three components of the pattern.
Learn how to design a trading system by CCI Learn how to design a trading system by CCI
In this new article from our series for learning how to design trading systems, I will present the Commodities Channel Index (CCI), explain its specifics, and share with you how to create a trading system based on this indicator.
Learn how to design a trading system by Momentum Learn how to design a trading system by Momentum
In my previous article, I mentioned the importance of identifying the trend which is the direction of prices. In this article I will share one of the most important concepts and indicators which is the Momentum indicator. I will share how to design a trading system based on this Momentum indicator.