Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil XIV): Das Symbolobjekt

Artyom Trishkin | 30 September, 2019

Inhalt


Ein gehandeltes Symbol spielt eine wichtige Rolle im Handel. Zunächst wird ein Programm auf dem Chart eines Symbols gestartet (mit Ausnahme der Dienste). Außerdem funktioniert und führt es Handels- und andere Operationen auf der Grundlage dieses Symbols durch. Daher wäre es sinnvoll, Bedingungen für die bequeme Beschaffung von Daten über notwendige Symbole mit der Möglichkeit zu schaffen, diese zu analysieren und zu vergleichen. Um dies zu erreichen, werden wir ein Symbolobjekt, eine Kollektion von Symbolobjekten und eine Kollektion von Symbolereignissen entwickeln.

Das Symbolobjekt

In diesem Artikel werden wir ein Basisobjekt erstellen, das eine Art "abstraktes" Symbol darstellt. Beim Erstellen einer Symbolsammlung erstellen wir dann Objekte, die aus dem Basissymbolobjekt abgeleitet sind, wobei wir Daten über die Zugehörigkeit des Symbols zu der einen oder anderen Symbolgruppe klären und einige der grundlegenden Objekteigenschaften erlauben/verwehren.

Unterteilen wir die Symbolobjekte in Kategorien:

Natürlich sind alle diese Kategorien beliebig. Die Platzierung eines Symbols in einer bestimmten Kategorie ist sehr subjektiv und hängt von den Präferenzen des Nutzers ab. Eine gewisse Klarheit erhält man durch die Eigenschaft "symbol tree path" (Symbolpfad). Sie enthält den Pfad der Symbolposition in einem bestimmten Ordner des Symbolbaums, sodass Sie einem Symbol eine Kategorie zuordnen können, die einem Ordnernamen entspricht. Jeder Server, mit dem sich das Terminal verbindet, kann jedoch über eigene Ordner zum Speichern von Symbolen mit passenden Namen verfügen. Die Namen der Ordner können von Server zu Server variieren.

Basierend auf dem, was wir haben, ist das erste, was wir tun, die Kategorie eines Symbols aus der benutzerdefinierten Liste der Kategorien zu bestimmen, und wenn das Symbol nicht in der benutzerdefinierten Kategorie gefunden wird, dann sollten wir einen Blick auf seinen Speicherort Ordner in der Symbolstruktur werfen. Wenn die Kategorie nicht aus ihrem Standortordner definiert werden kann, ist die endgültige Wahl der Symbolkategorie ihre Eigenschaft "contract price calculation method" (Kalkulationsmethode des Kontraktpreises), mit der wir eine der beiden Symbolkategorien - Börse oder Forexhandel - definieren und auswählen können.

All dies wird jedoch später bei der Entwicklung der Kollektion der Symbolobjekte durchgeführt. Nun müssen wir mit der Erstellung des Basissymbolobjekts beginnen.

Beginnen wir mit der Definition von Enumerationen und Makroersetzungen für die Eigenschaften der Symbolobjekte. Öffnen Sie die Datei Defines.mqh und fügen Sie die notwendigen Daten für die Arbeit mit einem Symbol am Ende der Liste hinzu:

//+------------------------------------------------------------------+
//| Data for working with symbols                                    |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Abstract symbol type (status)                                    |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_STATUS
  {
   SYMBOL_STATUS_FX,                                        // Forex symbol
   SYMBOL_STATUS_FX_MAJOR,                                  // Major Forex symbol
   SYMBOL_STATUS_FX_MINOR,                                  // Minor Forex symbol
   SYMBOL_STATUS_FX_EXOTIC,                                 // Exotic Forex symbol
   SYMBOL_STATUS_FX_RUB,                                    // Forex symbol/RUB
   SYMBOL_STATUS_FX_METAL,                                  // Metal
   SYMBOL_STATUS_INDEX,                                     // Index
   SYMBOL_STATUS_INDICATIVE,                                // Indicative
   SYMBOL_STATUS_CRYPTO,                                    // Cryptocurrency symbol
   SYMBOL_STATUS_COMMODITY,                                 // Commodity symbol
   SYMBOL_STATUS_EXCHANGE,                                  // Exchange symbol
   SYMBOL_STATUS_BIN_OPTION,                                // Binary option
   SYMBOL_STATUS_CUSTOM,                                    // Custom symbol
  };
//+------------------------------------------------------------------+

Der Symbolstatus ist die Zugehörigkeit zu der Symbolkategorie, die vor dem Anlegen eines vom Basissymbolobjekt abgeleiteten Objekts ausgewählt wird. Wir werden dies bei der Beschreibung der Entwicklung der Kollektion der Symbole tun.

Fügen wir die Integer-Eigenschaften der Symbole hinzu:

//+------------------------------------------------------------------+
//| Symbol integer properties                                        |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_INTEGER
  {
   SYMBOL_PROP_STATUS = 0,                                  // Symbol status
   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,                                      // An indication that the symbol is selected in Market Watch
   SYMBOL_PROP_VISIBLE,                                     // An 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_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_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,                              // StopLoss and TakeProfit orders lifetime 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)
   SYMBOL_PROP_BACKGROUND_COLOR                             // The color of the background used for the symbol in Market Watch
  }; 
#define SYMBOL_PROP_INTEGER_TOTAL    (35)                   // Total number of integer properties
#define SYMBOL_PROP_INTEGER_SKIP     (1)                    // Number of symbol integer properties not used in sorting
//+------------------------------------------------------------------+

Wir haben bereits erwogen, Enumerationen von Objekteigenschaften im Abschnitt "Implementieren der Ereignisbehandlung auf einem Netting-Konto" des sechsten Teils der Bibliotheksbeschreibung anzuordnen, so dass wir nicht auf die Definition des Zwecks von Makro-Substitutionen der Anzahl der Eigenschaften und der Anzahl der Objekteigenschaften, die nicht für die Suche und Sortierung verwendet werden, eingehen werden. Allerdings sollte ich beachten, dass neben den Integer-Eigenschaften des Standardsymbolobjekts aus der Enumeration ENUM_SYMBOL_INFO_INTEGER zwei weitere hinzugefügt wurden: Symbolstatus und Anzahl der Dezimalstellen der Losgröße des Symbols.

Lassen Sie uns die Enumeration der Real-Eigenschaften der Symbole hinzufügen:

//+------------------------------------------------------------------+
//| 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 of the day
   SYMBOL_PROP_VOLUMELOW_REAL,                              // Minimum Volume of the day
   SYMBOL_PROP_OPTION_STRIKE,                               // Option execution price
   SYMBOL_PROP_POINT,                                       // 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 price set by an issuer
   SYMBOL_PROP_TRADE_LIQUIDITY_RATE,                        // Liquidity rate – share of an asset value that can be used as a collateral
   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 a deal
   SYMBOL_PROP_VOLUME_LIMIT,                                // Maximum acceptable total volume of an open position and pending orders in one direction (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,                                 // Margin requirement applicable to long positions
   SYMBOL_PROP_MARGIN_SHORT,                                // Margin requirement applicable to short positions
   SYMBOL_PROP_MARGIN_STOP,                                 // Margin requirement applicable to Stop orders
   SYMBOL_PROP_MARGIN_LIMIT,                                // Margin requirement applicable to Limit orders
   SYMBOL_PROP_MARGIN_STOPLIMIT,                            // Margin requirement applicable to Stop Limit 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,                                // The open price of the session
   SYMBOL_PROP_SESSION_CLOSE,                               // The 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,                     // The minimum allowable price value for the session 
   SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX,                     // The 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).
  };
#define SYMBOL_PROP_DOUBLE_TOTAL     (47)                   // Total number of event's real properties
#define SYMBOL_PROP_DOUBLE_SKIP      (0)                    // Number of symbol real properties not used in sorting
//+------------------------------------------------------------------+

Abgesehen von den Eigenschaften, die in der Enumeration ENUM_SYMBOL_INFO_DOUBLE beschrieben sind, haben wir fünf neue Symboleigenschaften hinzugefügt, die aus irgendeinem Grund nicht in die Beschreibung der Aufzählung der Real-Eigenschaften aufgenommen wurden, aber sie sind immer noch vorhanden und gehören zur Enumeration.

Fügen wir die Enumeration der String-Eigenschaften des Symbols und mögliche Sortierkriterien für Symbole hinzu:

//+------------------------------------------------------------------+
//| Symbol string properties                                         |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_PROP_STRING
  {
   SYMBOL_PROP_NAME = (SYMBOL_PROP_INTEGER_TOTAL+SYMBOL_PROP_DOUBLE_TOTAL),   // Symbol name
   SYMBOL_PROP_BASIS,                                       // The name of the underlaying asset for a derivative symbol
   SYMBOL_PROP_CURRENCY_BASE,                               // The base currency of an instrument
   SYMBOL_PROP_CURRENCY_PROFIT,                             // Profit currency
   SYMBOL_PROP_CURRENCY_MARGIN,                             // Margin currency
   SYMBOL_PROP_BANK,                                        // The source of the current quote
   SYMBOL_PROP_DESCRIPTION,                                 // The 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 address of the web page containing symbol information
   SYMBOL_PROP_PATH,                                        // Path in the symbol tree
  };
#define SYMBOL_PROP_STRING_TOTAL     (11)                   // Total number of string 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
  {
//--- Sortieren nach den Integer-Eigenschaften
   SORT_BY_SYMBOL_STATUS = 0,                               // Sort by symbol status
   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_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_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)
//--- Sortieren nach den Double-Eigenschaften
   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 minimal 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,                              // Sort by coefficient of margin charging for long positions
   SORT_BY_SYMBOL_MARGIN_SHORT,                             // Sort by coefficient of margin charging for short positions
   SORT_BY_SYMBOL_MARGIN_STOP,                              // Sort by coefficient of margin charging for Stop orders
   SORT_BY_SYMBOL_MARGIN_LIMIT,                             // Sort by coefficient of margin charging for Limit orders
   SORT_BY_SYMBOL_MARGIN_STOPLIMIT,                         // Sort by coefficient of margin charging for Stop Limit 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 an Open price of the current session
   SORT_BY_SYMBOL_SESSION_CLOSE,                            // Sort by a Close price of the current session
   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 minimal price of the current session 
   SORT_BY_SYMBOL_SESSION_PRICE_LIMIT_MAX,                  // Sort by a maximal 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
//--- Sortieren nach den String-Eigenschaften
   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 basic 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 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
  };
//+------------------------------------------------------------------+

Die Enumeration der String-Eigenschaften enthält nun die entsprechenden Konstanten aus der Enumeration ENUM_SYMBOL_INFO_STRING, während die Liste der möglichen Sortierkriterien alle Symboleigenschaften ohne die Hintergrundfarbe der Symbole im Fenster Marktübersicht enthält. Es gibt keinen Grund, Symbole im zum Terminal gehörenden Fenster nach ihrer Hintergrundfarbe zu sortieren und zu vergleichen.

Dies sind alle notwendigen Daten für die Arbeit mit Symbolobjekten.

Lassen Sie uns nun die Symbol-Objektklasse entwickeln.

Erstellen Sie in \MQL5\Include\DoEasy\Objects\ die neue Datei der Klasse CCymbol namens Symbol.mqh. Tragen Sie die Klasse gleich die Einbindungen und Methoden ein, die standardmäßig für die Bibliothek sind:

//+------------------------------------------------------------------+
//|                                                       Symbol.mqh |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/de/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/de/users/artmedia70"
#property version   "1.00"
#property strict    // Notwendig für mql4
//+------------------------------------------------------------------+
//| Include-Dateien                                                  |
//+------------------------------------------------------------------+
#include <Object.mqh>
#include "..\..\Services\DELib.mqh"
//+------------------------------------------------------------------+
//| Abstract symbol class                                            |
//+------------------------------------------------------------------+
class CSymbol : public CObject
  {
private:
   long              m_long_prop[SYMBOL_PROP_INTEGER_TOTAL];         // Integer properties
   double            m_double_prop[SYMBOL_PROP_DOUBLE_TOTAL];        // Real properties
   string            m_string_prop[SYMBOL_PROP_STRING_TOTAL];        // String properties
//--- Return the index of the array the symbol's (1) double and (2) string properties are located at
   int               IndexProp(ENUM_SYMBOL_PROP_DOUBLE property)  const { return(int)property-SYMBOL_PROP_INTEGER_TOTAL;                                    }
   int               IndexProp(ENUM_SYMBOL_PROP_STRING property)  const { return(int)property-SYMBOL_PROP_INTEGER_TOTAL-SYMBOL_PROP_DOUBLE_TOTAL;           }
public:
//--- Standardmäßiger Konstruktor
                     CSymbol(void){;}
protected:
//--- 'Protected' Konstruktor
                     CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name);

public:
//--- Set (1) integer, (2) real and (3) string symbol properties
   void              SetProperty(ENUM_SYMBOL_PROP_INTEGER property,long value)   { this.m_long_prop[property]=value;                                        }
   void              SetProperty(ENUM_SYMBOL_PROP_DOUBLE property,double value)  { this.m_double_prop[this.IndexProp(property)]=value;                      }
   void              SetProperty(ENUM_SYMBOL_PROP_STRING property,string value)  { this.m_string_prop[this.IndexProp(property)]=value;                      }
//--- Return (1) integer, (2) real and (3) string symbol properties from the properties array
   long              GetProperty(ENUM_SYMBOL_PROP_INTEGER property)        const { return this.m_long_prop[property];                                       }
   double            GetProperty(ENUM_SYMBOL_PROP_DOUBLE property)         const { return this.m_double_prop[this.IndexProp(property)];                     }
   string            GetProperty(ENUM_SYMBOL_PROP_STRING property)         const { return this.m_string_prop[this.IndexProp(property)];                     }

//--- Return the flag of a symbol supporting the property
   virtual bool      SupportProperty(ENUM_SYMBOL_PROP_INTEGER property)    { return true; }
   virtual bool      SupportProperty(ENUM_SYMBOL_PROP_DOUBLE property)     { return true; }
   virtual bool      SupportProperty(ENUM_SYMBOL_PROP_STRING property)     { return true; }

//+------------------------------------------------------------------+
//| Description of symbol object properties                          |
//+------------------------------------------------------------------+
//--- Get description of a symbol (1) integer, (2) real and (3) string properties
   string            GetPropertyDescription(ENUM_SYMBOL_PROP_INTEGER property);
   string            GetPropertyDescription(ENUM_SYMBOL_PROP_DOUBLE property);
   string            GetPropertyDescription(ENUM_SYMBOL_PROP_STRING property);
//--- Return symbol status name
   string            StatusDescription(void)    const;
//--- Send description of symbol properties to the journal (full_prop=true - all properties, false - only supported ones)
   void              Print(const bool full_prop=false);

//--- Compare CSymbol objects by all possible properties (for sorting lists by a specified symbol object property)
   virtual int       Compare(const CObject *node,const int mode=0) const;
//--- Compare CSymbol objects by all properties (for searching for equal event objects)
   bool              IsEqual(CSymbol* compared_symbol) const;

  };

Wir haben alle diese Methoden bereits im ersten Teil der Bibliotheksbeschreibung berücksichtigt. Es hat keinen Sinn, hier auf sie einzugehen.

Nun fügen wir die für die Klassenoperation notwendigen Variablen dem 'private' Abschnitt hinzu:

//+------------------------------------------------------------------+
//|                                                       Symbol.mqh |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/de/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/de/users/artmedia70"
#property version   "1.00"
#property strict    // Notwendig für mql4
//+------------------------------------------------------------------+
//| Include-Dateien                                                  |
//+------------------------------------------------------------------+
#include <Object.mqh>
#include "..\..\Services\DELib.mqh"
//+------------------------------------------------------------------+
//| Abstract symbol class                                            |
//+------------------------------------------------------------------+
class CSymbol : public CObject
  {
private:
   MqlTick           m_tick;                                         // Symbol tick structure
   MqlBookInfo       m_book_info_array[];                            // Array of the market depth data structures
   string            m_symbol_name;                                  // Symbol name
   long              m_long_prop[SYMBOL_PROP_INTEGER_TOTAL];         // Integer properties
   double            m_double_prop[SYMBOL_PROP_DOUBLE_TOTAL];        // Real properties
   string            m_string_prop[SYMBOL_PROP_STRING_TOTAL];        // String properties
   int               m_digits_currency;                              // Number of decimal places in an account currency
   int               m_global_error;                                 // Global error code
//--- Return the index of the array the symbol's (1) double and (2) string properties are located at
   int               IndexProp(ENUM_SYMBOL_PROP_DOUBLE property)  const { return(int)property-SYMBOL_PROP_INTEGER_TOTAL;                                    }
   int               IndexProp(ENUM_SYMBOL_PROP_STRING property)  const { return(int)property-SYMBOL_PROP_INTEGER_TOTAL-SYMBOL_PROP_DOUBLE_TOTAL;           }
//--- Reset all symbol object data
   void              Reset(void);
public:
//--- Standardmäßiger Konstruktor
                     CSymbol(void){;}
protected:
//--- 'Protected' Konstruktor
                     CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name);

