Graphics in DoEasy library (Part 96): Graphics in form objects and handling mouse events
Contents
- Concept
- Improving library classes
- Form objects. Developing the functionality for handling mouse
- Test
- What's next?
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.
*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
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use