Wir werden Ask, Bid, Last Price und Tick Time Daten aus der Tick Struktur erhalten — in Millisekunden für MQL5 und in Sekunden für MQL4. Obwohl das Millisekundenfeld in der Tickstruktur in MQL4 vorhanden ist, wird es nicht verwendet. Daher werden wir für MQL4 das zweite Mal * 1000 verwenden, um es in das Millisekundenformat zu konvertieren.
Wir werden das Array der Struktur für die Daten der Markttiefe später benötigen, wenn wir den Inhalt der Markttiefe erhalten (nicht in diesem Artikel).
Ein globaler Fehlercode — es kann Fälle geben, in denen ein bibliotheksbasiertes Programm aufgrund einer fehlerhaften Ausführung einer Methode oder Funktion nicht weiterarbeiten kann. Das Programm sollte über die Fehlerausführung einer Methode oder Funktion informiert werden, damit es in der Lage ist, die Situation rechtzeitig richtig zu handhaben. Für diese Fälle wurden die Variable eingeführt. Sie soll einen Fehlercode enthalten, während das Basisobjekt der Bibliothek CEngine den Fehlercode überwacht. Enthält der Code einen Wert ungleich Null, wird er zunächst in der Klasse CEngine behandelt. Falls es nicht möglich ist, das Problem mit internen Mitteln zu "lösen", wird der Code an das aufrufende Programm für eine rechtzeitige Reaktion gesendet.
Vor der Erstellung eines Symbolobjekts sollten alle seine Felder und Strukturen zurückgesetzt werden. Dafür wird die Methode Reset() verwendet.

Füllen Sie im Konstruktor der geschützten Klasse alle Symboleigenschaften mit den Standardfunktionen aus. Allerdings sind nicht alle Funktionen für MQL4 geeignet, daher sollten wir die notwendigen Methoden zum Erhalten von Daten in der geschützten Klassensektion für die Fälle erstellen, in denen die Trennung der für MQL5 und MQL4 erhaltenen Daten eingeführt werden sollte:

protected:
//--- 'Protected' Konstruktor
                     CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name);

//--- Get and return integer properties of a selected symbol from its parameters
   long              SymbolExists(void)                  const;
   long              SymbolCustom(void)                  const;
   long              SymbolChartMode(void)               const;
   long              SymbolMarginHedgedUseLEG(void)      const;
   long              SymbolOrderFillingMode(void)        const;
   long              SymbolOrderMode(void)               const;
   long              SymbolOrderGTCMode(void)            const;
   long              SymbolOptionMode(void)              const;
   long              SymbolOptionRight(void)             const;
   long              SymbolBackgroundColor(void)         const;
   long              SymbolCalcMode(void)                const;
   long              SymbolSwapMode(void)                const;
   long              SymbolExpirationMode(void)          const;
   long              SymbolDigitsLot(void);
//--- Get and return real properties of a selected symbol from its parameters
   double            SymbolBidHigh(void)                 const;
   double            SymbolBidLow(void)                  const;
   double            SymbolVolumeReal(void)              const;
   double            SymbolVolumeHighReal(void)          const;
   double            SymbolVolumeLowReal(void)           const;
   double            SymbolOptionStrike(void)            const;
   double            SymbolTradeAccruedInterest(void)    const;
   double            SymbolTradeFaceValue(void)          const;
   double            SymbolTradeLiquidityRate(void)      const;
   double            SymbolMarginHedged(void)            const;
//--- Get and return string properties of a selected symbol from its parameters
   string            SymbolBasis(void)                   const;
   string            SymbolBank(void)                    const;
   string            SymbolISIN(void)                    const;
   string            SymbolFormula(void)                 const;
   string            SymbolPage(void)                    const;
//--- Return the number of decimal places of the account currency
   int               DigitsCurrency(void)                const { return this.m_digits_currency; }
//--- Search for a symbol and return the flag indicating its presence on the server
   bool              Exist(void)                         const;

public:

Deklarieren Sie im Abschnitt 'public' der Klasse die Methoden Rückgabe der Zustände verschiedener Flags, die zulässige Modi einiger Symboleigenschaften beschreiben, sowie String-Beschreibungen dieser Modi:

public:
//--- Set (1) integer, (2) real and (3) string symbol properties
   void              SetProperty(ENUM_SYMBOL_PROP_INTEGER property,long value)   { this.m_long_prop[property]=value;                                        }
   void              SetProperty(ENUM_SYMBOL_PROP_DOUBLE property,double value)  { this.m_double_prop[this.IndexProp(property)]=value;                      }
   void              SetProperty(ENUM_SYMBOL_PROP_STRING property,string value)  { this.m_string_prop[this.IndexProp(property)]=value;                      }
//--- Return (1) integer, (2) real and (3) string symbol properties from the properties array
   long              GetProperty(ENUM_SYMBOL_PROP_INTEGER property)        const { return this.m_long_prop[property];                                       }
   double            GetProperty(ENUM_SYMBOL_PROP_DOUBLE property)         const { return this.m_double_prop[this.IndexProp(property)];                     }
   string            GetProperty(ENUM_SYMBOL_PROP_STRING property)         const { return this.m_string_prop[this.IndexProp(property)];                     }

//--- Return the flag of a symbol supporting the property
   virtual bool      SupportProperty(ENUM_SYMBOL_PROP_INTEGER property)    { return true; }
   virtual bool      SupportProperty(ENUM_SYMBOL_PROP_DOUBLE property)     { return true; }
   virtual bool      SupportProperty(ENUM_SYMBOL_PROP_STRING property)     { return true; }

//--- Return the flag of allowing (1) market, (2) limit, (3) stop (4) and stop limit orders,
//--- the flag of allowing setting (5) StopLoss and (6) TakeProfit orders, (7) as well as closing by an opposite order
   bool              IsMarketOrdersAllowed(void)            const { return((this.OrderModeFlags() & SYMBOL_ORDER_MARKET)==SYMBOL_ORDER_MARKET);             }
   bool              IsLimitOrdersAllowed(void)             const { return((this.OrderModeFlags() & SYMBOL_ORDER_LIMIT)==SYMBOL_ORDER_LIMIT);               }
   bool              IsStopOrdersAllowed(void)              const { return((this.OrderModeFlags() & SYMBOL_ORDER_STOP)==SYMBOL_ORDER_STOP);                 }
   bool              IsStopLimitOrdersAllowed(void)         const { return((this.OrderModeFlags() & SYMBOL_ORDER_STOP_LIMIT)==SYMBOL_ORDER_STOP_LIMIT);     }
   bool              IsStopLossOrdersAllowed(void)          const { return((this.OrderModeFlags() & SYMBOL_ORDER_SL)==SYMBOL_ORDER_SL);                     }
   bool              IsTakeProfitOrdersAllowed(void)        const { return((this.OrderModeFlags() & SYMBOL_ORDER_TP)==SYMBOL_ORDER_TP);                     }
   bool              IsCloseByOrdersAllowed(void)           const;

//--- Return the (1) FOK and (2) IOC filling flag
   bool              IsFillingModeFOK(void)                 const { return((this.FillingModeFlags() & SYMBOL_FILLING_FOK)==SYMBOL_FILLING_FOK);             }
   bool              IsFillingModeIOC(void)                 const { return((this.FillingModeFlags() & SYMBOL_FILLING_IOC)==SYMBOL_FILLING_IOC);             }

//--- Return the flag of order expiration: (1) GTC, (2) DAY, (3) Specified and (4) Specified Day
   bool              IsExipirationModeGTC(void)             const { return((this.ExpirationModeFlags() & SYMBOL_EXPIRATION_GTC)==SYMBOL_EXPIRATION_GTC);    }
   bool              IsExipirationModeDAY(void)             const { return((this.ExpirationModeFlags() & SYMBOL_EXPIRATION_DAY)==SYMBOL_EXPIRATION_DAY);    }
   bool              IsExipirationModeSpecified(void)       const { return((this.ExpirationModeFlags() & SYMBOL_EXPIRATION_SPECIFIED)==SYMBOL_EXPIRATION_SPECIFIED);          }
   bool              IsExipirationModeSpecifiedDay(void)    const { return((this.ExpirationModeFlags() & SYMBOL_EXPIRATION_SPECIFIED_DAY)==SYMBOL_EXPIRATION_SPECIFIED_DAY);  }

//--- Return the description of allowing (1) market, (2) limit, (3) stop and (4) stop limit orders,
//--- the description of allowing (5) StopLoss and (6) TakeProfit orders, (7) as well as closing by an opposite order
   string            GetMarketOrdersAllowedDescription(void)      const;
   string            GetLimitOrdersAllowedDescription(void)       const;
   string            GetStopOrdersAllowedDescription(void)        const;
   string            GetStopLimitOrdersAllowedDescription(void)   const;
   string            GetStopLossOrdersAllowedDescription(void)    const;
   string            GetTakeProfitOrdersAllowedDescription(void)  const;
   string            GetCloseByOrdersAllowedDescription(void)     const;

//--- Return the description of allowing the filling type (1) FOK and (2) IOC, (3) as well as allowed order expiration modes
   string            GetFillingModeFOKAllowedDescrioption(void)   const;
   string            GetFillingModeIOCAllowedDescrioption(void)   const;

//--- Return the description of order expiration: (1) GTC, (2) DAY, (3) Specified and (4) Specified Day
   string            GetExpirationModeGTCDescription(void)        const;
   string            GetExpirationModeDAYDescription(void)        const;
   string            GetExpirationModeSpecifiedDescription(void)  const;
   string            GetExpirationModeSpecDayDescription(void)    const;

//--- 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
   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;
   

Außerdem fügen Sie folgende Elemente dem 'public' Bereich der Klasse hinzu:
das Fehlercodegewinnungsverfahren, das Verfahren zum Erhalten aller Daten durch ein Symbol, das Verfahren zum Aktualisieren von Kursdaten durch ein Symbol, sowie zusätzliche Verfahren zum Addieren/Entfernen eines Symbols aus dem Fenster der Marktübersicht, das Verfahren, das das Flag der Datensynchronisation durch ein Symbol und zurückgibt, die Verfahren zum Abonnieren der Markttiefe und zum Abmelden davon.
Wir werden die Arbeit mit der Markttiefe in den folgenden Artikeln arrangieren.

//--- Return the global error code
   int               GetError(void)                               const { return this.m_global_error;                                                       }
//--- Update all symbol data that can change
   void              Refresh(void);
//--- Update quote data by a symbol
   void              RefreshRates(void);

//--- (1) Add, (2) remove a symbol from the Market Watch window, (3) return the data synchronization flag by a symbol
   bool              SetToMarketWatch(void)                       const { return ::SymbolSelect(this.m_symbol_name,true);                                   }
   bool              RemoveFromMarketWatch(void)                  const { return ::SymbolSelect(this.m_symbol_name,false);                                  }
   bool              IsSynchronized(void)                         const { return ::SymbolIsSynchronized(this.m_symbol_name);                                }
//--- (1) Arrange a (1) subscription to the market depth, (2) close the market depth
   bool              BookAdd(void)                                const;
   bool              BookClose(void)                              const;

Da wir Methoden haben, die jede Eigenschaft nach ihrem Namen (Enumerationskonstante) zurückgeben, können wir bereits Daten über jede der externen Eigenschaften erhalten, aber das ist aus Programmiersicht nicht praktisch, da wir uns alle Konstantennamen aus den Enumerationen der Symbolobjekteigenschaften merken müssen. Deshalb (wie in den vorherigen Klassen und aus dem gleichen Grund) werden wir zusätzliche öffentliche Methoden vorstellen, die alle Eigenschaften des Symbolobjekts zurückgeben, aber mit sprechenden Namen.
Wir ergänzen sie ganz am Ende des Körpers der Klasse:

//+------------------------------------------------------------------+
//| Methods of a simplified access to the order object properties    |
//+------------------------------------------------------------------+
//--- Integer properties
   long              Status(void)                                 const { return this.GetProperty(SYMBOL_PROP_STATUS);                                      }
   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              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);                                   }
   datetime          Time(void)                                   const { return (datetime)this.GetProperty(SYMBOL_PROP_TIME);                              }
   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);                        }
   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            MarginLong(void)                             const { return this.GetProperty(SYMBOL_PROP_MARGIN_LONG);                                 }
   double            MarginShort(void)                            const { return this.GetProperty(SYMBOL_PROP_MARGIN_SHORT);                                }
   double            MarginStop(void)                             const { return this.GetProperty(SYMBOL_PROP_MARGIN_STOP);                                 }
   double            MarginLimit(void)                            const { return this.GetProperty(SYMBOL_PROP_MARGIN_LIMIT);                                }
   double            MarginStopLimit(void)                        const { return this.GetProperty(SYMBOL_PROP_MARGIN_STOPLIMIT);                            }
   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            NormalizedPrice(const double price)          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);                                        }
//---
  };
//+------------------------------------------------------------------+

Die Methoden werden deklariert, und einige von ihnen werden sofort im Klassenkörper implementiert. Lassen Sie uns nun die Implementierung aller deklarierten Methoden hinzufügen und analysieren.

Implementierung des Konstruktors der 'protected' Klasse:

//+------------------------------------------------------------------+
//| Class methods                                                    |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Closed parametric constructor                                    |
//+------------------------------------------------------------------+
CSymbol::CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name) : m_global_error(ERR_SUCCESS)
  {
   this.m_symbol_name=name;
   if(!this.Exist())
     {
      ::Print(DFUN_ERR_LINE,"\"",this.m_symbol_name,"\"",": ",TextByLanguage("Ошибка. Такого символа нет на сервере","Error. No such symbol on server"));
      this.m_global_error=ERR_MARKET_UNKNOWN_SYMBOL;
     }
   ::ResetLastError();
   if(!::SymbolInfoTick(this.m_symbol_name,this.m_tick))
     {
      this.m_global_error=::GetLastError();
      ::Print(DFUN_ERR_LINE,"\"",this.m_symbol_name,"\": ",TextByLanguage("Не удалось получить текущие цены. Ошибка: ","Could not get current prices. Error: "),this.m_global_error);
     }
//--- Data initialization
   ::ZeroMemory(this.m_tick);
   this.Reset();
   this.m_digits_currency=(#ifdef __MQL5__ (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif);
//--- Sichern der ganzzahligen Eigenschaften
   this.m_long_prop[SYMBOL_PROP_STATUS]                                       = symbol_status;
   this.m_long_prop[SYMBOL_PROP_VOLUME]                                       = (long)this.m_tick.volume;
   this.m_long_prop[SYMBOL_PROP_TIME]                                         = #ifdef __MQL5__ this.m_tick.time_msc #else this.m_tick.time*1000 #endif ;
   this.m_long_prop[SYMBOL_PROP_SELECT]                                       = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SELECT);
   this.m_long_prop[SYMBOL_PROP_VISIBLE]                                      = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_VISIBLE);
   this.m_long_prop[SYMBOL_PROP_SESSION_DEALS]                                = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SESSION_DEALS);
   this.m_long_prop[SYMBOL_PROP_SESSION_BUY_ORDERS]                           = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SESSION_BUY_ORDERS);
   this.m_long_prop[SYMBOL_PROP_SESSION_SELL_ORDERS]                          = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SESSION_SELL_ORDERS);
   this.m_long_prop[SYMBOL_PROP_VOLUMEHIGH]                                   = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_VOLUMEHIGH);
   this.m_long_prop[SYMBOL_PROP_VOLUMELOW]                                    = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_VOLUMELOW);
   this.m_long_prop[SYMBOL_PROP_DIGITS]                                       = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_DIGITS);
   this.m_long_prop[SYMBOL_PROP_SPREAD]                                       = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SPREAD);
   this.m_long_prop[SYMBOL_PROP_SPREAD_FLOAT]                                 = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SPREAD_FLOAT);
   this.m_long_prop[SYMBOL_PROP_TICKS_BOOKDEPTH]                              = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TICKS_BOOKDEPTH);
   this.m_long_prop[SYMBOL_PROP_TRADE_MODE]                                   = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_MODE);
   this.m_long_prop[SYMBOL_PROP_START_TIME]                                   = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_START_TIME);
   this.m_long_prop[SYMBOL_PROP_EXPIRATION_TIME]                              = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_EXPIRATION_TIME);
   this.m_long_prop[SYMBOL_PROP_TRADE_STOPS_LEVEL]                            = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_STOPS_LEVEL);
   this.m_long_prop[SYMBOL_PROP_TRADE_FREEZE_LEVEL]                           = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_FREEZE_LEVEL);
   this.m_long_prop[SYMBOL_PROP_TRADE_EXEMODE]                                = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_EXEMODE);
   this.m_long_prop[SYMBOL_PROP_SWAP_ROLLOVER3DAYS]                           = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SWAP_ROLLOVER3DAYS);
   this.m_long_prop[SYMBOL_PROP_EXPIRATION_MODE]                              = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_EXPIRATION_MODE);
   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_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_EXPIRATION_MODE]                              = this.SymbolExpirationMode();
//--- Sichern der Double-Eigenschaften
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKHIGH)]                    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_ASKHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKLOW)]                     = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_ASKLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTHIGH)]                   = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_LASTHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTLOW)]                    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_LASTLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_POINT)]                      = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_POINT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT)]    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE_PROFIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS)]      = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE_LOSS);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_SIZE)]            = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_SIZE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_CONTRACT_SIZE)]        = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_CONTRACT_SIZE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MIN)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_MIN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MAX)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_MAX);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_STEP)]                = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_STEP);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_LIMIT)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_LIMIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_LONG)]                  = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SWAP_LONG);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_SHORT)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SWAP_SHORT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_INITIAL)]             = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_INITIAL);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_MAINTENANCE)]         = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_MAINTENANCE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG)]                = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_LONG);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_SHORT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_STOP)]                = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_STOP);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LIMIT)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_LIMIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_STOPLIMIT)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_STOPLIMIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_VOLUME)]             = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_TURNOVER)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_TURNOVER);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_INTEREST)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_INTEREST);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME)]  = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_BUY_ORDERS_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_SELL_ORDERS_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_OPEN)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_OPEN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_CLOSE)]              = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_CLOSE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_AW)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_AW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT)]   = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_PRICE_SETTLEMENT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN)]    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_PRICE_LIMIT_MIN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX)]    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_PRICE_LIMIT_MAX);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BID)]                        = this.m_tick.bid;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASK)]                        = this.m_tick.ask;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LAST)]                       = this.m_tick.last;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDHIGH)]                    = this.SymbolBidHigh();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDLOW)]                     = this.SymbolBidLow();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_REAL)]                = this.SymbolVolumeReal();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMEHIGH_REAL)]            = this.SymbolVolumeHighReal();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMELOW_REAL)]             = this.SymbolVolumeLowReal();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_OPTION_STRIKE)]              = this.SymbolOptionStrike();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_ACCRUED_INTEREST)]     = this.SymbolTradeAccruedInterest();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_FACE_VALUE)]           = this.SymbolTradeFaceValue();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_LIQUIDITY_RATE)]       = this.SymbolTradeLiquidityRate();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_HEDGED)]              = this.SymbolMarginHedged();
//--- Sichern der String-Eigenschaften
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_NAME)]                       = this.m_symbol_name;
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_BASE)]              = ::SymbolInfoString(this.m_symbol_name,SYMBOL_CURRENCY_BASE);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_PROFIT)]            = ::SymbolInfoString(this.m_symbol_name,SYMBOL_CURRENCY_PROFIT);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_MARGIN)]            = ::SymbolInfoString(this.m_symbol_name,SYMBOL_CURRENCY_MARGIN);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_DESCRIPTION)]                = ::SymbolInfoString(this.m_symbol_name,SYMBOL_DESCRIPTION);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_PATH)]                       = ::SymbolInfoString(this.m_symbol_name,SYMBOL_PATH);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_BASIS)]                      = this.SymbolBasis();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_BANK)]                       = this.SymbolBank();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_ISIN)]                       = this.SymbolISIN();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_FORMULA)]                    = this.SymbolFormula();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_PAGE)]                       = this.SymbolPage();
//--- Sichern weiterer ganzzahliger Eigenschaften
   this.m_long_prop[SYMBOL_PROP_DIGITS_LOTS]                                  = this.SymbolDigitsLot();
  }
//+------------------------------------------------------------------+

Die Argumente des Konstruktors sind Symbolstatus und sein Name. Beim Anlegen der Symbolkollektion bewegen wir uns in einer Schleife über alle benötigten Symbole, die definieren, ob sie zu einer zuvor festgelegten Kategorie gehören (in der Aufzählung ENUM_SYMBOL_STATUS) und erstellen ein neues Objekt, das aus der abstrakten Symbolklasse abgeleitet ist. Nur der Symbolname wird an die abgeleitete Klasse übergeben, während der Status basierend auf dem abgeleiteten Objekttyp automatisch gesetzt und beim Anlegen des abgeleiteten Objekts an den Konstruktor der übergeordneten Klasse gesendet wird. Wir haben das bereits analysiert, als wir die Erstellung von Auftragsobjekten im zweiten Teil der Bibliotheksbeschreibung diskutierten.
Initialisieren Sie den Fehlercode in der Konstruktor-Initialisierungsliste sofort.
Überprüfen Sie im Körper der Methode zunächst , ob ein solches Symbol auf dem Server vorhanden ist. Wenn nicht, senden Sie die Fehlermeldung an das Journal und fügen Sie den Wert "Unbekanntes Symbol" zum Fehlercode hinzu. Diese Prüfung ist in der Tat unnötig, da beim Anlegen Daten zu einem aus der Liste ausgewählten Symbol an das Objekt übergeben werden. Aber ich denke, es sollte vorhanden sein, da ein falsches Symbol an das neu erstellte Objekt übergeben werden kann.
Als nächstes erhalten wir Daten über den letzten Tick. Wenn keine empfangen wurde, senden Sie die entsprechende Nachricht an das Journal und weisen Sie den Wert des letzten Fehlers mit GetLastError() dem Fehlercode zu. Das Objekt wird auf jeden Fall angelegt, während der Fehlercode in einem aufrufenden Programm die Entscheidung ermöglicht, ob es belassen wird oder entfernt werden soll.
Anschließend werden alle Daten des Symbolobjekts initialisiert (zurückgesetzt) und die Anzahl der Nachkommastellen für die Kontowährung für die korrekte Ausgabe der Werte in das Journal eingestellt.
Alle Objekteigenschaften werden mit Hilfe der Funktionen der SymbolInfo eingetragen. In Fällen, in denen es Unterschiede in MQL5 und MQL4 für den Empfang dieser Werte gibt, werden die Daten mit speziell entwickelten Methoden gefüllt, die später beschrieben werden.

Nachfolgend finden Sie die Methode zum Vergleich zweier Symbolobjekte für die Suche und Sortierung:

//+------------------------------------------------------------------+
//|Compare CSymbol objects by all possible properties                |
//+------------------------------------------------------------------+
int CSymbol::Compare(const CObject *node,const int mode=0) const
  {
   const CSymbol *symbol_compared=node;
//--- compare integer properties of two symbols
   if(mode<SYMBOL_PROP_INTEGER_TOTAL)
     {
      long value_compared=symbol_compared.GetProperty((ENUM_SYMBOL_PROP_INTEGER)mode);
      long value_current=this.GetProperty((ENUM_SYMBOL_PROP_INTEGER)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- compare real properties of two symbols
   else if(mode<SYMBOL_PROP_INTEGER_TOTAL+SYMBOL_PROP_DOUBLE_TOTAL)
     {
      double value_compared=symbol_compared.GetProperty((ENUM_SYMBOL_PROP_DOUBLE)mode);
      double value_current=this.GetProperty((ENUM_SYMBOL_PROP_DOUBLE)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- compare string properties of two symbols
   else if(mode<SYMBOL_PROP_INTEGER_TOTAL+SYMBOL_PROP_DOUBLE_TOTAL+SYMBOL_PROP_STRING_TOTAL)
     {
      string value_compared=symbol_compared.GetProperty((ENUM_SYMBOL_PROP_STRING)mode);
      string value_current=this.GetProperty((ENUM_SYMBOL_PROP_STRING)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
   return 0;
  }
//+------------------------------------------------------------------+

Nachfolgend finden Sie das Verfahren zum Vergleichen zweier Symbolobjekte, um zu definieren, ob sie gleich sind:

//+------------------------------------------------------------------+
//| Compare CSymbol objects by all properties                        |
//+------------------------------------------------------------------+
bool CSymbol::IsEqual(CSymbol *compared_symbol) const
  {
   int beg=0, end=SYMBOL_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_INTEGER prop=(ENUM_SYMBOL_PROP_INTEGER)i;
      if(this.GetProperty(prop)!=compared_symbol.GetProperty(prop)) return false; 
     }
   beg=end; end+=SYMBOL_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_DOUBLE prop=(ENUM_SYMBOL_PROP_DOUBLE)i;
      if(this.GetProperty(prop)!=compared_symbol.GetProperty(prop)) return false; 
     }
   beg=end; end+=SYMBOL_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_STRING prop=(ENUM_SYMBOL_PROP_STRING)i;
      if(this.GetProperty(prop)!=compared_symbol.GetProperty(prop)) return false; 
     }
   return true;
  }
//+------------------------------------------------------------------+

Ich habe beide Methoden bereits im ersten und im fünften Teil der Bibliotheksbeschreibung besprochen.

Nachfolgend finden Sie die Methode zur Initialisierung aller Symbolobjekteigenschaften:

//+------------------------------------------------------------------+
//| Reset all symbol object data                                     |
//+------------------------------------------------------------------+
void CSymbol::Reset(void)
  {
   int beg=0, end=SYMBOL_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_INTEGER prop=(ENUM_SYMBOL_PROP_INTEGER)i;
      this.SetProperty(prop,0);
     }
   beg=end; end+=SYMBOL_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_DOUBLE prop=(ENUM_SYMBOL_PROP_DOUBLE)i;
      this.SetProperty(prop,0);
     }
   beg=end; end+=SYMBOL_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_STRING prop=(ENUM_SYMBOL_PROP_STRING)i;
      this.SetProperty(prop,NULL);
     }
  }
//+------------------------------------------------------------------+

Die Methode funktioniert identisch mit den vorherigen, aber anstatt mit dem Musterobjekt zu vergleichen, werden hier alle Klassenfelder in einer Schleife für jeden der drei Eigenschaftssätze zurückgesetzt.

Nachfolgend finden Sie die Methoden zum Empfangen der Integer-Eigenschaften des Symbols, die in MQL4 entweder ganz oder teilweise fehlen:

//+----------------------------------------------------------------------+
//| Integer properties                                                   |
//+----------------------------------------------------------------------+
//+----------------------------------------------------------------------+
//| Return the symbol existence flag                                     |
//+----------------------------------------------------------------------+
long CSymbol::SymbolExists(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_EXIST) #else this.Exist() #endif);
  }
//+----------------------------------------------------------------------+
//| Return the custom symbol flag                                        |
//+----------------------------------------------------------------------+
long CSymbol::SymbolCustom(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_CUSTOM) #else false #endif);
  }
//+----------------------------------------------------------------------+
//| Return the price type for building bars - Bid or Last                |
//+----------------------------------------------------------------------+
long CSymbol::SymbolChartMode(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_CHART_MODE) #else SYMBOL_CHART_MODE_BID #endif);
  }
//+----------------------------------------------------------------------+
//|Return the calculation mode of a hedging margin using the larger leg  |
//+----------------------------------------------------------------------+
long CSymbol::SymbolMarginHedgedUseLEG(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_MARGIN_HEDGED_USE_LEG) #else false #endif);
  }
//+----------------------------------------------------------------------+
//| Return the order filling policies flags                              |
//+----------------------------------------------------------------------+
long CSymbol::SymbolOrderFillingMode(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_FILLING_MODE) #else 0 #endif );
  }
//+----------------------------------------------------------------------+
//| Return the flag allowing the closure by an opposite position         |
//+----------------------------------------------------------------------+
bool CSymbol::IsCloseByOrdersAllowed(void) const
  {
   return(#ifdef __MQL5__(this.OrderModeFlags() & SYMBOL_ORDER_CLOSEBY)==SYMBOL_ORDER_CLOSEBY #else (bool)::MarketInfo(this.m_symbol_name,MODE_CLOSEBY_ALLOWED)  #endif );
  }  
//+----------------------------------------------------------------------+
//| Return the lifetime of pending orders and                            |
//| placed StopLoss/TakeProfit levels                                    |
//+----------------------------------------------------------------------+
long CSymbol::SymbolOrderGTCMode(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_ORDER_GTC_MODE) #else SYMBOL_ORDERS_GTC #endif);
  }
//+----------------------------------------------------------------------+
//| Return the option type                                               |
//+----------------------------------------------------------------------+
long CSymbol::SymbolOptionMode(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_OPTION_MODE) #else SYMBOL_OPTION_MODE_NONE #endif);
  }
//+----------------------------------------------------------------------+
//| Return the option right                                              |
//+----------------------------------------------------------------------+
long CSymbol::SymbolOptionRight(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_OPTION_RIGHT) #else SYMBOL_OPTION_RIGHT_NONE #endif);
  }
//+----------------------------------------------------------------------+
//|Return the background color used to highlight a symbol in Market Watch|
//+----------------------------------------------------------------------+
long CSymbol::SymbolBackgroundColor(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_BACKGROUND_COLOR) #else clrNONE #endif);
  }
//+----------------------------------------------------------------------+
//| Return the margin calculation method                                 |
//+----------------------------------------------------------------------+
long CSymbol::SymbolCalcMode(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_CALC_MODE) #else (long)::MarketInfo(this.m_symbol_name,MODE_MARGINCALCMODE) #endif);
  }
//+----------------------------------------------------------------------+
//| Return the swaps calculation method                                  |
//+----------------------------------------------------------------------+
long CSymbol::SymbolSwapMode(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SWAP_MODE) #else (long)::MarketInfo(this.m_symbol_name,MODE_SWAPTYPE) #endif);
  }
//+----------------------------------------------------------------------+
//| Return the flags of allowed order expiration modes                   |
//+----------------------------------------------------------------------+
long CSymbol::SymbolExpirationMode(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_EXPIRATION_MODE) #else (long)SYMBOL_EXPIRATION_GTC #endif);
  }
//+----------------------------------------------------------------------+

Hier verwenden wir die bedingten Kompilierungsdirektiven #ifdef __MQL5__ — zum Kompilieren für MQL5 und #else— zum Kompilieren für MQL4 #endif.

Für MQL5 erhalten wir einfach Daten aus der Funktion SymbolInfoInteger() mit der erforderlichen Property-ID, während wir für MQL4 entweder einen strikt gesetzten Wert (wenn wir wissen, dass dieser genaue Wert in MQL4 verwendet wird) oder Null (oder 'falsch', oder eine eingestellte Makroersetzung für den fehlenden Wert) zurückgeben.

Platzieren Sie die Codes von zwei weiteren Methoden in derselben Liste:

Nachfolgend finden Sie die Methode, die die Flags der zulässigen Auftragsarten für ein Symbol zurückgibt:

//+------------------------------------------------------------------+
//| Return the flags of allowed order types                          |
//+------------------------------------------------------------------+
long CSymbol::SymbolOrderMode(void) const
  {
   return
     (
      #ifdef __MQL5__
         ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_ORDER_MODE)
      #else 
         (SYMBOL_ORDER_MARKET+SYMBOL_ORDER_LIMIT+SYMBOL_ORDER_STOP+SYMBOL_ORDER_SL+SYMBOL_ORDER_TP+(this.IsCloseByOrdersAllowed() ? SYMBOL_ORDER_CLOSEBY : 0))
      #endif 
     );
  }
//+------------------------------------------------------------------+

Da MQL5 die Möglichkeit bietet, für jedes der Symbole Flags (die die Möglichkeit der Platzierung verschiedener Ordertypen anzeigen) zu empfangen:

Für MQL5 müssen wir die Flags von der Funktion SymbolInfoInteger() mit der Funktion SYMBOL_ORDER_MODE Eigenschafts-ID beziehen, die alle für ein Symbol gesetzten Flags zurückgibt.

In MQL4 können wir nur Daten über die Berechtigung zum Schließen in entgegengesetzter Reihenfolge aus der Funktion MarketInfo() mit der Anforderungs-ID MODE_CLOSEBY_ALLOWED erhalten (zurückgegeben von der Methode IsCloseByOrdersAllowed() in der obigen Auflistung).
Daher müssen wir die benötigten Flags abfragen und sie an das einem MQL4-Programm zurückgeben:

Nachfolgend finden Sie das Verfahren zum Erhalten der Anzahl der Dezimalstellen der Losgröße eines Symbols:

//+------------------------------------------------------------------+
//| Calculate and return the number of decimal places                |
//| in a symbol lot                                                  |
//+------------------------------------------------------------------+
long CSymbol::SymbolDigitsLot(void)
  {
   if(this.LotsMax()==0 || this.LotsMin()==0 || this.LotsStep()==0)
     {
      ::Print(DFUN_ERR_LINE,TextByLanguage("Не удалось получить данные \"","Failed to get data of \""),this.Name(),"\"");
      this.m_global_error=ERR_MARKET_UNKNOWN_SYMBOL;
      return 2;
     }
   double val=::round(this.LotsMin()/this.LotsStep())*this.LotsStep();
   string val_str=(string)val;
   int len=::StringLen(val_str);
   int n=len-::StringFind(val_str,".",0)-1;
   if(::StringSubstr(val_str,len-1,1)=="0")
      n--;
   return n;
  }
//+------------------------------------------------------------------+

Das Verfahren berechnet die Anzahl der Dezimalstellen der Losgröße eines Symbols.
Wir haben eine solche Funktion bereits in der Datei DELib.mqh mit den Dienstfunktionen:

//+------------------------------------------------------------------+
//| Returns the number of decimal places in a symbol lot             |
//+------------------------------------------------------------------+
uint DigitsLots(const string symbol_name) 
  { 
   return (int)ceil(fabs(log(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))/log(10)));
  }
//+------------------------------------------------------------------+

Sie hat jedoch gewisse Mängel. Ich wurde in einem der Artikel-Diskussionen darüber informiert: Wenn die Schrittweite einer Losgröße 0,25 beträgt, gibt die Funktion keinen korrekten Wert zurück. Also entschied ich mich, nach einer genaueren Methode zu suchen und entschied mich schließlich dafür, dass die genaueste Methode darin besteht, einfach die Anzahl der Dezimalstellen über die Zeichenkette des auf die Schrittweite reduzierte Losgröße zu berechnen: lots=MathRound(lots/lotStep)*lotStep. Diese Entscheidung wurde durch die Diskussion in dem diesem Thema gewidmeten Thread (auf Russisch) ausgelöst, in dem eine bestimmte Suchmethode vorgeschlagen wurde, die eine Suche in einer Zeichenkette ist. Aber wir müssen eine notwendige Anzahl von Dezimalstellen nur einmal für jedes der verwendeten Symbole finden, während danach ein konstanter Wert verwendet wird. Diese Methode hat keine Nachteile gegenüber allen Berechnungsmethoden. Also, verwenden wir die vorgeschlagene Lösung.

Nachfolgend finden Sie die Methoden zum Erhalt der Real- und String-Eigenschaften der Symbole, die in MQL4 entweder ganz oder teilweise fehlen:

//+------------------------------------------------------------------+
//| Real properties                                                  |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Return maximum Bid for a day                                     |
//+------------------------------------------------------------------+
double CSymbol::SymbolBidHigh(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_BIDHIGH) #else ::MarketInfo(this.m_symbol_name,MODE_HIGH) #endif);
  }
//+------------------------------------------------------------------+
//| Return minimum Bid for a day                                     |
//+------------------------------------------------------------------+
double CSymbol::SymbolBidLow(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_BIDLOW) #else ::MarketInfo(this.m_symbol_name,MODE_LOW) #endif);
  }
//+------------------------------------------------------------------+
//| Return real Volume for a day                                     |
//+------------------------------------------------------------------+
double CSymbol::SymbolVolumeReal(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_REAL) #else 0 #endif);
  }
//+------------------------------------------------------------------+
//| Return real maximum Volume for a day                             |
//+------------------------------------------------------------------+
double CSymbol::SymbolVolumeHighReal(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUMEHIGH_REAL) #else 0 #endif);
  }
//+------------------------------------------------------------------+
//| Return real minimum Volume for a day                             |
//+------------------------------------------------------------------+
double CSymbol::SymbolVolumeLowReal(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUMELOW_REAL) #else 0 #endif);
  }
//+------------------------------------------------------------------+
//| Return an option execution price                                 |
//+------------------------------------------------------------------+
double CSymbol::SymbolOptionStrike(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_OPTION_STRIKE) #else 0 #endif);
  }
//+------------------------------------------------------------------+
//| Return accrued interest                                          |
//+------------------------------------------------------------------+
double CSymbol::SymbolTradeAccruedInterest(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_ACCRUED_INTEREST) #else 0 #endif);
  }
//+------------------------------------------------------------------+
//| Return a bond face value                                         |
//+------------------------------------------------------------------+
double CSymbol::SymbolTradeFaceValue(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_FACE_VALUE) #else 0 #endif);
  }
//+------------------------------------------------------------------+
//| Return a liquidity rate                                          |
//+------------------------------------------------------------------+
double CSymbol::SymbolTradeLiquidityRate(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_LIQUIDITY_RATE) #else 0 #endif);
  }
//+------------------------------------------------------------------+
//| Return a contract or margin size                                 |
//| for a single lot of covered positions                            |
//+------------------------------------------------------------------+
double CSymbol::SymbolMarginHedged(void) const
  {
   return(#ifdef __MQL5__ ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_HEDGED) #else ::MarketInfo(this.m_symbol_name, MODE_MARGINHEDGED) #endif);
  }
//+------------------------------------------------------------------+
//| String properties                                                |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Return a base asset name for a derivative instrument             |
//+------------------------------------------------------------------+
string CSymbol::SymbolBasis(void) const
  {
   return
     (
      #ifdef __MQL5__ 
         ::SymbolInfoString(this.m_symbol_name,SYMBOL_BASIS) 
      #else 
         ": "+TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") 
      #endif
     );
  }
//+------------------------------------------------------------------+
//| Return a quote source for a symbol                               |
//+------------------------------------------------------------------+
string CSymbol::SymbolBank(void) const
  {
   return
     (
      #ifdef __MQL5__ 
         ::SymbolInfoString(this.m_symbol_name,SYMBOL_BANK) 
      #else 
         ": "+TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") 
      #endif
     );
  }
//+------------------------------------------------------------------+
//| Return a symbol name to ISIN                                     |
//+------------------------------------------------------------------+
string CSymbol::SymbolISIN(void) const
  {
   return
     (
      #ifdef __MQL5__ 
         ::SymbolInfoString(this.m_symbol_name,SYMBOL_ISIN) 
      #else 
         ": "+TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") 
      #endif
     );
  }
  
//+------------------------------------------------------------------+
//| Return a formula for constructing a custom symbol price          |
//+------------------------------------------------------------------+
string CSymbol::SymbolFormula(void) const
  {
   return
     (
      #ifdef __MQL5__ 
         ::SymbolInfoString(this.m_symbol_name,SYMBOL_FORMULA) 
      #else 
         ": "+TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") 
      #endif
     );
  }
//+------------------------------------------------------------------+
//| Return an address of a web page with a symbol data               |
//+------------------------------------------------------------------+
string CSymbol::SymbolPage(void) const
  {
   return
     (
      #ifdef __MQL5__ 
         ::SymbolInfoString(this.m_symbol_name,SYMBOL_PAGE) 
      #else 
         ": "+TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") 
      #endif
     );
  }
//+------------------------------------------------------------------+

Hier ist alles ähnlich wie bei den Methoden zum Erhalten der Integer-Eigenschaften: Der erhaltene Wert wird durch die Direktiven zur bedingten Kompilierung dividiert, und die Eigenschaftswerte werden entweder mit den entsprechenden MQL5 und MQL4 Funktionen zurückgegeben, oder für MQL4 wird 0 zurückgegeben (wenn es kein MQL5 Analogon gibt). Die Zeichenkettenmeldung, dass MQL4 diese Zeichenketteneigenschaft nicht unterstützt, kann ebenfalls zurückgegeben werden.

Nachfolgend finden Sie die Methode zum Senden der vollständigen Liste aller Symbolobjekteigenschaften an das Journal:

//+------------------------------------------------------------------+
//| Send symbol properties to the journal                            |
//+------------------------------------------------------------------+
void CSymbol::Print(const bool full_prop=false)
  {
   ::Print("============= ",
           TextByLanguage("Начало списка параметров: \"","Beginning of the parameter list: \""),
           this.Name(),"\""," ",(this.Description()!= #ifdef __MQL5__ "" #else NULL #endif  ? "("+this.Description()+")" : ""),
           " =================="
          );
   int beg=0, end=SYMBOL_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_INTEGER prop=(ENUM_SYMBOL_PROP_INTEGER)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=SYMBOL_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_DOUBLE prop=(ENUM_SYMBOL_PROP_DOUBLE)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=SYMBOL_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_SYMBOL_PROP_STRING prop=(ENUM_SYMBOL_PROP_STRING)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("================== ",
           TextByLanguage("Конец списка параметров: ","End of the parameter list: \""),
           this.Name(),"\""," ",(this.Description()!= #ifdef __MQL5__ "" #else NULL #endif  ? "("+this.Description()+")" : ""),
           " ==================\n"
          );
  }
//+------------------------------------------------------------------+

Die Beschreibung jeder nachfolgenden Eigenschaft wird in drei Schleifen für alle Objekteigenschaften mit den Methoden GetPropertyDescription() angezeigt, die eine Objekteigenschaftsbeschreibung (die an die Methode übergeben wird) über ihren Typ ( integer, real oder string) zurückgeben:

//+------------------------------------------------------------------+
//| Return the description of the symbol integer property            |
//+------------------------------------------------------------------+
string CSymbol::GetPropertyDescription(ENUM_SYMBOL_PROP_INTEGER property)
  {
   return
     (
   //--- Allgemeine Eigenschaften
      property==SYMBOL_PROP_STATUS              ?  TextByLanguage("Статус","Status")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(string)this.GetStatusDescription()
         )  :
      property==SYMBOL_PROP_CUSTOM              ?  TextByLanguage("Пользовательский символ","Custom symbol")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)   ?  TextByLanguage("Да","Yes") : TextByLanguage("Нет","No"))
         )  :
      property==SYMBOL_PROP_CHART_MODE          ?  TextByLanguage("Тип цены для построения баров","Price type used for generating symbols bars")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetChartModeDescription()
         )  :
      property==SYMBOL_PROP_EXIST               ?  TextByLanguage("Символ с таким именем существует","Symbol with this name exists")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)   ?  TextByLanguage("Да","Yes") : TextByLanguage("Нет","No"))
         )  :
      property==SYMBOL_PROP_SELECT  ?  TextByLanguage("Символ выбран в Market Watch","Symbol selected in Market Watch")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)   ?  TextByLanguage("Да","Yes") : TextByLanguage("Нет","No"))
         )  :
      property==SYMBOL_PROP_VISIBLE ?  TextByLanguage("Символ отображается в Market Watch","Symbol visible in Market Watch")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)   ?  TextByLanguage("Да","Yes") : TextByLanguage("Нет","No"))
         )  :
      property==SYMBOL_PROP_SESSION_DEALS       ?  TextByLanguage("Количество сделок в текущей сессии","Number of deals in the current session")+
         (!this.SupportProperty(property)    ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else TextByLanguage("Свойство не поддерживается в MQL4","Property is not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_BUY_ORDERS  ?  TextByLanguage("Общее число ордеров на покупку в текущий момент","Number of Buy orders at the moment")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property is not support") :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_SELL_ORDERS ?  TextByLanguage("Общее число ордеров на продажу в текущий момент","Number of Sell orders at the moment")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_VOLUME              ?  TextByLanguage("Объем в последней сделке","Volume of the last deal")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_VOLUMEHIGH          ?  TextByLanguage("Максимальный объём за день","Maximum day volume")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property is not support") :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else TextByLanguage("Свойство не поддерживается в MQL4","Property is not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_VOLUMELOW           ?  TextByLanguage("Минимальный объём за день","Minimum day volume")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_TIME                ?  TextByLanguage("Время последней котировки","Time of last quote")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)==0 ? TextByLanguage("(Ещё не было тиков)","(No ticks yet)") : TimeMSCtoString(this.GetProperty(property)))
         )  :
      property==SYMBOL_PROP_DIGITS              ?  TextByLanguage("Количество знаков после запятой","Digits after decimal point")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_DIGITS_LOTS         ?  TextByLanguage("Количество знаков после запятой в значении лота","Digits after decimal point in lot value")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_SPREAD              ?  TextByLanguage("Размер спреда в пунктах","Spread value in points")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_SPREAD_FLOAT        ?  TextByLanguage("Плавающий спред","Floating spread")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)   ?  TextByLanguage("Да","Yes") : TextByLanguage("Нет","No"))
         )  :
      property==SYMBOL_PROP_TICKS_BOOKDEPTH     ?  TextByLanguage("Максимальное количество показываемых заявок в стакане","Maximum number of requests shown in Depth of Market")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__(string)this.GetProperty(property) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_TRADE_CALC_MODE     ?  TextByLanguage("Способ вычисления стоимости контракта","Contract price calculation mode")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetCalcModeDescription()
         )  :
      property==SYMBOL_PROP_TRADE_MODE ?  TextByLanguage("Тип исполнения ордеров","Order execution type")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetTradeModeDescription()
         )  :
      property==SYMBOL_PROP_START_TIME          ?  TextByLanguage("Дата начала торгов по инструменту","Date of symbol trade beginning")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)==0  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": "+TimeMSCtoString(this.GetProperty(property)*1000))
         )  :
      property==SYMBOL_PROP_EXPIRATION_TIME     ?  TextByLanguage("Дата окончания торгов по инструменту","Date of symbol trade end")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)==0  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": "+TimeMSCtoString(this.GetProperty(property)*1000))
         )  :
      property==SYMBOL_PROP_TRADE_STOPS_LEVEL   ?  TextByLanguage("Минимальный отступ от цены закрытия для установки Stop ордеров","Minimum indention from close price to place Stop orders")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_TRADE_FREEZE_LEVEL  ?  TextByLanguage("Дистанция заморозки торговых операций","Distance to freeze trade operations in points")+
         (!this.SupportProperty(property)    ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(string)this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_TRADE_EXEMODE       ?  TextByLanguage("Режим заключения сделок","Deal execution mode")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetTradeExecDescription()
         )  :
      property==SYMBOL_PROP_SWAP_MODE           ?  TextByLanguage("Модель расчета свопа","Swap calculation model")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetSwapModeDescription()
         )  :
      property==SYMBOL_PROP_SWAP_ROLLOVER3DAYS  ?  TextByLanguage("День недели для начисления тройного свопа","Day of week to charge 3 days swap rollover")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+DayOfWeekDescription(this.SwapRollover3Days())
         )  :
      property==SYMBOL_PROP_MARGIN_HEDGED_USE_LEG  ?  TextByLanguage("Расчет хеджированной маржи по наибольшей стороне","Calculating hedging margin using larger leg")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)   ?  TextByLanguage("Да","Yes") : TextByLanguage("Нет","No"))
         )  :
      property==SYMBOL_PROP_EXPIRATION_MODE     ?  TextByLanguage("Флаги разрешенных режимов истечения ордера","Flags of allowed order expiration modes")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetExpirationModeFlagsDescription()
         )  :
      property==SYMBOL_PROP_FILLING_MODE        ?  TextByLanguage("Флаги разрешенных режимов заливки ордера","Flags of allowed order filling modes")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetFillingModeFlagsDescription()
         )  :
      property==SYMBOL_PROP_ORDER_MODE          ?  TextByLanguage("Флаги разрешенных типов ордера","Flags of allowed order types")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetOrderModeFlagsDescription()
         )  :
      property==SYMBOL_PROP_ORDER_GTC_MODE      ?  TextByLanguage("Срок действия StopLoss и TakeProfit ордеров","Expiration of Stop Loss and Take Profit orders")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetOrderGTCModeDescription()
         )  :
      property==SYMBOL_PROP_OPTION_MODE         ?  TextByLanguage("Тип опциона","Option type")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetOptionTypeDescription()
         )  :
      property==SYMBOL_PROP_OPTION_RIGHT        ?  TextByLanguage("Право опциона","Option right")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetOptionRightDescription()
         )  :
      property==SYMBOL_PROP_BACKGROUND_COLOR    ?  TextByLanguage("Цвет фона символа в Market Watch","Background color of symbol in Market Watch")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         #ifdef __MQL5__
         (this.GetProperty(property)>clrWhite  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": "+::ColorToString((color)this.GetProperty(property),true))
         #else TextByLanguage(": Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the description of the symbol real property               |
//+------------------------------------------------------------------+
string CSymbol::GetPropertyDescription(ENUM_SYMBOL_PROP_DOUBLE property)
  {
   int dg=this.Digits();
   int dgl=this.DigitsLot();
   int dgc=this.DigitsCurrency();
   return
     (
      property==SYMBOL_PROP_BID              ?  TextByLanguage("Цена Bid","Bid price")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)==0 ? TextByLanguage("(Ещё не было тиков)","(No ticks yet)") : ::DoubleToString(this.GetProperty(property),dg))
         )  :
      property==SYMBOL_PROP_BIDHIGH          ?  TextByLanguage("Максимальный Bid за день","Maximum Bid for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_BIDLOW           ?  TextByLanguage("Минимальный Bid за день","Minimum Bid for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_ASK              ?  TextByLanguage("Цена Ask","Ask price")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+(this.GetProperty(property)==0 ? TextByLanguage("(Ещё не было тиков)","(No ticks yet)") : ::DoubleToString(this.GetProperty(property),dg))
         )  :
      property==SYMBOL_PROP_ASKHIGH          ?  TextByLanguage("Максимальный Ask за день","Maximum Ask for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_ASKLOW           ?  TextByLanguage("Минимальный Ask за день","Minimum Ask for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_LAST             ?  TextByLanguage("Цена последней сделки","Price of the last deal")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_LASTHIGH         ?  TextByLanguage("Максимальный Last за день","Maximum Last for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_LASTLOW          ?  TextByLanguage("Минимальный Last за день","Minimum Last for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_VOLUME_REAL      ?  TextByLanguage("Реальный объём за день","Real volume of the last deal")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_VOLUMEHIGH_REAL  ?  TextByLanguage("Максимальный реальный объём за день","Maximum real volume for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_VOLUMELOW_REAL   ?  TextByLanguage("Минимальный реальный объём за день","Minimum real volume for the day")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_OPTION_STRIKE    ?  TextByLanguage("Цена исполнения опциона","Option strike price")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_POINT            ?  TextByLanguage("Значение одного пункта","Symbol point value")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_TRADE_TICK_VALUE ?  TextByLanguage("Рассчитанная стоимость тика для позиции","Calculated tick price for position")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :
      property==SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT   ?  TextByLanguage("Рассчитанная стоимость тика для прибыльной позиции","Calculated tick price for profitable position")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_TRADE_TICK_VALUE_LOSS  ?  TextByLanguage("Рассчитанная стоимость тика для убыточной позиции","Calculated tick price for losing position")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_TRADE_TICK_SIZE  ?  TextByLanguage("Минимальное изменение цены","Minimum price change")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==SYMBOL_PROP_TRADE_CONTRACT_SIZE ?  TextByLanguage("Размер торгового контракта","Trade contract size")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :
      property==SYMBOL_PROP_TRADE_ACCRUED_INTEREST ?  TextByLanguage("Накопленный купонный доход","Accumulated coupon interest")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_TRADE_FACE_VALUE ?  TextByLanguage("Начальная стоимость облигации, установленная эмитентом","Initial bond value set by issuer")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_TRADE_LIQUIDITY_RATE   ?  TextByLanguage("Коэффициент ликвидности","Liquidity rate")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),2) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_VOLUME_MIN       ?  TextByLanguage("Минимальный объем для заключения сделки","Minimum volume for a deal")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgl)
         )  :
      property==SYMBOL_PROP_VOLUME_MAX       ?  TextByLanguage("Максимальный объем для заключения сделки","Maximum volume for a deal")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgl)
         )  :
      property==SYMBOL_PROP_VOLUME_STEP      ?  TextByLanguage("Минимальный шаг изменения объема для заключения сделки","Minimum volume change step for deal execution")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgl)
         )  :
      property==SYMBOL_PROP_VOLUME_LIMIT     ?  TextByLanguage("Максимально допустимый общий объем позиции и отложенных ордеров в одном направлении","Maximum allowed aggregate volume of open position and pending orders in one direction")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SWAP_LONG        ?  TextByLanguage("Значение свопа на покупку","Long swap value")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :

      property==SYMBOL_PROP_SWAP_SHORT       ?  TextByLanguage("Значение свопа на продажу","Short swap value")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :
      property==SYMBOL_PROP_MARGIN_INITIAL   ?  TextByLanguage("Начальная (инициирующая) маржа","Initial margin")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :
      property==SYMBOL_PROP_MARGIN_MAINTENANCE  ?  TextByLanguage("Поддерживающая маржа по инструменту","Maintenance margin")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :
      property==SYMBOL_PROP_MARGIN_LONG      ?  TextByLanguage("Коэффициент взимания маржи по длинным позициям","Coefficient of margin charging for long positions")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_MARGIN_SHORT     ?  TextByLanguage("Коэффициент взимания маржи по коротким позициям","Coefficient of margin charging for short positions")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_MARGIN_STOP      ?  TextByLanguage("Коэффициент взимания маржи по Stop ордерам","Coefficient of margin charging for Stop orders")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_MARGIN_LIMIT     ?  TextByLanguage("Коэффициент взимания маржи по Limit ордерам","Coefficient of margin charging for Limit orders")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_MARGIN_STOPLIMIT ?  TextByLanguage("Коэффициент взимания маржи по Stop Limit ордерам","Coefficient of margin charging for StopLimit orders")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_VOLUME   ?  TextByLanguage("Cуммарный объём сделок в текущую сессию","Summary volume of the current session deals")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_TURNOVER ?  TextByLanguage("Cуммарный оборот в текущую сессию","Summary turnover of the current session")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgc) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_INTEREST ?  TextByLanguage("Cуммарный объём открытых позиций","Summary open interest")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME ?  TextByLanguage("Общий объём ордеров на покупку в текущий момент","Current volume of Buy orders")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME   ?  TextByLanguage("Общий объём ордеров на продажу в текущий момент","Current volume of Sell orders")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dgl) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_OPEN     ?  TextByLanguage("Цена открытия сессии","Open price of the current session")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_CLOSE    ?  TextByLanguage("Цена закрытия сессии","Close price of the current session")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_AW       ?  TextByLanguage("Средневзвешенная цена сессии","Average weighted price of the current session")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_PRICE_SETTLEMENT  ?  TextByLanguage("Цена поставки на текущую сессию","Settlement price of the current session")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN   ?  TextByLanguage("Минимально допустимое значение цены на сессию","Minimum price of the current session")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX   ?  TextByLanguage("Максимально допустимое значение цены на сессию","Maximum price of the current session")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+ #ifdef __MQL5__::DoubleToString(this.GetProperty(property),dg) #else TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #endif 
         )  :
      property==SYMBOL_PROP_MARGIN_HEDGED    ?  TextByLanguage("Размер контракта или маржи для одного лота перекрытых позиций","Contract size or margin value per one lot of hedged positions")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+::DoubleToString(this.GetProperty(property),dgc)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the description of the symbol string property             |
//+------------------------------------------------------------------+
string CSymbol::GetPropertyDescription(ENUM_SYMBOL_PROP_STRING property)
  {
   return
     (
      property==SYMBOL_PROP_NAME             ?  TextByLanguage("Имя символа","Symbol name")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
          ": "+this.GetProperty(property)
         )  :
      property==SYMBOL_PROP_BASIS            ?  TextByLanguage("Имя базового актива для производного инструмента","Underlying asset of derivative")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_CURRENCY_BASE    ?  TextByLanguage("Базовая валюта инструмента","Basic currency of a symbol")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_CURRENCY_PROFIT  ?  TextByLanguage("Валюта прибыли","Profit currency")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_CURRENCY_MARGIN  ?  TextByLanguage("Валюта залоговых средств","Margin currency")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_BANK             ?  TextByLanguage("Источник текущей котировки","Feeder of the current quote")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_DESCRIPTION      ?  TextByLanguage("Описание символа","Symbol description")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_FORMULA          ?  TextByLanguage("Формула для построения цены пользовательского символа","Formula used for custom symbol pricing")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_ISIN             ?  TextByLanguage("Имя торгового символа в системе международных идентификационных кодов","Name of a symbol in ISIN system")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_PAGE             ?  TextByLanguage("Адрес интернет страницы с информацией по символу","Address of the web page containing symbol information")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      property==SYMBOL_PROP_PATH             ?  TextByLanguage("Путь в дереве символов","Path in symbol tree")+
         (!this.SupportProperty(property) ?  TextByLanguage(": Свойство не поддерживается",": Property not supported") :
         (this.GetProperty(property)=="" || this.GetProperty(property)==NULL  ?  TextByLanguage(": (Отсутствует)",": (Not set)") : ": \""+this.GetProperty(property)+"\"")
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+

Obwohl die Methoden ziemlich sperrig sind, läuft alles darauf hinaus, eine an die Methode übergebene Eigenschaft zu vergleichen und ihre String-Beschreibung zurückzugeben. Ich glaube, sie sind ziemlich leicht zu verstehen, und es hat keinen Sinn, sich mit ihnen zu beschäftigen.

Nachfolgend finden Sie die Methode zum Suchen nach einem Symbol in der Liste der Serversymbole und zum Rückgeben des Flags für dessen An- und Abwesenheit:

//+-------------------------------------------------------------------------------+
//| Search for a symbol and return the flag indicating its presence on the server |
//+-------------------------------------------------------------------------------+
bool CSymbol::Exist(void) const
  {
   int total=::SymbolsTotal(false);
   for(int i=0;i<total;i++)
      if(::SymbolName(i,false)==this.m_symbol_name)
         return true;
   return false;
  }
//+------------------------------------------------------------------+

Vergleichen Sie jedes nachfolgende Symbol (seinen Namen) aus der Liste mit dem Namen des aktuellen Symbolobjekts in einer Schleife durch die vollständige Liste aller Symbole des Servers (in den Funktionen SymbolsTotal() und SymbolName(), Flag = false). Wenn gefunden, geben Sie true zurück — das Symbol ist auf dem Server vorhanden. Andernfalls wird false zurückgegeben — das Symbol gibt es nicht auf dem Server.

Nachfolgend finden Sie die Methoden, um die Markttiefe zu abonnieren und sich von ihr abzumelden:

//+------------------------------------------------------------------+
//| Subscribe to the market depth                                    |
//+------------------------------------------------------------------+
bool CSymbol::BookAdd(void) const
  {
   return #ifdef __MQL5__ ::MarketBookAdd(this.m_symbol_name) #else false #endif ;
  }
//+------------------------------------------------------------------+
//| Close the market depth                                           |
//+------------------------------------------------------------------+
bool CSymbol::BookClose(void) const
  {
   return #ifdef __MQL5__ ::MarketBookRelease(this.m_symbol_name) #else false #endif ;
  }
//+------------------------------------------------------------------+

In MQL5 geben die Methoden einfach das Ergebnis von MarketBookAdd() und MarketBookRelease() Funktionen Operation zurück, während in MQL4, false sofort zurückgegeben wird, da es dort keine Möglichkeit gibt, mit der Markttiefe zu arbeiten. Diese Methoden werden zunächst zu einem Symbolobjekt hinzugefügt. Wir werden die Fähigkeit, sie zu verwalten, sowie andere Methoden für die Arbeit mit der Markttiefe in den kommenden Artikeln einführen.

Nachfolgend finden Sie die Methoden, die String-Beschreibungen der Symbolobjekteigenschaften zurückgeben:

//+------------------------------------------------------------------+
//| Return the status description                                    |
//+------------------------------------------------------------------+
string CSymbol::GetStatusDescription() const
  {
   return
     (
      this.Status()==SYMBOL_STATUS_FX              ? TextByLanguage("Форекс символ","Forex symbol")                  :
      this.Status()==SYMBOL_STATUS_FX_MAJOR        ? TextByLanguage("Форекс символ-мажор","Forex major symbol")      :
      this.Status()==SYMBOL_STATUS_FX_MINOR        ? TextByLanguage("Форекс символ-минор","Forex minor symbol")      :
      this.Status()==SYMBOL_STATUS_FX_EXOTIC       ? TextByLanguage("Форекс символ-экзотик","Forex Exotic Symbol")   :
      this.Status()==SYMBOL_STATUS_FX_RUB          ? TextByLanguage("Форекс символ/рубль","Forex symbol RUB")        :
      this.Status()==SYMBOL_STATUS_FX_METAL        ? TextByLanguage("Металл","Metal")                                :
      this.Status()==SYMBOL_STATUS_INDEX           ? TextByLanguage("Индекс","Index")                                :
      this.Status()==SYMBOL_STATUS_INDICATIVE      ? TextByLanguage("Индикатив","Indicative")                        :
      this.Status()==SYMBOL_STATUS_CRYPTO          ? TextByLanguage("Криптовалютный символ","Crypto symbol")         :
      this.Status()==SYMBOL_STATUS_COMMODITY       ? TextByLanguage("Товарный символ","Commodity symbol")            :
      this.Status()==SYMBOL_STATUS_EXCHANGE        ? TextByLanguage("Биржевой символ","Exchange symbol")             : 
      this.Status()==SYMBOL_STATUS_BIN_OPTION      ? TextByLanguage("Бинарный опцион","Binary option")               : 
      this.Status()==SYMBOL_STATUS_CUSTOM          ? TextByLanguage("Пользовательский символ","Custom symbol")       :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the price type description for constructing bars          |
//+------------------------------------------------------------------+
string CSymbol::GetChartModeDescription(void) const
  {
   return
     (
      this.ChartMode()==SYMBOL_CHART_MODE_BID ? TextByLanguage("Бары строятся по ценам Bid","Bars based on Bid prices") : 
      TextByLanguage("Бары строятся по ценам Last","Bars based on Last prices")
     );
  }
//+------------------------------------------------------------------+
//| Return the description of the margin calculation method          |
//+------------------------------------------------------------------+
string CSymbol::GetCalcModeDescription(void) const
  {
   return
     (
      this.TradeCalcMode()==SYMBOL_CALC_MODE_FOREX                ? 
         TextByLanguage("Расчет прибыли и маржи для Форекс","Forex mode")                                               :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE    ? 
         TextByLanguage("Расчет прибыли и маржи для Форекс без учета плеча","Forex No Leverage mode")                   :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_FUTURES              ? 
         TextByLanguage("Расчет залога и прибыли для фьючерсов","Futures mode")                                         :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_CFD                  ? 
         TextByLanguage("Расчет залога и прибыли для CFD","CFD mode")                                                   :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_CFDINDEX             ? 
         TextByLanguage("Расчет залога и прибыли для CFD на индексы","CFD index mode")                                  :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_CFDLEVERAGE          ? 
         TextByLanguage("Расчет залога и прибыли для CFD при торговле с плечом","CFD Leverage mode")                    :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_EXCH_STOCKS          ? 
         TextByLanguage("Расчет залога и прибыли для торговли ценными бумагами на бирже","Exchange mode")               :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_EXCH_FUTURES         ? 
         TextByLanguage("Расчет залога и прибыли для торговли фьючерсными контрактами на бирже","Futures mode")         :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS   ? 
         TextByLanguage("Расчет залога и прибыли для торговли фьючерсными контрактами на FORTS","FORTS Futures mode")   :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_EXCH_BONDS           ? 
         TextByLanguage("Расчет прибыли и маржи по торговым облигациям на бирже","Exchange Bonds mode")                 :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_EXCH_STOCKS_MOEX     ? 
         TextByLanguage("Расчет прибыли и маржи при торговле ценными бумагами на MOEX","Exchange MOEX Stocks mode")     :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_EXCH_BONDS_MOEX      ? 
         TextByLanguage("Расчет прибыли и маржи по торговым облигациям на MOEX","Exchange MOEX Bonds mode")             :
      this.TradeCalcMode()==SYMBOL_CALC_MODE_SERV_COLLATERAL      ? 
         TextByLanguage("Используется в качестве неторгуемого актива на счете","Collateral mode")                       :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the description of a symbol trading mode                  |
//+------------------------------------------------------------------+
string CSymbol::GetTradeModeDescription(void) const
  {
   return
     (
      this.TradeMode()==SYMBOL_TRADE_MODE_DISABLED    ? TextByLanguage("Торговля по символу запрещена","Trade disabled for symbol")                     :
      this.TradeMode()==SYMBOL_TRADE_MODE_LONGONLY    ? TextByLanguage("Разрешены только покупки","Only long positions allowed")                               :
      this.TradeMode()==SYMBOL_TRADE_MODE_SHORTONLY   ? TextByLanguage("Разрешены только продажи","Only short positions allowed")                              :
      this.TradeMode()==SYMBOL_TRADE_MODE_CLOSEONLY   ? TextByLanguage("Разрешены только операции закрытия позиций","Only position close operations allowed")  :
      this.TradeMode()==SYMBOL_TRADE_MODE_FULL        ? TextByLanguage("Нет ограничений на торговые операции","No trade restrictions")                         :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the description of a symbol trade execution mode          |
//+------------------------------------------------------------------+
string CSymbol::GetTradeExecDescription(void) const
  {
   return
     (
      this.TradeExecutionMode()==SYMBOL_TRADE_EXECUTION_REQUEST   ? TextByLanguage("Торговля по запросу","Execution by request")       :
      this.TradeExecutionMode()==SYMBOL_TRADE_EXECUTION_INSTANT   ? TextByLanguage("Торговля по потоковым ценам","Instant execution")  :
      this.TradeExecutionMode()==SYMBOL_TRADE_EXECUTION_MARKET    ? TextByLanguage("Исполнение ордеров по рынку","Market execution")   :
      this.TradeExecutionMode()==SYMBOL_TRADE_EXECUTION_EXCHANGE  ? TextByLanguage("Биржевое исполнение","Exchange execution")         :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the description of a swap calculation model               |
//+------------------------------------------------------------------+
string CSymbol::GetSwapModeDescription(void) const
  {
   return
     (
      this.SwapMode()==SYMBOL_SWAP_MODE_DISABLED         ? 
         TextByLanguage("Нет свопов","Swaps disabled (no swaps)")                                                                                                                                                    :
      this.SwapMode()==SYMBOL_SWAP_MODE_POINTS           ? 
         TextByLanguage("Свопы начисляются в пунктах","Swaps charged in points")                                                                                                                                 :
      this.SwapMode()==SYMBOL_SWAP_MODE_CURRENCY_SYMBOL  ? 
         TextByLanguage("Свопы начисляются в деньгах в базовой валюте символа","Swaps charged in money in base currency of symbol")                                                                          :
      this.SwapMode()==SYMBOL_SWAP_MODE_CURRENCY_MARGIN  ? 
         TextByLanguage("Свопы начисляются в деньгах в маржинальной валюте символа","Swaps charged in money in margin currency of symbol")                                                                   :
      this.SwapMode()==SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT ? 
         TextByLanguage("Свопы начисляются в деньгах в валюте депозита клиента","Swaps charged in money, in client deposit currency")                                                                            :
      this.SwapMode()==SYMBOL_SWAP_MODE_INTEREST_CURRENT ? 
         TextByLanguage("Свопы начисляются в годовых процентах от цены инструмента на момент расчета свопа","Swaps charged as specified annual interest from instrument price at calculation of swap")   :
      this.SwapMode()==SYMBOL_SWAP_MODE_INTEREST_OPEN    ? 
         TextByLanguage("Свопы начисляются в годовых процентах от цены открытия позиции по символу","Swaps charged as specified annual interest from open price of position")                            :
      this.SwapMode()==SYMBOL_SWAP_MODE_REOPEN_CURRENT   ? 
         TextByLanguage("Свопы начисляются переоткрытием позиции по цене закрытия","Swaps charged by reopening positions by close price")                                                                    :
      this.SwapMode()==SYMBOL_SWAP_MODE_REOPEN_BID       ? 
         TextByLanguage("Свопы начисляются переоткрытием позиции по текущей цене Bid","Swaps charged by reopening positions by the current Bid price")                                                           :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the description of StopLoss and TakeProfit order lifetime |
//+------------------------------------------------------------------+
string CSymbol::GetOrderGTCModeDescription(void) const
  {
   return
     (
      this.OrderModeGTC()==SYMBOL_ORDERS_GTC                   ? 
         TextByLanguage("Отложенные ордеры и уровни Stop Loss/Take Profit действительны неограниченно по времени до явной отмены","Pending orders and Stop Loss/Take Profit levels are valid for unlimited period until their explicit cancellation") :
      this.OrderModeGTC()==SYMBOL_ORDERS_DAILY                 ? 
         TextByLanguage("При смене торгового дня отложенные ордеры и все уровни StopLoss и TakeProfit удаляются","At the end of the day, all Stop Loss and Take Profit levels, as well as pending orders are deleted")                                   :
      this.OrderModeGTC()==SYMBOL_ORDERS_DAILY_EXCLUDING_STOPS ? 
         TextByLanguage("При смене торгового дня удаляются только отложенные ордеры, уровни StopLoss и TakeProfit сохраняются","At the end of the day, only pending orders deleted, while Stop Loss and Take Profit levels preserved")           :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return the option type description                               |
//+------------------------------------------------------------------+
string CSymbol::GetOptionTypeDescription(void) const
  {
   return
     (
      #ifdef __MQL4__ TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #else 
      this.OptionMode()==SYMBOL_OPTION_MODE_EUROPEAN ? 
         TextByLanguage("Европейский тип опциона – может быть погашен только в указанную дату","European option may only be exercised on specified date")                               :
      this.OptionMode()==SYMBOL_OPTION_MODE_AMERICAN ? 
         TextByLanguage("Американский тип опциона – может быть погашен в любой день до истечения срока опциона","American option may be exercised on any trading day or before expiry")   :
      ""
      #endif 
     );
  }
//+------------------------------------------------------------------+
//| Return the option right description                              |
//+------------------------------------------------------------------+
string CSymbol::GetOptionRightDescription(void) const
  {
   return
     (
      #ifdef __MQL4__ TextByLanguage("Свойство не поддерживается в MQL4","Property not supported in MQL4") #else 
      this.OptionRight()==SYMBOL_OPTION_RIGHT_CALL ? 
         TextByLanguage("Опцион, дающий право купить актив по фиксированной цене","Call option gives you right to buy asset at specified price")    :
      this.OptionRight()==SYMBOL_OPTION_RIGHT_PUT  ? 
         TextByLanguage("Опцион, дающий право продать актив по фиксированной цене  ","Put option gives you right to sell asset at specified price") :
      ""
      #endif 
     );
  }
//+------------------------------------------------------------------+
//| Return the description of the flags of allowed order types       |
//+------------------------------------------------------------------+
string CSymbol::GetOrderModeFlagsDescription(void) const
  {
   string first=#ifdef __MQL5__ "\n - " #else ""   #endif ;
   string next= #ifdef __MQL5__ "\n - " #else "; " #endif ;
   return
     (
      first+this.GetMarketOrdersAllowedDescription()+
      next+this.GetLimitOrdersAllowedDescription()+
      next+this.GetStopOrdersAllowedDescription()+
      next+this.GetStopLimitOrdersAllowedDescription()+
      next+this.GetStopLossOrdersAllowedDescription()+
      next+this.GetTakeProfitOrdersAllowedDescription()+
      next+this.GetCloseByOrdersAllowedDescription()
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of the flags of allowed filling types         |
//+----------------------------------------------------------------------+
string CSymbol::GetFillingModeFlagsDescription(void) const
  {
   string first=#ifdef __MQL5__ "\n - " #else ""   #endif ;
   string next= #ifdef __MQL5__ "\n - " #else "; " #endif ;
   return
     (
      first+TextByLanguage("Вернуть (Да)","Return (Yes)")+
      next+this.GetFillingModeFOKAllowedDescrioption()+
      next+this.GetFillingModeIOCAllowedDescrioption()
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of the flags of allowed order expiration modes|
//+----------------------------------------------------------------------+
string CSymbol::GetExpirationModeFlagsDescription(void) const
  {
   string first=#ifdef __MQL5__ "\n - " #else ""   #endif ;
   string next= #ifdef __MQL5__ "\n - " #else "; " #endif ;
   return
     (
      first+this.GetExpirationModeGTCDescription()+
      next+this.GetExpirationModeDAYDescription()+
      next+this.GetExpirationModeSpecifiedDescription()+
      next+this.GetExpirationModeSpecDayDescription()
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing to use market orders              |
//+----------------------------------------------------------------------+
string CSymbol::GetMarketOrdersAllowedDescription(void) const
  {
   return
     (this.IsMarketOrdersAllowed() ? 
      TextByLanguage("Рыночный ордер (Да)","Market order (Yes)") : 
      TextByLanguage("Рыночный ордер (Нет)","Market order (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing to use limit orders               |
//+----------------------------------------------------------------------+
string CSymbol::GetLimitOrdersAllowedDescription(void) const
  {
   return
     (this.IsLimitOrdersAllowed() ? 
      TextByLanguage("Лимит ордер (Да)","Limit order (Yes)") : 
      TextByLanguage("Лимит ордер (Нет)","Limit order (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing to use stop orders                |
//+----------------------------------------------------------------------+
string CSymbol::GetStopOrdersAllowedDescription(void) const
  {
   return
     (this.IsStopOrdersAllowed() ? 
      TextByLanguage("Стоп ордер (Да)","Stop order (Yes)") : 
      TextByLanguage("Стоп ордер (Нет)","Stop order (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing to use stop limit orders          |
//+----------------------------------------------------------------------+
string CSymbol::GetStopLimitOrdersAllowedDescription(void) const
  {
   return
     (this.IsStopLimitOrdersAllowed() ? 
      TextByLanguage("Стоп-лимит ордер (Да)","StopLimit order (Yes)") : 
      TextByLanguage("Стоп-лимит ордер (Нет)","StopLimit order (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing to set StopLoss orders            |
//+----------------------------------------------------------------------+
string CSymbol::GetStopLossOrdersAllowedDescription(void) const
  {
   return
     (this.IsStopLossOrdersAllowed() ? 
      TextByLanguage("StopLoss (Да)","StopLoss (Yes)") : 
      TextByLanguage("StopLoss (Нет)","StopLoss (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing to set TakeProfit orders          |
//+----------------------------------------------------------------------+
string CSymbol::GetTakeProfitOrdersAllowedDescription(void) const
  {
   return
     (this.IsTakeProfitOrdersAllowed() ? 
      TextByLanguage("TakeProfit (Да)","TakeProfit (Yes)") : 
      TextByLanguage("TakeProfit (Нет)","TakeProfit (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing to close by an opposite position  |
//+----------------------------------------------------------------------+
string CSymbol::GetCloseByOrdersAllowedDescription(void) const
  {
   return
     (this.IsCloseByOrdersAllowed() ? 
      TextByLanguage("Закрытие встречным (Да)","CloseBy order (Yes)") : 
      TextByLanguage("Закрытие встречным (Нет)","CloseBy order (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing FOK filling type                  |
//+----------------------------------------------------------------------+
string CSymbol::GetFillingModeFOKAllowedDescrioption(void) const
  {
   return
     (this.IsFillingModeFOK() ? 
      TextByLanguage("Всё/Ничего (Да)","Fill or Kill (Yes)") : 
      TextByLanguage("Всё/Ничего (Нет)","Fill or Kill (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of allowing IOC filling type                  |
//+----------------------------------------------------------------------+
string CSymbol::GetFillingModeIOCAllowedDescrioption(void) const
  {
   return
     (this.IsFillingModeIOC() ? 
      TextByLanguage("Всё/Частично (Да)","Immediate or Cancel order (Yes)") : 
      TextByLanguage("Всё/Частично (Нет)","Immediate or Cancel (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of GTC order expiration                       |
//+----------------------------------------------------------------------+
string CSymbol::GetExpirationModeGTCDescription(void) const
  {
   return
     (this.IsExipirationModeGTC() ? 
      TextByLanguage("Неограниченно (Да)","Unlimited (Yes)") : 
      TextByLanguage("Неограниченно (Нет)","Unlimited (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of DAY order expiration                       |
//+----------------------------------------------------------------------+
string CSymbol::GetExpirationModeDAYDescription(void) const
  {
   return
     (this.IsExipirationModeDAY() ? 
      TextByLanguage("До конца дня (Да)","Valid till the end of day (Yes)") : 
      TextByLanguage("До конца дня (Нет)","Valid till the end of day (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of Specified order expiration                 |
//+----------------------------------------------------------------------+
string CSymbol::GetExpirationModeSpecifiedDescription(void) const
  {
   return
     (this.IsExipirationModeSpecified() ? 
      TextByLanguage("Срок указывается в ордере (Да)","Time specified in order (Yes)") : 
      TextByLanguage("Срок указывается в ордере (Нет)","Time specified in order (No)")
     );
  }
//+----------------------------------------------------------------------+
//| Return the description of Specified Day order expiration             |
//+----------------------------------------------------------------------+
string CSymbol::GetExpirationModeSpecDayDescription(void) const
  {
   return
     (this.IsExipirationModeSpecifiedDay() ? 
      TextByLanguage("День указывается в ордере (Да)","Date specified in order (Yes)") : 
      TextByLanguage("День указывается в ордере (Нет)","Date specified in order (No)")
     );
  }
//+------------------------------------------------------------------+

In den Methoden ist alles einfach: Ein Eigenschaftswert wird überprüft und seine String-Beschreibung zurückgegeben.
Einige Methoden (nämlich die Flag-Beschreibung) zeigen Zeichenkettenwerte anderer Methoden innerhalb einer zurückgegebenen Beschreibung an. Diese anderen Methoden wiederum geben die Beschreibungen bestimmter Flags zurück, aus denen der Wert einer überprüften Eigenschaft besteht. So erhalten wir eine formatierte zusammengesetzte Beschreibung aller Flags einer einzelnen Eigenschaft.
In MQL5 werden z.B. Flags einer einzelnen Eigenschaft in einer Spalte unter dem Namen einer beschriebenen Eigenschaft angezeigt:

Die Flags der erlaubten Auftragsarten: 
 - Marktorder (Ja)
 - Limit-Order (Ja)
 - Stop-Order (Ja)
 - Stop-Limit-Order (Ja)
 - Stop-Loss (Ja)
 - Take-Profit (Ja)
 - Schließen durch (Ja)

In MQL4 werden diese Eigenschaften in einer einzigen Zeichenkette angezeigt:

Die Flags der erlaubten Auftragsarten: Market order (Yes); Limit order (Yes); Stop order (Yes); Stop limit order (No); StopLoss (Yes); TakeProfit (Yes); Close by (Yes)

Dies liegt daran, dass in MQL4 die Funktion Print() das Zeichen zum Zeilenumbruch "\n" nicht akzeptiert. Daher verfügen die Methoden über eine separate Formatierung für MQL5 und MQL4 unter Verwendung von bedingten Kompilierungsanweisungen.

Nachfolgend finden Sie die Servicemethode, die einen normalisierten Preis unter Berücksichtigung der Symboleigenschaften zurückgibt:

//+------------------------------------------------------------------+
//| Return a normalized price considering symbol properties          |
//+------------------------------------------------------------------+
double CSymbol::NormalizedPrice(const double price) const
  {
   double tsize=this.TradeTickSize();
   return(tsize!=0 ? ::NormalizeDouble(::round(price/tsize)*tsize,this.Digits()) : ::NormalizeDouble(price,this.Digits()));
  }
//+------------------------------------------------------------------+

Die Methode normalisiert den Preis unter Berücksichtigung der kleinstmöglichen Preisänderung.

Schließlich gibt es zwei Methoden:
Methode zur Aktualisierung aller Symbolobjekteigenschaften, die sich in der Zukunft ändern können, und die Methode zur Aktualisierung der Kursdaten des Symbols:.

//+------------------------------------------------------------------+
//| Update all symbol data that may change                           |
//+------------------------------------------------------------------+
void CSymbol::Refresh(void)
  {
   ::ResetLastError();
   if(!::SymbolInfoTick(this.m_symbol_name,this.m_tick))
     {
      this.m_global_error=::GetLastError();
      ::Print(DFUN_ERR_LINE,this.Name(),": ",TextByLanguage("Не удалось получить текущие цены. Ошибка: ","Could not get current prices. Error: "),this.m_global_error);
      return;
     }
//--- Update integer properties
   this.m_long_prop[SYMBOL_PROP_VOLUME]                                       = (long)this.m_tick.volume;
   this.m_long_prop[SYMBOL_PROP_TIME]                                         = #ifdef __MQL5__ this.m_tick.time_msc #else this.m_tick.time*1000 #endif ;
   this.m_long_prop[SYMBOL_PROP_SELECT]                                       = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SELECT);
   this.m_long_prop[SYMBOL_PROP_VISIBLE]                                      = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_VISIBLE);
   this.m_long_prop[SYMBOL_PROP_SESSION_DEALS]                                = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SESSION_DEALS);
   this.m_long_prop[SYMBOL_PROP_SESSION_BUY_ORDERS]                           = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SESSION_BUY_ORDERS);
   this.m_long_prop[SYMBOL_PROP_SESSION_SELL_ORDERS]                          = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SESSION_SELL_ORDERS);
   this.m_long_prop[SYMBOL_PROP_VOLUMEHIGH]                                   = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_VOLUMEHIGH);
   this.m_long_prop[SYMBOL_PROP_VOLUMELOW]                                    = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_VOLUMELOW);
   this.m_long_prop[SYMBOL_PROP_SPREAD]                                       = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SPREAD);
   this.m_long_prop[SYMBOL_PROP_TICKS_BOOKDEPTH]                              = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TICKS_BOOKDEPTH);
   this.m_long_prop[SYMBOL_PROP_START_TIME]                                   = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_START_TIME);
   this.m_long_prop[SYMBOL_PROP_EXPIRATION_TIME]                              = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_EXPIRATION_TIME);
   this.m_long_prop[SYMBOL_PROP_TRADE_STOPS_LEVEL]                            = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_STOPS_LEVEL);
   this.m_long_prop[SYMBOL_PROP_TRADE_FREEZE_LEVEL]                           = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_FREEZE_LEVEL);
   this.m_long_prop[SYMBOL_PROP_BACKGROUND_COLOR]                             = this.SymbolBackgroundColor();
//--- Update real properties
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKHIGH)]                    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_ASKHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKLOW)]                     = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_ASKLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTHIGH)]                   = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_LASTHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTLOW)]                    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_LASTLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT)]    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE_PROFIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS)]      = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE_LOSS);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_SIZE)]            = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_SIZE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_CONTRACT_SIZE)]        = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_CONTRACT_SIZE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MIN)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_MIN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MAX)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_MAX);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_STEP)]                = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_STEP);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_LIMIT)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_VOLUME_LIMIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_LONG)]                  = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SWAP_LONG);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_SHORT)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SWAP_SHORT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_INITIAL)]             = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_INITIAL);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_MAINTENANCE)]         = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_MAINTENANCE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG)]                = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_LONG);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_SHORT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_STOP)]                = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_STOP);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LIMIT)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_LIMIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_STOPLIMIT)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_MARGIN_STOPLIMIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_VOLUME)]             = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_TURNOVER)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_TURNOVER);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_INTEREST)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_INTEREST);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME)]  = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_BUY_ORDERS_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_SELL_ORDERS_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_OPEN)]               = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_OPEN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_CLOSE)]              = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_CLOSE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_AW)]                 = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_AW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT)]   = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_PRICE_SETTLEMENT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN)]    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_PRICE_LIMIT_MIN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX)]    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_SESSION_PRICE_LIMIT_MAX);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASK)]                        = this.m_tick.ask;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BID)]                        = this.m_tick.bid;
   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();
  }
//+------------------------------------------------------------------+
//| Update quote data by symbol                                      |
//+------------------------------------------------------------------+
void CSymbol::RefreshRates(void)
  {
   ::ResetLastError();
   if(!::SymbolInfoTick(this.m_symbol_name,this.m_tick))
     {
      this.m_global_error=::GetLastError();
      ::Print(DFUN_ERR_LINE,this.Name(),": ",TextByLanguage("Не удалось получить текущие цены. Ошибка: ","Could not get current prices. Error: "),this.m_global_error);
      return;
     }
//--- Update integer properties
   this.m_long_prop[SYMBOL_PROP_VOLUME]                                       = (long)this.m_tick.volume;
   this.m_long_prop[SYMBOL_PROP_TIME]                                         = #ifdef __MQL5__ this.m_tick.time_msc #else this.m_tick.time*1000 #endif ;
   this.m_long_prop[SYMBOL_PROP_SPREAD]                                       = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_SPREAD);
   this.m_long_prop[SYMBOL_PROP_TRADE_STOPS_LEVEL]                            = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_STOPS_LEVEL);
   this.m_long_prop[SYMBOL_PROP_TRADE_FREEZE_LEVEL]                           = ::SymbolInfoInteger(this.m_symbol_name,SYMBOL_TRADE_FREEZE_LEVEL);
//--- Update real properties
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKHIGH)]                    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_ASKHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKLOW)]                     = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_ASKLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTHIGH)]                   = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_LASTHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTLOW)]                    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_LASTLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE)]           = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT)]    = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE_PROFIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS)]      = ::SymbolInfoDouble(this.m_symbol_name,SYMBOL_TRADE_TICK_VALUE_LOSS);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASK)]                        = this.m_tick.ask;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BID)]                        = this.m_tick.bid;
   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_OPTION_STRIKE)]              = this.SymbolOptionStrike();
  }  
//+------------------------------------------------------------------+

Hier ist alles ganz einfach: Die erforderlichen Symboleigenschaften werden aus ihren Daten neu eingetragen.
Beide Verfahren sind für die Gewinnung relevanter Daten über Symboleigenschaften gedacht. Die Methode Refresh() sollte unmittelbar vor dem Abrufen der erforderlichen Daten aufgerufen werden, während die Methode RefreshRates() im Timer für alle Symbolobjekte innerhalb der Kollektionsliste, mit der wir uns später befassen werden, immer wieder aufgerufen wird.

Damit ist die Entwicklung der Objektmethoden für abstrakte Symbole abgeschlossen.

Nun müssen wir noch einige Ergänzungen in der Datei ToMQL4.mqh vornehmen, wo wir alle notwendigen Enumerationen und Makroersetzungen für eine fehlerfreie Kompilierung in MQL4 einstellen.

In der Symbol-Objektklasse haben wir die Rückgabe von MQL5-Fehlercodes verwendet. Fügen wir sie hinzu, um MQL4 über ihre Grenzen zu informieren:

//+------------------------------------------------------------------+
//|                                                       ToMQL4.mqh |
//|              Copyright 2017, Artem A. Trishkin, Skype artmedia70 |
//|                         https://www.mql5.com/de/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Artem A. Trishkin, Skype artmedia70"
#property link      "https://www.mql5.com/de/users/artmedia70"
#property strict
#ifdef __MQL4__
//+------------------------------------------------------------------+
//| Error codes                                                      |
//+------------------------------------------------------------------+
#define ERR_SUCCESS                       (ERR_NO_ERROR)
#define ERR_MARKET_UNKNOWN_SYMBOL         (ERR_UNKNOWN_SYMBOL)
//+------------------------------------------------------------------+

Wir haben auch die Flags verwendet, die für verschiedene Symbolordnungsmodi verantwortlich sind. Lassen Sie uns auch diese spezifizieren:

//+------------------------------------------------------------------+
//| Flags of allowed order expiration modes                          |
//+------------------------------------------------------------------+
#define SYMBOL_EXPIRATION_GTC             (1)
#define SYMBOL_EXPIRATION_DAY             (2)
#define SYMBOL_EXPIRATION_SPECIFIED       (4)
#define SYMBOL_EXPIRATION_SPECIFIED_DAY   (8)
//+------------------------------------------------------------------+
//| Flags of allowed order filling modes                             |
//+------------------------------------------------------------------+
#define SYMBOL_FILLING_FOK                (1)
#define SYMBOL_FILLING_IOC                (2)
//+------------------------------------------------------------------+
//| Flags of allowed order types                                     |
//+------------------------------------------------------------------+
#define SYMBOL_ORDER_MARKET               (1)
#define SYMBOL_ORDER_LIMIT                (2)
#define SYMBOL_ORDER_STOP                 (4)
#define SYMBOL_ORDER_STOP_LIMIT           (8)
#define SYMBOL_ORDER_SL                   (16)
#define SYMBOL_ORDER_TP                   (32)
#define SYMBOL_ORDER_CLOSEBY              (64)
//+------------------------------------------------------------------+

Fügen Sie die in MQL4 fehlenden Enumerationen hinzu:

//+------------------------------------------------------------------+
//| Prices a symbol chart is based on                                |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_CHART_MODE
  {
   SYMBOL_CHART_MODE_BID,                 // Bars are based on Bid prices
   SYMBOL_CHART_MODE_LAST                 // Bars are based on Last prices
  };
//+------------------------------------------------------------------+
//| Lifetime of pending orders and                                   |
//| placed StopLoss/TakeProfit levels                                |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_ORDER_GTC_MODE
  {
   SYMBOL_ORDERS_GTC,                     // Pending orders and Stop Loss/Take Profit levels are valid for an unlimited period until their explicit cancellation
   SYMBOL_ORDERS_DAILY,                   // At the end of the day, all Stop Loss and Take Profit levels, as well as pending orders are deleted
   SYMBOL_ORDERS_DAILY_EXCLUDING_STOPS    // At the end of the day, only pending orders are deleted, while Stop Loss and Take Profit levels are preserved
  };
//+------------------------------------------------------------------+
//| Option types                                                     |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_OPTION_MODE
  {
   SYMBOL_OPTION_MODE_EUROPEAN,           // European option may only be exercised on a specified date
   SYMBOL_OPTION_MODE_AMERICAN            // American option may be exercised on any trading day or before expiry
  };
#define SYMBOL_OPTION_MODE_NONE     (2)   // Option type absent in MQL4
//+------------------------------------------------------------------+
//| Right provided by an option                                      |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_OPTION_RIGHT
  {
   SYMBOL_OPTION_RIGHT_CALL,              // A call option gives you the right to buy an asset at a specified price
   SYMBOL_OPTION_RIGHT_PUT                // A put option gives you the right to sell an asset at a specified price
  };
#define SYMBOL_OPTION_RIGHT_NONE    (2)   // No option - no right
//+------------------------------------------------------------------+

Verwenden Sie Makro-Substitutionen, um zusätzliche Eigenschaften für Optionen festzulegen. Diese Eigenschaften zeigen das Fehlen von Optionstyp und Recht an. Wir werden sie in MQL4 verwenden, wenn wir den Wert dieser Symbolobjekteigenschaften zurückgeben.

Die folgenden beiden Enumerationen enthalten keine Folge von konstanten Werten in MQL5 und MQL4.

Deshalb habe ich die Sequenzen der Angabe von Konstanten, die in den Enumerationen enthalten sind, getauscht. Die entsprechenden Werte für MQL5 und MQL4 werden in den Kommentaren auf konstante Werte gesetzt. Ihre Reihenfolge wird hier so eingestellt, dass sie mit den Werten in MQL4 übereinstimmt, um korrekte Werte zurückzugeben:

//+------------------------------------------------------------------+
//| Symbol margin calculation method                                 |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_CALC_MODE
  {
   SYMBOL_CALC_MODE_FOREX,                // (MQL5 - 0, MQL4 - 0) Forex mode
   SYMBOL_CALC_MODE_CFD,                  // (MQL5 - 3, MQL4 - 1) CFD mode
   SYMBOL_CALC_MODE_FUTURES,              // (MQL5 - 2, MQL4 - 2) Futures mode
   SYMBOL_CALC_MODE_CFDINDEX,             // (MQL5 - 4, MQL4 - 3) CFD index mode
   SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE,    // (MQL5 - 1, MQL4 - N) Forex No Leverage mode
   SYMBOL_CALC_MODE_CFDLEVERAGE,          // CFD Leverage mode
   SYMBOL_CALC_MODE_EXCH_STOCKS,          // Exchange mode
   SYMBOL_CALC_MODE_EXCH_FUTURES,         // Futures mode
   SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS,   // FORTS Futures mode
   SYMBOL_CALC_MODE_EXCH_BONDS,           // Exchange Bonds mode
   SYMBOL_CALC_MODE_EXCH_STOCKS_MOEX,     // Exchange MOEX Stocks mode
   SYMBOL_CALC_MODE_EXCH_BONDS_MOEX,      // Exchange MOEX Bonds mode
   SYMBOL_CALC_MODE_SERV_COLLATERAL       // Collateral mode
  };  
//+------------------------------------------------------------------+
//| Swap charging methods during a rollover                          |
//+------------------------------------------------------------------+
enum ENUM_SYMBOL_SWAP_MODE
  {
   SYMBOL_SWAP_MODE_POINTS,               // (MQL5 - 1, MQL4 - 0) Swaps are charged in points
   SYMBOL_SWAP_MODE_CURRENCY_SYMBOL,      // (MQL5 - 2, MQL4 - 1) Swaps are charged in money in symbol base currency
   SYMBOL_SWAP_MODE_INTEREST_OPEN,        // (MQL5 - 6, MQL4 - 2) Swaps are charged as the specified annual interest from the open price of position
   SYMBOL_SWAP_MODE_CURRENCY_MARGIN,      // (MQL5 - 3, MQL4 - 3) Swaps are charged in money in margin currency of the symbol
   SYMBOL_SWAP_MODE_DISABLED,             // (MQL5 - 0, MQL4 - N) No swaps
   SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT,     // Swaps are charged in money, in client deposit currency
   SYMBOL_SWAP_MODE_INTEREST_CURRENT,     // Swaps are charged as the specified annual interest from the instrument price at calculation of swap
   SYMBOL_SWAP_MODE_REOPEN_CURRENT,       // Swaps are charged by reopening positions by the close price
   SYMBOL_SWAP_MODE_REOPEN_BID            // Swaps are charged by reopening positions by the current Bid price
  };
//+------------------------------------------------------------------+

Alle Daten des Symbolobjekts sind nun angelegt.

Da wir den Fehlercode, der von den Klassen zurückgegeben wird, in das Hauptobjekt der Engine Library eingeführt haben, müssen wir das CEngine Klassenvariablenelement zum Speichern des Fehlercodes hinzufügen. Öffnen Sie \MQL5\Include\DoEasy\ Engine.mqh und nehmen Sie die notwendigen Änderungen vor.
Im Abschnitt 'private' der Klasse deklarieren Sie die Variable zum Speichern der Fehlercodes:

class CEngine : public CObject
  {
private:
   CHistoryCollection   m_history;                       // Kollektion der historischen Aufträge und Deals
   CMarketCollection    m_market;                        // Kollektion der Marktorder und Deals
   CEventsCollection    m_events;                        // Event collection
   CAccountsCollection  m_accounts;                      // Account collection
   CArrayObj            m_list_counters;                 // Liste der Timerzähler
   int                  m_global_error;                  // Global error code
   bool                 m_first_start;                   // Flag des Erststarts
   bool                 m_is_hedge;                      // Flag des Hedging-Kontos
   bool                 m_is_tester;                     // Flag of working in the tester

In der Initialisierungsliste des Klassenkonstruktors, initialisieren Sie den Fehlercode. Als Nächstes fügen Sie in den Blöcken zum Erstellen des Millisekunden-Timers für MQL5 und MQL4, den letzten Fehlercode zur Variable hinzu:

//+------------------------------------------------------------------+
//| CEngine Konstruktor                                              |
//+------------------------------------------------------------------+
CEngine::CEngine() : m_first_start(true),m_last_trade_event(TRADE_EVENT_NO_EVENT),m_last_account_event(ACCOUNT_EVENT_NO_EVENT),m_global_error(ERR_SUCCESS)
  {
   this.m_list_counters.Sort();
   this.m_list_counters.Clear();
   this.CreateCounter(COLLECTION_ORD_COUNTER_ID,COLLECTION_ORD_COUNTER_STEP,COLLECTION_ORD_PAUSE);
   this.CreateCounter(COLLECTION_ACC_COUNTER_ID,COLLECTION_ACC_COUNTER_STEP,COLLECTION_ACC_PAUSE);
   
   this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif;
   this.m_is_tester=::MQLInfoInteger(MQL_TESTER);
   ::ResetLastError();
   #ifdef __MQL5__
      if(!::EventSetMillisecondTimer(TIMER_FREQUENCY))
        {
         ::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   //---__MQL4__
   #else 
      if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY))
        {
         ::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   #endif 
  }
//+------------------------------------------------------------------+

Nun müssen wir die Datei einer neu erstellten Klasse in das Hauptobjekt der Bibliothek einbinden (temporär - nur für die aktuelle Prüfung):

//+------------------------------------------------------------------+
//|                                                       Engine.mqh |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/de/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/de/users/artmedia70"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include-Dateien                                                  |
//+------------------------------------------------------------------+
#include "Collections\HistoryCollection.mqh"
#include "Collections\MarketCollection.mqh"
#include "Collections\EventsCollection.mqh"
#include "Collections\AccountsCollection.mqh"
#include "Services\TimerCounter.mqh"
#include "Objects\Symbols\Symbol.mqh"
//+------------------------------------------------------------------+
//| Bibliothek der Basisklasse                                       |
//+------------------------------------------------------------------+
class CEngine : public CObject
  {

Nun ist alles bereit, um das Symbolobjekt zu testen.

Aber zuerst möchte ich Ihre Aufmerksamkeit auf einen Fehler lenken, den ich im vorherigen Artikel unbeaufsichtigt gelassen habe, als ich die Methode erstellte, die ein Kontoereignis nach seiner Nummer in der Liste zurückgibt - in der Klasse zur Kontoerfassung CAccountsCollection.
Die aktuelle Version der Methode sieht wie folgt aus:

//+------------------------------------------------------------------+
//| Return the account event by its number in the list               |
//+------------------------------------------------------------------+
ENUM_ACCOUNT_EVENT CAccountsCollection::GetEvent(const int shift=WRONG_VALUE)
  {
   int total=this.m_list_changes.Total();
   if(total==0)
      return ACCOUNT_EVENT_NO_EVENT;   
   int index=(shift<0 || shift>total-1 ? total-1 : total-shift-1);
   int event=this.m_list_changes.At(index);
   return ENUM_ACCOUNT_EVENT(event!=NULL ? event : ACCOUNT_EVENT_NO_EVENT);
  }
//+------------------------------------------------------------------+

Hier ist, was ich über die Rückgabe von Ereignissen aus der Methode geschrieben habe:

Die Ereignisse in der Liste der Änderungen der Kontoeigenschaften befinden sich in der Reihenfolge, in der sie hinzugefügt wurden — das allererste befindet sich im Index 0, während das allerletzte im Index (list_size-1) liegt. Wir wollen jedoch, dass die Nutzer wie in einer Zeitreihe ein gewünschtes Ereignis erhalten — der Nullindex sollte das allerletzte Ereignis enthalten. Um dies zu erreichen, verfügt die Methode über die Indexberechnung: index = (list_size - desired_event_number-1). In diesem Fall wird wenn wir 0 oder -1 übergeben, das letzte Ereignis in der Liste zurückgegeben; bei 1, das vorletzte, und wenn die Zahl die Listengröße überschreitet, wird das letzte Ereignis zurückgegeben.

Hier haben wir eine logische Inkonsistenz: Wenn wir 0 an die Methode übergeben, erhalten wir das letzte Ereignis. Wenn wir den Wert übergeben, der die Array-Größe überschreitet, schreibt die Logik vor, dass wir das erste Ereignis anstelle des letzten zurückgeben sollten. Es wäre logisch, entweder 0 oder einen negativen Wert (standardmäßig) zu übergeben, um das letzte Ereignis zu empfangen und dann in Reihenfolge zu gehen: 1 - vorletzter, 2 - vorletzter, zwei, usw., wie in einer Zeitreihe.
Wenn wir die Array-Größe nicht kennen und eine wissentlich große Zahl übergeben, dann sollten wir damit rechnen, den weitesten Wert in der Zeit zu erhalten — den ersten, während die Methode den letzten zurückgibt. Beheben wir dieses unlogische Verhalten:

//+------------------------------------------------------------------+
//| Return the account event by its number in the list               |
//+------------------------------------------------------------------+
ENUM_ACCOUNT_EVENT CAccountsCollection::GetEvent(const int shift=WRONG_VALUE)
  {
   int total=this.m_list_changes.Total();
   if(total==0)
      return ACCOUNT_EVENT_NO_EVENT;   
   int index=(shift<=0 ? total-1 : shift>total-1 ? 0 : total-shift-1);
   int event=this.m_list_changes.At(index);
   return ENUM_ACCOUNT_EVENT(event!=NULL ? event : ACCOUNT_EVENT_NO_EVENT);
  }
//+------------------------------------------------------------------+

Hier: wenn 0 oder -1 übergeben wird, geben wir das letzte Ereignis zurück, wenn der Wert, der die Array-Größe überschreitet, übergeben wird, geben wir das erste Ereignis zurück. Der Index eines zurückgegebenen Ereignisses wird in anderen Fällen berechnet.

Testen des Symbolobjekts

Um das Objektsymbol zu testen, nehmen wir den EA aus dem vorherigen Artikel und speichern ihn unter dem Namen TestDoEasyPart14.mq5.

Wir werden das Objektsymbol in OnInit() überprüfen. Dazu fügen wir einfach die folgenden Codezeilen an das Ende von OnInit() an:

//+------------------------------------------------------------------+
//| Initialisierungsfunktion des Experten                            |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Calling the function displays the list of enumeration constants in the journal, 
//--- (the list is set in the strings 22 and 25 of the DELib.mqh file) for checking the constants validity
   //EnumNumbersTest();

//--- Set EA global variables
   prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_";
   for(int i=0;i<TOTAL_BUTT;i++)
     {
      butt_data[i].name=prefix+EnumToString((ENUM_BUTTONS)i);
      butt_data[i].text=EnumToButtText((ENUM_BUTTONS)i);
     }
   lot=NormalizeLot(Symbol(),fmax(InpLots,MinimumLots(Symbol())*2.0));
   magic_number=InpMagic;
   stoploss=InpStopLoss;
   takeprofit=InpTakeProfit;
   distance_pending=InpDistance;
   distance_stoplimit=InpDistanceSL;
   slippage=InpSlippage;
   trailing_stop=InpTrailingStop*Point();
   trailing_step=InpTrailingStep*Point();
   trailing_start=InpTrailingStart;
   stoploss_to_modify=InpStopLossModify;
   takeprofit_to_modify=InpTakeProfitModify;

//--- Check and remove remaining EA graphical objects
   if(IsPresentObects(prefix))
      ObjectsDeleteAll(0,prefix);

//--- Create the button panel
   if(!CreateButtons(InpButtShiftX,InpButtShiftY))
      return INIT_FAILED;
//--- Set trailing activation button status
   ButtonState(butt_data[TOTAL_BUTT-1].name,trailing_on);

//--- Set CTrade trading class parameters
#ifdef __MQL5__
   trade.SetDeviationInPoints(slippage);
   trade.SetExpertMagicNumber(magic_number);
   trade.SetTypeFillingBySymbol(Symbol());
   trade.SetMarginMode();
   trade.LogLevel(LOG_LEVEL_NO);
#endif 
//--- Fast check of a symbol object
   string smb=Symbol();
   CSymbol* sy=new CSymbol(SYMBOL_STATUS_FX,smb);
   if(sy!=NULL)
     {
      sy.Refresh();
      sy.RefreshRates();
      sy.Print();
      delete sy;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

Hier erstellen wir ein neues Symbolobjekt. Da wir das Symbol im nächsten Artikel einer bestimmten Gruppe zuordnen werden, übergeben Sie einfach das "Forex-Symbol" und den Symbolnamen an den Konstruktor.
Wenn das Objekt erstellt wird, aktualisieren Sie alle seine Daten, aktualisieren Sie die Angebotsdaten, zeigen Sie alle Eigenschaften des Symbolobjekts im Journal an und löschen Sie das Objekt, um ein Speicherleck zu vermeiden, wenn der Test EA seine Arbeit beendet hat.

Wenn wir nun versuchen, das EA zu kompilieren, erhalten wir den Fehler beim Zugriff auf den Konstruktor der geschützten Klasse:

'CSymbol::CSymbol' - cannot access protected member function    TestDoEasyPart14.mq5    131     20
   see declaration of 'CSymbol::CSymbol'        Symbol.mqh      39      22
1 error(s), 0 warning(s)                2       1

Gehen Sie zur Datei Symbol.mqh und verschieben Sie den parametrischen Konstruktor vorübergehend vom 'protected' Abschnitt der Klasse in den 'public' Abschnitt:

//+------------------------------------------------------------------+
//| Abstract symbol class                                            |
//+------------------------------------------------------------------+
class CSymbol : public CObject
  {
private:
   MqlTick           m_tick;                                         // Symbol tick structure
   MqlBookInfo       m_book_info_array[];                            // Array of the market depth data structures
   string            m_symbol_name;                                  // Symbol name
   long              m_long_prop[SYMBOL_PROP_INTEGER_TOTAL];         // Integer properties
   double            m_double_prop[SYMBOL_PROP_DOUBLE_TOTAL];        // Real properties
   string            m_string_prop[SYMBOL_PROP_STRING_TOTAL];        // String properties
   int               m_digits_currency;                              // Number of decimal places in an account currency
   int               m_global_error;                                 // Global error code
//--- Return the index of the array the symbol's (1) double and (2) string properties are located at
   int               IndexProp(ENUM_SYMBOL_PROP_DOUBLE property)  const { return(int)property-SYMBOL_PROP_INTEGER_TOTAL;                                    }
   int               IndexProp(ENUM_SYMBOL_PROP_STRING property)  const { return(int)property-SYMBOL_PROP_INTEGER_TOTAL-SYMBOL_PROP_DOUBLE_TOTAL;           }
//--- Reset all symbol object data
   void              Reset(void);
public:
//--- Standardmäßiger Konstruktor
                     CSymbol(void){;}
                     CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name);
protected:
//--- 'Protected' Konstruktor

//--- Get and return integer properties of a selected symbol from its parameters

Jetzt kompiliert alles ohne Probleme.

Starten wir den EA auf dem Chart eines Symbols im MetaTrader 5.
Alle Eigenschaften des Symbolobjekts werden ins Journal geschrieben:

Account 18222304: Artyom Trishkin (MetaQuotes Software Corp. 10000.00 RUR, 1:100, Demo account MetaTrader 5)
============= Beginning of the parameter list:: "EURUSD" (Euro vs US Dollar) ==================
Status: Forex symbol
Custom symbol: No
The price type used for generating bars: Bars are based on Bid prices
The symbol under this name exists: Yes
The symbol is selected in Market Watch: Yes
The symbol is displayed in Market Watch: Yes
The number of deals in the current session: 0
The total number of Buy orders at the moment: 0
The total number of Sell orders at the moment: 0
Last deal volume: 0
Maximum volume within a day: 0
Minimum volume within a day: 0
Latest quote time: 2019.06.17 15:37:13.016
Number of decimal places: 5
Number of decimal places for a lot: 2
Spread in points: 10
Floating spread: Yes
Maximum number of orders displayed in the Depth of Market: 10
Contract price calculation method: Forex mode
Order execution type: No trade restrictions
Symbol trading start date: (Not set)
Symbol trading end date: (Not set)
Minimum distance in points from the current close price for setting Stop orders: 0
Freeze distance for trading operations: 0
Deal execution mode: Instant execution
Swap calculation model: Swaps are charged in points
Triple-day swap: Wednesday
Calculating hedging margin using the larger leg: No
Flags of allowed order expiration modes: 
 - Unlimited (Yes)
 - Valid till the end of the day (Yes)
 - Time is specified in the order (Yes)
 - Date is specified in the order (Yes)
Flags of allowed order filling modes: 
 - Return (Yes)
 - Fill or Kill (Yes)
 - Immediate or Cancel (No)
Die Flags der erlaubten Auftragsarten: 
 - Marktorder (Ja)
 - Limit-Order (Ja)
 - Stop-Order (Ja)
 - Stop-Limit-Order (Ja)
 - Stop-Loss (Ja)
 - Take-Profit (Ja)
 - CloseBy order (Yes)
StopLoss and TakeProfit orders lifetime: Pending orders and Stop Loss/Take Profit levels are valid for an unlimited period until their explicit cancellation
Option type: European option may only be exercised on a specified date
Option right: A call option gives you the right to buy an asset at a specified price
Background color of the symbol in Market Watch: (Not set)
------
Bid price: 1.12411
The highest Bid price of the day: 1.12467
The lowest Bid price of the day: 1.12033
Ask price: 1.12421
The highest Ask price of the day: 1.12477
The lowest Ask price of the day: 1.12043
The last deal price: 0.00000
The highest Last price of the day: 0.00000
The lowest Last price of the day: 0.00000
Volume of the day: 0.00
Maximum Volume of the day: 0.00
Minimum Volume of the day: 0.00
Option execution price: 0.00000
Point value: 0.00001
Calculated tick value for a position: 64.22
Calculated tick value for a winning position: 64.22
Calculated tick value for a losing position: 64.23
Minimum price change: 0.00001
Trade contract size: 100000.00
Accrued interest: 0.00
Face value: 0.00
Liquidity rate: 0.00
Minimum volume for a deal: 0.01
Maximum volume for a deal: 500.00
Minimum volume change step for a deal: 0.01
Maximum acceptable total volume of an open position and pending orders in one direction: 0.00
Long swap value: -0.70
Short swap value: -1.00
Initial margin: 0.00
Maintenance margin for an instrument: 0.00
Margin requirement applicable to long positions: 0.00
Margin requirement applicable to short positions: 0.00
Margin requirement applicable to Stop orders: 0.00
Margin requirement applicable to Limit orders: 0.00
Margin requirement applicable to Stop Limit orders: 0.00
The total volume of deals in the current session: 0.00
The total turnover in the current session: 0.00
The total volume of open positions: 0.00
The total volume of Buy orders at the moment: 0.00
The total volume of Sell orders at the moment: 0.00
The open price of the session: 0.00000
The close price of the session: 0.00000
The average weighted price of the session: 0.00000
The settlement price of the current session: 0.00000
The minimum allowable price value for the session: 0.00000
The maximum allowable price value for the session: 0.00000
Size of a contract or margin for one lot of hedged positions: 100000.00
------
Symbol name: EURUSD
The name of the underlaying asset for a derivative symbol: (Not set)
The base currency of an instrument: "EUR"
Profit currency: "USD"
Margin currency: "EUR"
The source of the current quote: (Not set)
Symbol description: "Euro vs US Dollar"
The formula used for custom symbol pricing: (Not set)
The name of a trading symbol in the international system of securities identification numbers: (Not set)
The address of the web page containing symbol information: "http://www.google.com/finance?q=EURUSD"
Path in the symbol tree: "Forex\EURUSD"
================== End of the parameter list: EURUSD" (Euro vs US Dollar) ==================

Starten wir den EA auf dem Chart eines Symbols im MetaTrader 4.
Alle Eigenschaften des Symbolobjekts werden ins Journal geschrieben:

Account 49610941: Artyom Trishkin (MetaQuotes Software Corp. 5000000.00 USD, 1:100, Hedge, Demo account MetaTrader 4)
============= Beginning of the parameter list: "EURUSD" (Euro vs US Dollar) ==================
Status: Forex symbol
Custom symbol: No
The price type used for generating bars: Bars are based on Bid prices
The symbol under this name exists: Yes
The symbol is selected in Market Watch: Yes
The symbol is displayed in Market Watch: Yes
The number of deals in the current session: Property not supported in MQL4
The total number of Buy orders at the moment: Property not supported in MQL4
The total number of Sell orders at the moment: Property not supported in MQL4
Last deal volume: Property not supported in MQL4
Maximum volume within a day: Property not supported in MQL4
Minimum volume within a day: Property not supported in MQL4
Latest quote time: 2019.06.17 19:40:41.000
Number of decimal places: 5
Number of decimal places for a lot: 2
Spread in points: 20
Floating spread: Yes
Maximum number of orders displayed in the Depth of Market: Property not supported in MQL4
Contract price calculation method: Forex mode
Order execution type: No trade restrictions
Symbol trading start date: (Not set)
Symbol trading end date: (Not set)
Minimum distance in points from the current close price for setting Stop orders: 8
Freeze distance for trading operations: 0
Deal execution mode: Instant execution
Swap calculation model: Swaps are charged in points
Triple-day swap: Wednesday
Calculating hedging margin using the larger leg: No
Flags of allowed order expiration modes: Unlimited (Yes); Valid till the end of the day (No); Time is specified in the order (No); Date is specified in the order (No)
Flags of allowed order filling modes: Return (Yes); Fill or Kill (No); Immediate or Cancel (No)
Flags of allowed order types: Market order (Yes); Limit order (Yes); Stop order (Yes); Stop limit order (No); StopLoss (Yes); TakeProfit (Yes); Close by (Yes)
StopLoss and TakeProfit orders lifetime: Pending orders and Stop Loss/Take Profit levels are valid for an unlimited period until their explicit cancellation
Option type: Property not supported in MQL4
Option right: Property not supported in MQL4
The color of the background used for the symbol in Market Watch: Property not supported in MQL4
------
Bid price: 1.12328
The highest Bid price of the day: 1.12462
The lowest Bid price of the day: 1.12029
Ask price: 1.12348
The highest Ask price of the day: Property not supported in MQL4
The lowest Ask price of the day: Property not supported in MQL4
Last deal price: Property not supported in MQL4
The highest Last price of the day: Property not supported in MQL4
The lowest Last price of the day: Property not supported in MQL4
Volume of the day: Property not supported in MQL4
Maximum Volume of the day: Property not supported in MQL4
Minimum Volume of the day: Property not supported in MQL4
Option execution price: Property not supported in MQL4
Point value: 0.00001
Calculated tick value for a position: 1.00
Calculated tick value for a winning position: Property not supported in MQL4
Calculated tick value for a losing position: Property not supported in MQL4
Minimum price change: 0.00001
Trade contract size: 100000.00
Accrued interest: Property not supported in MQL4
Face value: Property not supported in MQL4
Liquidity rate: Property not supported in MQL4
Minimum volume for a deal: 0.01
Maximum volume for a deal: 100000.00
Minimum volume change step for a deal: 0.01
Maximum acceptable total volume of an open position and pending orders in one direction: Property not supported in MQL4
Long swap value: 0.33
Short swap value: -1.04
Initial margin: 0.00
Maintenance margin for an instrument: 0.00
Margin requirement applicable to long positions: Property not supported in MQL4
Margin requirement applicable to short positions: Property not supported in MQL4
Margin requirement applicable to Stop orders: Property not supported in MQL4
Margin requirement applicable to Limit orders: Property not supported in MQL4
Margin requirement applicable to Stop Limit orders: Property not supported in MQL4
The total volume of deals in the current session: Property not supported in MQL4
The total turnover in the current session: Property not supported in MQL4
The total volume of open positions: Property not supported in MQL4
The total volume of Buy orders at the moment: Property not supported in MQL4
EURUSD,H4: The total volume of Sell orders at the moment: Property not supported in MQL4
The open price of the session: Property not supported in MQL4
The close price of the session: Property not supported in MQL4
The average weighted price of the session: Property not supported in MQL4
The settlement price of the current session: Property not supported in MQL4
The minimum allowable price value for the session: Property not supported in MQL4
The maximum allowable price value for the session: Property not supported in MQL4
Size of a contract or margin for one lot of hedged positions: 50000.00
------
Symbol name: EURUSD
The name of the underlaying asset for a derivative symbol: ": Property not supported in MQL4"
The base currency of an instrument: "EUR"
Profit currency: "USD"
Margin currency: "EUR"
The source of the current quote: ": Property not supported in MQL4"
Symbol description: "Euro vs US Dollar"
The formula used for custom symbol pricing: ": Property not supported in MQL4"
The name of a trading symbol in the international system of securities identification numbers: ": Property not supported in MQL4"
The address of the web page containing symbol information: ": Property not supported in MQL4"
Path in the symbol tree: "Forex\EURUSD"
================== End of the parameter list: EURUSD" (Euro vs US Dollar) ==================

Im Gegensatz zum Start in MetaTrader 5 werden hier nicht alle Eigenschaften unterstützt. Daher gibt es entsprechende Meldungen im Journal. Die Liste der Flags wird in einer einzigen Zeile angezeigt, die bereits oben erwähnt wurde.
Im nächsten Artikel werden beim Erstellen von abgeleiteten Objekten keine Beschreibungszeilen für nicht unterstützte Eigenschaften angezeigt. Die Flags, die die Unterstützung bestimmter Eigenschaften durch das Objekt anzeigen, werden stattdessen für jedes abgeleitete Objekt gesetzt. Die Flags sind für jede Eigenschaft zu setzen.

Was kommt als Nächstes?

Im nächsten Artikel werden wir mit der Entwicklung der Klasse der Kollektion von Symbolen beginnen, die es den Nutzern ermöglicht, einfach nach Daten zu suchen sowie Symbole aus der Kollektionsliste zu sortieren und zu vergleichen.

Alle Dateien der aktuellen Version der Bibliothek sind unten zusammen mit den Dateien der Test-EAs angehängt, die Sie testen und herunterladen können.
Stellen Sie Ihre Fragen, Kommentare und Vorschläge in den Kommentaren.

Zurück zum Inhalt

Frühere Artikel dieser Serie:

Teil 1. Konzept, Datenverwaltung.
Teil 2. Erhebung (Collection) historischer Aufträge und Deals.
Teil 3. Erhebung (Collection) von Marktorders und Positionen, Organisieren der Suche
Teil 4. Handelsereignisse. Konzept
Teil 5. Klassen und Kollektionen von Handelsereignissen. Senden von Ereignissen an das Programm
Teil 6. Ereignisse auf Netting-Konten
Teil 7. Ereignis der Aktivierung einer StopLimit-Order, Vorbereiten der Funktionsweise bei Änderungen von Orders und Positionen
Teil 8. Ereignisse von Änderungen von Orders und Positionen
Teil 9. Kompatibilität mit MQL4 - Datenvorbereitung
Teil 10. Kompatibilität mit MQL4 - Ereignisse der Positionseröffnung und Aktivierung von Pending-Orders
Teil 11. Kompatibilität mit MQL4 - Ereignisse des Schließens von Positionen
Teil 12. Objektklasse "Account" und die Kollektion von Konto-Objekten
Teil 13. Das Objekt der Kontoereignisse