
MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第22部): 取引クラス - 基本取引クラス、制限の検証
内容
前の記事では、取引関数に特化した広範なライブラリセクションを開き、銘柄基本取引オブジェクトを作成しました。取引オブジェクトは、パラメータでサーバに送信された取引リクエストのすべてのプロパティを受信し、呼び出されたクラスメソッドの種類(ポジションを開く/指値注文を出す/変更/決済/削除)に従って取引リクエスト構造体に入力し、サーバに取引注文を送信します。取引リクエストプロパティの有効な値は、取引注文を送信するために基本取引オブジェクトに渡されます。ただし、取引オブジェクトを最大限に使用するには、まず、ターミナル、プログラム、口座、銘柄で取引操作を行うための既存の制限を確認する必要があります。これらの初期チェックに合格した後で、取引リクエストのプロパティを確認します。
本稿では、本格的な取引クラスの開発を開始します。最初に実装するのは、取引操作の制限の検証です。
概念
基本取引オブジェクトが既に存在します。このオブジェクトは銘柄オブジェクトの一部で、クラスメソッドの1つに渡されたパラメータに従って取引リクエスト構造体に入力し、サーバに取引注文を送信します。本格的な取引クラスを実装する前に、基本的な取引オブジェクト機能、つまり、取引注文の送信結果を音声で伝える機能を追加します。この機能では、取引イベントを通知する音声を設定できます。取引イベントのカスタム音声を銘柄ごとに設定することもできますが、もちろん、イベントごとにすべての銘柄に共通する音声を指定することもできます。すべての銘柄とイベントで同じ音を使用するかどうかに関係なく、基本取引オブジェクトには取引イベントの音を設定する十分な機会があります。
次に、すべての取引操作が行われる取引クラスを作成します。本稿では、取引操作の許可を確認し、必要な銘柄の基本取引オブジェクトの必要なメソッドを呼び出すという、クラスの最小限の機能を実装します。
基本取引オブジェクト機能の拡張
取引イベントに音声を割り当てるには、マクロ置換と列挙が必要です。Defines.mqhファイルを開いて、標準的音声ファイルを置き換えるマクロ置換を追加します。
//+------------------------------------------------------------------+ //| マクロ置換 | //+------------------------------------------------------------------+ //--- Describe the function with the error line number #define DFUN_ERR_LINE (__FUNCTION__+(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian" ? ", Page " : ", Line ")+(string)__LINE__+": ") #define DFUN (__FUNCTION__+": ") // "Function description" #define COUNTRY_LANG ("Russian") // Country language #define END_TIME (D'31.12.3000 23:59:59') // End date for account history data requests #define TIMER_FREQUENCY (16) // Minimal frequency of the library timer in milliseconds //--- Standard sounds #define SND_ALERT "alert.wav" #define SND_ALERT2 "alert2.wav" #define SND_CONNECT "connect.wav" #define SND_DISCONNECT "disconnect.wav" #define SND_EMAIL "email.wav" #define SND_EXPERT "expert.wav" #define SND_NEWS "news.wav" #define SND_OK "ok.wav" #define SND_REQUEST "request.wav" #define SND_STOPS "stops.wav" #define SND_TICK "tick.wav" #define SND_TIMEOUT "timeout.wav" #define SND_WAIT "wait.wav" //--- Parameters of the orders and deals collection timer
これにより、標準の音声ファイルを取引イベントを通知するための音声ファイルとして使用する場合に、設定する名前を指定する方が便利になります。
取引クラスを操作するためのデータブロック内のリストの後に、取引操作タイプの列挙と音声設定モードの列挙を追加します。
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Data for working with trading classes | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Logging level | //+------------------------------------------------------------------+ enum ENUM_LOG_LEVEL { LOG_LEVEL_NO_MSG, // Trading logging disabled LOG_LEVEL_ERROR_MSG, // Only trading errors LOG_LEVEL_ALL_MSG // Full logging }; //+------------------------------------------------------------------+ //| Types of performed operations | //+------------------------------------------------------------------+ enum ENUM_ACTION_TYPE { ACTION_TYPE_BUY = ORDER_TYPE_BUY, // Open Buy ACTION_TYPE_SELL = ORDER_TYPE_SELL, // Open Sell ACTION_TYPE_BUY_LIMIT = ORDER_TYPE_BUY_LIMIT, // Place BuyLimit ACTION_TYPE_SELL_LIMIT = ORDER_TYPE_SELL_LIMIT, // Place SellLimit ACTION_TYPE_BUY_STOP = ORDER_TYPE_BUY_STOP, // Place BuyStop ACTION_TYPE_SELL_STOP = ORDER_TYPE_SELL_STOP, // Place SellStop ACTION_TYPE_BUY_STOP_LIMIT = ORDER_TYPE_BUY_STOP_LIMIT, // Place BuyStopLimit ACTION_TYPE_SELL_STOP_LIMIT = ORDER_TYPE_SELL_STOP_LIMIT, // Place SellStopLimit ACTION_TYPE_CLOSE_BY = ORDER_TYPE_CLOSE_BY, // Close a position by an opposite one ACTION_TYPE_MODIFY = ACTION_TYPE_CLOSE_BY+1, // Modification }; //+------------------------------------------------------------------+ //| Sound setting mode | //+------------------------------------------------------------------+ enum ENUM_MODE_SET_SOUND { MODE_SET_SOUND_OPEN, // Opening/placing sound setting mode MODE_SET_SOUND_CLOSE, // Closing/removal sound setting mode MODE_SET_SOUND_MODIFY_SL, // StopLoss modification sound setting mode MODE_SET_SOUND_MODIFY_TP, // TakeProfit modification sound setting mode MODE_SET_SOUND_MODIFY_PRICE, // Placing price modification sound setting mode MODE_SET_SOUND_ERROR_OPEN, // Opening/placing error sound setting mode MODE_SET_SOUND_ERROR_CLOSE, // Closing/removal error sound setting mode MODE_SET_SOUND_ERROR_MODIFY_SL, // StopLoss modification error sound setting mode MODE_SET_SOUND_ERROR_MODIFY_TP, // TakeProfit modification error sound setting mode MODE_SET_SOUND_ERROR_MODIFY_PRICE, // Placing price modification error sound setting mode }; //+------------------------------------------------------------------+
ターミナルバージョン2155では、MQL5に新しい銘柄プロパティと口座プロパティが導入されました。
- MQL5: ENUM_SYMBOL_INFO_STRING列挙体に以下の値が追加されました。
- SYMBOL_CATEGORY — 銘柄カテゴリ。金融商品の追加マーキングに使用。例えば、これは銘柄が属する市場セクターである可能性があります(農業、石油およびガスなど)。
- SYMBOL_EXCHANGE — 銘柄が取引される取引所の名前。
- MQL5: FIFOルールによるポジション決済のサポートが追加されました。
- ACCOUNT_FIFO_CLOSE値がENUM_ACCOUNT_INFO_INTEGERに追加されました。これは、FIFOルールによってのみポジションを決済できることを示しています。プロパティ値がtrueの場合、各商品のポジションは、開かれたのと同じ順序でのみ決済することができます。最も古いものを最初に決済してから、次の商品を決済するなどです。別の順序でポジションを決済しようとすると、エラーが返されます。ポジション管理をヘッジしない口座のプロパティ値は常に「false」です(ACCOUNT_MARGIN_MODE!=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)。
- 新しい戻りコード:
MT_RET_REQUEST_CLOSE_ONLY — 銘柄に「FIFOルールによる既存のポジションの決済のみが許可されている」というルールが設定されているため、リクエストは拒否されます。
ポジションを決済するには、主に3つの方法があります。
- クライアントターミナルからの決済: トレーダーは、シグナルサービスのサブスクリプションなどに基づいて、自動売買ロボットを使用して手動でポジションを決済します。FIFOルールを満たさないポジションを決済しようとした場合、トレーダーは適切なエラーを受け取ります。
- ストップロスまたはテイクプロフィット発動による決済: これらの注文はサーバ側で処理されるため、ポジション決済はトレーダー(ターミナル)側からリクエストされるのではなく、サーバによって開始されます。ポジションのストップロスまたはテイクプロフィットが発動され、このポジションがFIFOルールに準拠していない場合(同じ銘柄に古いポジションが存在する場合)、そのポジションは決済されません。
- ストップアウトの発動による決済: このような操作はサーバ側で処理されます。FIFOベースの決済が無効になっている通常モードでは、ストップアウトポジションの場合、損失が最大のポジションから決済されます。このオプションが有効な場合、負けポジションではオープン時間がさら確認されます。サーバは、各銘柄の負けポジションを判断し、各銘柄の最も古いポジションを見つけ、見つかったポジションの中で最も損失が大きいポジションを決済します。
これをすべて考慮して、新しいプロパティが銘柄および口座オブジェクトに追加されました。
新しいプロパティが口座整数プロパティのブロックに追加され、整数プロパティの数が11になりました。
//+------------------------------------------------------------------+ //| Account integer properties | //+------------------------------------------------------------------+ enum ENUM_ACCOUNT_PROP_INTEGER { ACCOUNT_PROP_LOGIN, // Account number ACCOUNT_PROP_TRADE_MODE, // Trading account type ACCOUNT_PROP_LEVERAGE, // Leverage ACCOUNT_PROP_LIMIT_ORDERS, // Maximum allowed number of active pending orders ACCOUNT_PROP_MARGIN_SO_MODE, // Mode of setting the minimum available margin level ACCOUNT_PROP_TRADE_ALLOWED, // Permission to trade for the current account from the server side ACCOUNT_PROP_TRADE_EXPERT, // Permission to trade for an EA from the server side ACCOUNT_PROP_MARGIN_MODE, // Margin calculation mode ACCOUNT_PROP_CURRENCY_DIGITS, // Number of digits for an account currency necessary for accurate display of trading results ACCOUNT_PROP_SERVER_TYPE, // Trade server type (MetaTrader5, MetaTrader4) ACCOUNT_PROP_FIFO_CLOSE // Flag of a position closure by FIFO rule only }; #define ACCOUNT_PROP_INTEGER_TOTAL (11) // Total number of integer properties #define ACCOUNT_PROP_INTEGER_SKIP (0) // Number of integer account properties not used in sorting //+------------------------------------------------------------------+
整数プロパティによる新しい並び替え基準が口座並び替え基準のブロックに追加されました。
//+------------------------------------------------------------------+ //| Possible account sorting criteria | //+------------------------------------------------------------------+ #define FIRST_ACC_DBL_PROP (ACCOUNT_PROP_INTEGER_TOTAL-ACCOUNT_PROP_INTEGER_SKIP) #define FIRST_ACC_STR_PROP (ACCOUNT_PROP_INTEGER_TOTAL-ACCOUNT_PROP_INTEGER_SKIP+ACCOUNT_PROP_DOUBLE_TOTAL-ACCOUNT_PROP_DOUBLE_SKIP) enum ENUM_SORT_ACCOUNT_MODE { //--- 整数型プロパティによって並び替える SORT_BY_ACCOUNT_LOGIN = 0, // Sort by account number SORT_BY_ACCOUNT_TRADE_MODE, // Sort by trading account type SORT_BY_ACCOUNT_LEVERAGE, // Sort by leverage SORT_BY_ACCOUNT_LIMIT_ORDERS, // Sort by maximum acceptable number of existing pending orders SORT_BY_ACCOUNT_MARGIN_SO_MODE, // Sort by mode for setting the minimum acceptable margin level SORT_BY_ACCOUNT_TRADE_ALLOWED, // Sort by permission to trade for the current account SORT_BY_ACCOUNT_TRADE_EXPERT, // Sort by permission to trade for an EA SORT_BY_ACCOUNT_MARGIN_MODE, // Sort by margin calculation mode SORT_BY_ACCOUNT_CURRENCY_DIGITS, // Sort by number of digits for an account currency SORT_BY_ACCOUNT_SERVER_TYPE, // Sort by trade server type (MetaTrader5, MetaTrader4) SORT_BY_ACCOUNT_FIFO_CLOSE, // Sort by the flag of a position closure by FIFO rule only //--- 実数型プロパティによって並び替える
銘柄オブジェクトプロパティも同様の方法で追加されます。
文字列プロパティのブロックは2つの新しいプロパティを備えており、文字列プロパティの数が13に増加しました。
//+------------------------------------------------------------------+ //| Symbol string properties | //+------------------------------------------------------------------+ enum ENUM_SYMBOL_PROP_STRING { SYMBOL_PROP_NAME = (SYMBOL_PROP_INTEGER_TOTAL+SYMBOL_PROP_DOUBLE_TOTAL), // Symbol name SYMBOL_PROP_BASIS, // Name of the underlaying asset for a derivative symbol SYMBOL_PROP_CURRENCY_BASE, // Instrument base currency SYMBOL_PROP_CURRENCY_PROFIT, // Profit currency SYMBOL_PROP_CURRENCY_MARGIN, // Margin currency SYMBOL_PROP_BANK, // Source of the current quote SYMBOL_PROP_DESCRIPTION, // String description of a symbol SYMBOL_PROP_FORMULA, // The formula used for custom symbol pricing SYMBOL_PROP_ISIN, // The name of a trading symbol in the international system of securities identification numbers (ISIN) SYMBOL_PROP_PAGE, // The web page containing symbol information SYMBOL_PROP_PATH, // Location in the symbol tree SYMBOL_PROP_CATEGORY, // Symbol category SYMBOL_PROP_EXCHANGE // Name of an exchange a symbol is traded on }; #define SYMBOL_PROP_STRING_TOTAL (13) // Total number of string properties //+------------------------------------------------------------------+
銘柄文字列プロパティによる2つの新しい並び替え基準が、可能な銘柄並び替え基準のリストに追加されました。
//--- 文字列型プロパティによって並び替える SORT_BY_SYMBOL_NAME = FIRST_SYM_STR_PROP, // Sort by a symbol name SORT_BY_SYMBOL_BASIS, // Sort by an underlying asset of a derivative SORT_BY_SYMBOL_CURRENCY_BASE, // Sort by a base currency of a symbol SORT_BY_SYMBOL_CURRENCY_PROFIT, // Sort by a profit currency SORT_BY_SYMBOL_CURRENCY_MARGIN, // Sort by a margin currency SORT_BY_SYMBOL_BANK, // Sort by a feeder of the current quote SORT_BY_SYMBOL_DESCRIPTION, // Sort by a symbol string description SORT_BY_SYMBOL_FORMULA, // Sort by the formula used for custom symbol pricing SORT_BY_SYMBOL_ISIN, // Sort by the name of a symbol in the ISIN system SORT_BY_SYMBOL_PAGE, // Sort by an address of the web page containing symbol information SORT_BY_SYMBOL_PATH, // Sort by a path in the symbol tree SORT_BY_SYMBOL_CATEGORY, // Sort by symbol category SORT_BY_SYMBOL_EXCHANGE // Sort by a name of an exchange a symbol is traded on }; //+------------------------------------------------------------------+
また、オブジェクト、クラス、メソッドの新しいプロパティを操作するために、ライブラリテキストメッセージインデックスの新しい定数がいくつか追加されました。
Datas.mqhファイルでの新しい定数を見てみましょう。
//+------------------------------------------------------------------+ //| List of the library's text message indices | //+------------------------------------------------------------------+ enum ENUM_MESSAGES_LIB { MSG_LIB_PARAMS_LIST_BEG=ERR_USER_ERROR_FIRST, // Beginning of the parameter list MSG_LIB_PARAMS_LIST_END, // End of the parameter list MSG_LIB_PROP_NOT_SUPPORTED, // Property not supported MSG_LIB_PROP_NOT_SUPPORTED_MQL4, // Property not supported in MQL4 MSG_LIB_PROP_NOT_SUPPORTED_MT5_LESS_2155, // Property not supported in MetaTrader 5 versions lower than 2155 MSG_LIB_PROP_NOT_SUPPORTED_POSITION, // Property not supported for position MSG_LIB_PROP_NOT_SUPPORTED_PENDING, // Property not supported for pending order MSG_LIB_PROP_NOT_SUPPORTED_MARKET, // Property not supported for market order MSG_LIB_PROP_NOT_SUPPORTED_MARKET_HIST, // Property not supported for historical market order MSG_LIB_PROP_NOT_SET, // Value not set MSG_LIB_PROP_EMPTY, // Not set MSG_LIB_SYS_ERROR, // Error MSG_LIB_SYS_NOT_SYMBOL_ON_SERVER, // Error. No such symbol on server MSG_LIB_SYS_NOT_SYMBOL_ON_LIST, // Error. No such symbol in the list of used symbols: MSG_LIB_SYS_FAILED_PUT_SYMBOL, // Failed to place to market watch. Error: MSG_LIB_SYS_NOT_GET_PRICE, // Failed to get current prices. Error: MSG_LIB_SYS_NOT_GET_MARGIN_RATES, // Failed to get margin ratios. Error: MSG_LIB_SYS_NOT_GET_DATAS, // Failed to get data MSG_LIB_SYS_FAILED_CREATE_STORAGE_FOLDER, // Failed to create folder for storing files. Error: MSG_LIB_SYS_FAILED_ADD_ACC_OBJ_TO_LIST, // Error. Failed to add current account object to collection list MSG_LIB_SYS_FAILED_CREATE_CURR_ACC_OBJ, // Error. Failed to create account object with current account data MSG_LIB_SYS_FAILED_OPEN_FILE_FOR_WRITE, // Could not open file for writing MSG_LIB_SYS_INPUT_ERROR_NO_SYMBOL, // Input error: no symbol MSG_LIB_SYS_FAILED_CREATE_SYM_OBJ, // Failed to create symbol object MSG_LIB_SYS_FAILED_ADD_SYM_OBJ, // Failed to add symbol MSG_LIB_SYS_NOT_GET_CURR_PRICES, // Failed to get current prices by event symbol MSG_LIB_SYS_EVENT_ALREADY_IN_LIST, // This event is already in the list MSG_LIB_SYS_FILE_RES_ALREADY_IN_LIST, // This file already created and added to list: MSG_LIB_SYS_FAILED_CREATE_RES_LINK, // Error. Failed to create object pointing to resource file MSG_LIB_SYS_ERROR_ALREADY_CREATED_COUNTER, // Error. Counter with ID already created MSG_LIB_SYS_FAILED_CREATE_COUNTER, // Failed to create timer counter MSG_LIB_SYS_FAILED_CREATE_TEMP_LIST, // Error creating temporary list MSG_LIB_SYS_ERROR_NOT_MARKET_LIST, // Error. This is not a market collection list MSG_LIB_SYS_ERROR_NOT_HISTORY_LIST, // Error. This is not a history collection list MSG_LIB_SYS_FAILED_ADD_ORDER_TO_LIST, // Could not add order to the list MSG_LIB_SYS_FAILED_ADD_DEAL_TO_LIST, // Could not add deal to the list MSG_LIB_SYS_FAILED_ADD_CTRL_ORDER_TO_LIST, // Failed to add control order MSG_LIB_SYS_FAILED_ADD_CTRL_POSITION_TO_LIST, // Failed to add control position MSG_LIB_SYS_FAILED_ADD_MODIFIED_ORD_TO_LIST, // Could not add modified order to the list of modified orders MSG_LIB_SYS_FAILED_CREATE_TIMER, // Failed to create timer. Error: MSG_LIB_SYS_NO_TICKS_YET, // No ticks yet MSG_LIB_SYS_FAILED_CREATE_OBJ_STRUCT, // Could not create object structure MSG_LIB_SYS_FAILED_WRITE_UARRAY_TO_FILE, // Could not write uchar array to file MSG_LIB_SYS_FAILED_LOAD_UARRAY_FROM_FILE, // Could not load uchar array from file MSG_LIB_SYS_FAILED_CREATE_OBJ_STRUCT_FROM_UARRAY, // Could not create object structure from uchar array MSG_LIB_SYS_FAILED_SAVE_OBJ_STRUCT_TO_UARRAY, // Failed to save object structure to uchar array, error MSG_LIB_SYS_ERROR_INDEX, // Error. "index" value should be within 0 - 3 MSG_LIB_SYS_ERROR_FAILED_CONV_TO_LOWERCASE, // Failed to convert string to lowercase, error //--- COrder MSG_ORD_BUY, // Buy MSG_ORD_SELL, // Sell MSG_ORD_TO_BUY, // Buy order MSG_ORD_TO_SELL, // Sell order MSG_DEAL_TO_BUY, // Buy deal MSG_DEAL_TO_SELL, // Sell deal MSG_ORD_MARKET, // Market order MSG_ORD_HISTORY, // Historical order MSG_ORD_DEAL, // Deal MSG_ORD_POSITION, // Position MSG_ORD_PENDING_ACTIVE, // Active pending order MSG_ORD_PENDING, // Pending order MSG_ORD_UNKNOWN_TYPE, // Unknown order type MSG_POS_UNKNOWN_TYPE, // Unknown position type MSG_POS_UNKNOWN_DEAL, // Unknown deal type //--- //--- MSG_SYM_PROP_NAME, // Symbol name MSG_SYM_PROP_BASIS, // Underlying asset of derivative MSG_SYM_PROP_CURRENCY_BASE, // Basic currency of symbol MSG_SYM_PROP_CURRENCY_PROFIT, // Profit currency MSG_SYM_PROP_CURRENCY_MARGIN, // Margin currency MSG_SYM_PROP_BANK, // Feeder of the current quote MSG_SYM_PROP_DESCRIPTION, // Symbol description MSG_SYM_PROP_FORMULA, // Formula used for custom symbol pricing MSG_SYM_PROP_ISIN, // Symbol name in ISIN system MSG_SYM_PROP_PAGE, // Address of web page containing symbol information MSG_SYM_PROP_PATH, // Location in symbol tree MSG_SYM_PROP_CAYEGORY, // Symbol category MSG_SYM_PROP_EXCHANGE, // Name of an exchange a symbol is traded on //--- //--- MSG_SYM_TRADE_MODE_DISABLED, // Trade disabled for symbol MSG_SYM_TRADE_MODE_LONGONLY, // Only long positions allowed MSG_SYM_TRADE_MODE_SHORTONLY, // Only short positions allowed MSG_SYM_TRADE_MODE_CLOSEONLY, // Enable close only MSG_SYM_TRADE_MODE_FULL, // No trading limitations MSG_SYM_MARKET_ORDER_DISABLED, // Market orders disabled MSG_SYM_LIMIT_ORDER_DISABLED, // Limit orders disabled MSG_SYM_STOP_ORDER_DISABLED, // Stop orders disabled MSG_SYM_STOP_LIMIT_ORDER_DISABLED, // StopLimit orders disabled MSG_SYM_SL_ORDER_DISABLED, // StopLoss orders disabled MSG_SYM_TP_ORDER_DISABLED, // TakeProfit orders disabled MSG_SYM_CLOSE_BY_ORDER_DISABLED, // CloseBy orders disabled //--- //--- CAccount MSG_ACC_PROP_LOGIN, // Account number MSG_ACC_PROP_TRADE_MODE, // Trading account type MSG_ACC_PROP_LEVERAGE, // Leverage MSG_ACC_PROP_LIMIT_ORDERS, // Maximum allowed number of active pending orders MSG_ACC_PROP_MARGIN_SO_MODE, // Mode of setting the minimum available margin level MSG_ACC_PROP_TRADE_ALLOWED, // Trading permission of the current account MSG_ACC_PROP_TRADE_EXPERT, // Trading permission of an EA MSG_ACC_PROP_MARGIN_MODE, // Margin calculation mode MSG_ACC_PROP_CURRENCY_DIGITS, // Number of decimal places for the account currency MSG_ACC_PROP_SERVER_TYPE, // Trade server type MSG_ACC_PROP_FIFO_CLOSE, // Flag of a position closure by FIFO rule only //--- //--- CTrading MSG_LIB_TEXT_TERMINAL_NOT_TRADE_ENABLED, // Trade operations are not allowed in the terminal (the AutoTrading button is disabled) MSG_LIB_TEXT_EA_NOT_TRADE_ENABLED, // EA is not allowed to trade (F7 --> Common --> Allow Automated Trading) MSG_LIB_TEXT_ACCOUNT_NOT_TRADE_ENABLED, // Trading is disabled for the current account MSG_LIB_TEXT_ACCOUNT_EA_NOT_TRADE_ENABLED, // Trading on the trading server side is disabled for EAs on the current account MSG_LIB_TEXT_TERMINAL_NOT_CONNECTED, // No connection to the trade server MSG_LIB_TEXT_REQUEST_REJECTED_DUE, // Request was rejected before sending to the server due to: MSG_LIB_TEXT_NOT_ENOUTH_MONEY_FOR, // Insufficient funds for opening a position: MSG_LIB_TEXT_MAX_VOLUME_LIMIT_EXCEEDED, // Exceeded maximum allowed aggregate volume of orders and positions in one direction MSG_LIB_TEXT_REQ_VOL_LESS_MIN_VOLUME, // Request volume is less than the minimum acceptable one MSG_LIB_TEXT_REQ_VOL_MORE_MAX_VOLUME, // Request volume exceeds the maximum acceptable one MSG_LIB_TEXT_CLOSE_BY_ORDERS_DISABLED, // Close by is disabled MSG_LIB_TEXT_INVALID_VOLUME_STEP, // Request volume is not a multiple of the minimum lot change step gradation MSG_LIB_TEXT_CLOSE_BY_SYMBOLS_UNEQUAL, // Symbols of opposite positions are not equal };
次に、テキストメッセージ配列に宣言された定数に対応するテキストを追加します。
//+------------------------------------------------------------------+ //| Array of predefined library messages | //| (1) in user's country language | //| (2) in the international language (English) | //| (3) any additional language. | //| The default languages are English and Russian. | //| To add the necessary number of other languages, simply | //| set the total number of used languages in TOTAL_LANG | //| and add the necessary translation after the English text | //+------------------------------------------------------------------+ string messages_library[][TOTAL_LANG]= { {"Начало списка параметров","Beginning of event parameter list"}, {"Конец списка параметров","End of parameter list"}, {"Свойство не поддерживается","Property not supported"}, {"Свойство не поддерживается в MQL4","Property not supported in MQL4"}, {"Свойство не поддерживается в MetaTrader5 версии ниже 2155","Property not supported in MetaTrader 5, build lower than 2155"}, {"Свойство не поддерживается у позиции","Property not supported for position"}, {"Свойство не поддерживается у отложенного ордера","Property not supported for pending order"}, {"Свойство не поддерживается у маркет-ордера","Property not supported for market order"}, {"Свойство не поддерживается у исторического маркет-ордера","Property not supported for historical market order"}, {"Значение не задано","Value not set"}, {"Отсутствует","Not set"}, {"Ошибка ","Error "}, {"Ошибка. Такого символа нет на сервере","Error. No such symbol on server"}, {"Ошибка. Такого символа нет в списке используемых символов: ","Error. This symbol is not in the list of symbols used: "}, {"Не удалось поместить в обзор рынка. Ошибка: ","Failed to put in market watch. Error: "}, {"Не удалось получить текущие цены. Ошибка: ","Could not get current prices. Error: "}, {"Не удалось получить коэффициенты взимания маржи. Ошибка: ","Failed to get margin rates. Error: "}, {"Не удалось получить данные ","Failed to get data of "}, {"Не удалось создать папку хранения файлов. Ошибка: ","Could not create file storage folder. Error: "}, {"Ошибка. Не удалось добавить текущий объект-аккаунт в список-коллекцию","Error. Failed to add current account object to collection list"}, {"Ошибка. Не удалось создать объект-аккаунт с данными текущего счёта","Error. Failed to create account object with current account data"}, {"Не удалось открыть для записи файл ","Could not open file for writing: "}, {"Ошибка входных данных: нет символа ","Input error: no "}, {"Не удалось создать объект-символ ","Failed to create symbol object "}, {"Не удалось добавить символ ","Failed to add "}, {"Не удалось получить текущие цены по символу события ","Failed to get current prices by event symbol "}, {"Такое событие уже есть в списке","This event already in the list"}, {"Такой файл уже создан и добавлен в список: ","This file has already been created and added to list: "}, {"Ошибка. Не удалось создать объект-указатель на файл ресурса","Error. Failed to create resource file link object"}, {"Ошибка. Уже создан счётчик с идентификатором ","Error. Already created counter with id "}, {"Не удалось создать счётчик таймера ","Failed to create timer counter "}, {"Ошибка создания временного списка","Error creating temporary list"}, {"Ошибка. Список не является списком рыночной коллекции","Error. The list is not a list of market collection"}, {"Ошибка. Список не является списком исторической коллекции","Error. The list is not a list of history collection"}, {"Не удалось добавить ордер в список","Could not add order to list"}, {"Не удалось добавить сделку в список","Could not add deal to list"}, {"Не удалось добавить контрольный ордер ","Failed to add control order "}, {"Не удалось добавить контрольую позицию ","Failed to add control position "}, {"Не удалось добавить модифицированный ордер в список изменённых ордеров","Could not add modified order to list of modified orders"}, {"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: "}, //--- COrder {"Buy","Buy"}, {"Sell","Sell"}, {"Ордер на покупку","Buy order"}, {"Ордер на продажу","Sell order"}, {"Сделка на покупку","Buy deal"}, {"Сделка на продажу","Sell deal"}, {"Маркет-ордер","Market order"}, {"Исторический ордер","History order"}, {"Сделка","Deal"}, {"Позиция","Active position"}, {"Установленный отложенный ордер","Active pending order"}, {"Отложенный ордер","Pending order"}, {"Неизвестный тип ордера","Unknown order type"}, {"Неизвестный тип позиции","Unknown position type"}, {"Неизвестный тип сделки","Unknown deal type"}, //--- {"Путь в дереве символов","Path in symbol tree"}, {"Название категории или сектора, к которой принадлежит торговый символ","Name of sector or category trading symbol belongs to"}, {"Название биржи или площадки, на которой торгуется символ","Name of exchange financial symbol traded in"}, //--- {"Форекс символ","Forex symbol"}, {"Разрешены только операции закрытия позиций","Close only"}, {"Нет ограничений на торговые операции","No trade restrictions"}, {"Торговля рыночными ордерами запрещена","Trading through market orders prohibited"}, {"Установка Limit-ордеров запрещена","Limit orders prohibited"}, {"Установка Stop-ордеров запрещена","Stop orders prohibited"}, {"Установка StopLimit-ордеров запрещена","StopLimit orders prohibited"}, {"Установка StopLoss-ордеров запрещена","StopLoss orders prohibited"}, {"Установка TakeProfit-ордеров запрещена","TakeProfit orders prohibited"}, {"Установка CloseBy-ордеров запрещена","CloseBy orders prohibited"}, //--- {"Торговля по запросу","Execution by request"}, {"Торговля по потоковым ценам","Instant execution"}, {"Исполнение ордеров по рынку","Market execution"}, {"Биржевое исполнение","Exchange execution"}, //--- //--- CAccount {"Номер счёта","Account number"}, {"Тип торгового счета","Account trade mode"}, {"Размер предоставленного плеча","Account leverage"}, {"Максимально допустимое количество действующих отложенных ордеров","Maximum allowed number of active pending orders"}, {"Режим задания минимально допустимого уровня залоговых средств","Mode for setting minimal allowed margin"}, {"Разрешенность торговли для текущего счета","Allowed trade for the current account"}, {"Разрешенность торговли для эксперта","Allowed trade for Expert Advisor"}, {"Режим расчета маржи","Margin calculation mode"}, {"Количество знаков после запятой для валюты счета","Number of decimal places in account currency"}, {"Тип торгового сервера","Type of trading server"}, {"Признак закрытия позиций только по правилу FIFO","Sign of closing positions only according to FIFO rule"}, //--- {"Баланс счета","Account balance"}, //--- CEngine {"С момента последнего запуска ЕА торговых событий не было","No trade events since the last launch of EA"}, {"Не удалось получить описание последнего торгового события","Failed to get description of the last trading event"}, {"Не удалось получить список открытых позиций","Failed to get open positions list"}, {"Не удалось получить список установленных ордеров","Failed to get pending orders list"}, {"Нет открытых позиций","No open positions"}, {"Нет установленных ордеров","No placed orders"}, {"В терминале нет разрешения на проведение торговых операций (отключена кнопка \"Авто-торговля\")","No permission to conduct trading operations in terminal (\"AutoTrading\" button disabled)"}, {"Для советника нет разрешения на проведение торговых операций (F7 --> Общие --> \"Разрешить автоматическую торговлю\")","EA does not have permission to conduct trading operations (F7 --> Common --> \"Allow Automatic Trading\")"}, {"Для текущего счёта запрещена торговля","Trading prohibited for the current account"}, {"Для советников на текущем счёте запрещена торговля на стороне торгового сервера","From the side of trade server, trading for EA on the current account prohibited"}, {"Нет связи с торговым сервером","No connection to trade server"}, {"Запрос отклонён до отправки на сервер по причине:","Request rejected before being sent to server due to:"}, {"Не хватает средств на открытие позиции: ","Not enough money to open position: "}, {"Превышен максимальный совокупный объём ордеров и позиций в одном направлении","Exceeded maximum total volume of orders and positions in one direction"}, {"Объём в запросе меньше минимально-допустимого","Volume in request less than minimum allowable"}, {"Объём в запросе больше максимально-допустимого","Volume in request greater than maximum allowable"}, {"Закрытие встречным запрещено","CloseBy orders prohibited"}, {"Объём в запросе не кратен минимальной градации шага изменения лота","Volume in request not a multiple of minimum gradation of step for changing lot"}, {"Символы встречных позиций не равны","Symbols of two opposite positions not equal"}, }; //+---------------------------------------------------------------------+ //| Array of messages for trade server return codes (10004 - 10045) | //| (1) in user's country language | //| (2) in the international language | //+---------------------------------------------------------------------+ string messages_ts_ret_code[][TOTAL_LANG]= { {"Реквота","Requote"}, // 10004 {"Неизвестный код возврата торгового сервера","Unknown trading server return code"}, // 10005 {"Запрос отклонен","Request rejected"}, // 10006 {"Запрос отменен трейдером","Request canceled by trader"}, // 10007 {"Ордер размещен","Order placed"}, // 10008 {"Заявка выполнена","Request completed"}, // 10009 {"Заявка выполнена частично","Only part of request completed"}, // 10010 {"Ошибка обработки запроса","Request processing error"}, // 10011 {"Запрос отменен по истечению времени","Request canceled by timeout"}, // 10012 {"Неправильный запрос","Invalid request"}, // 10013 {"Неправильный объем в запросе","Invalid volume in request"}, // 10014 {"Неправильная цена в запросе","Invalid price in request"}, // 10015 {"Неправильные стопы в запросе","Invalid stops in request"}, // 10016 {"Торговля запрещена","Trading disabled"}, // 10017 {"Рынок закрыт","Market closed"}, // 10018 {"Нет достаточных денежных средств для выполнения запроса","Not enough money to complete request"}, // 10019 {"Цены изменились","Prices changed"}, // 10020 {"Отсутствуют котировки для обработки запроса","No quotes to process request"}, // 10021 {"Неверная дата истечения ордера в запросе","Invalid order expiration date in request"}, // 10022 {"Состояние ордера изменилось","Order state changed"}, // 10023 {"Слишком частые запросы","Too frequent requests"}, // 10024 {"В запросе нет изменений","No changes in request"}, // 10025 {"Автотрейдинг запрещен сервером","Autotrading disabled by server"}, // 10026 {"Автотрейдинг запрещен клиентским терминалом","Autotrading disabled by client terminal"}, // 10027 {"Запрос заблокирован для обработки","Request locked for processing"}, // 10028 {"Ордер или позиция заморожены","Order or position frozen"}, // 10029 {"Указан неподдерживаемый тип исполнения ордера по остатку","Invalid order filling type"}, // 10030 {"Нет соединения с торговым сервером","No connection with trade server"}, // 10031 {"Операция разрешена только для реальных счетов","Operation allowed only for live accounts"}, // 10032 {"Достигнут лимит на количество отложенных ордеров","Number of pending orders reached limit"}, // 10033 {"Достигнут лимит на объем ордеров и позиций для данного символа","Volume of orders and positions for symbol reached limit"}, // 10034 {"Неверный или запрещённый тип ордера","Incorrect or prohibited order type"}, // 10035 {"Позиция с указанным идентификатором уже закрыта","Position with specified identifier already closed"}, // 10036 {"Неизвестный код возврата торгового сервера","Unknown trading server return code"}, // 10037 {"Закрываемый объем превышает текущий объем позиции","Close volume exceeds the current position volume"}, // 10038 {"Для указанной позиции уже есть ордер на закрытие","Close order already exists for specified position"}, // 10039 {"Достигнут лимит на количество открытых позиций","Number of positions reached limit"}, // 10040 { "Запрос на активацию отложенного ордера отклонен, а сам ордер отменен", // 10041 "Pending order activation request rejected, order canceled" }, { "Запрос отклонен, так как на символе установлено правило \"Разрешены только длинные позиции\"", // 10042 "Request rejected, because \"Only long positions are allowed\" rule set for symbol" }, { "Запрос отклонен, так как на символе установлено правило \"Разрешены только короткие позиции\"", // 10043 "Request rejected, because \"Only short positions are allowed\" rule set for symbol" }, { "Запрос отклонен, так как на символе установлено правило \"Разрешено только закрывать существующие позиции\"", // 10044 "Request rejected because \"Only position closing is allowed\" rule set for symbol" }, { "Запрос отклонен, так как для торгового счета установлено правило \"Разрешено закрывать существующие позиции только по правилу FIFO\"", // 10045 "Request rejected, because \"Position closing is allowed only by FIFO rule\" flag set for trading account" }, }; //+------------------------------------------------------------------+
すでにお分かりのように、実行されたすべてのアクションは、ライブラリに新しいメッセージを追加し、メッセージ定数に記述されたインデックスによってメッセージにアクセスすることを目的としています。
ここで、\MQL5\Include\DoEasy\Services\Message.mqhにあるメッセージクラスを改善しましょう。
クラスのpublicセクションで、音声ファイルの再生を停止するメソッドを宣言します。
public: //--- (1) Display a text message in the journal, send a push notification and e-mail, //--- (2) Display a message by ID, send a push notification and e-mail, //--- (3) play an audio file //--- (4) Stop playing any sound static bool Out(const string text,const bool push=false,const bool mail=false,const string subject=NULL); static bool OutByID(const int msg_id,const bool code=true); static bool PlaySound(const string file_name); static bool StopPlaySound(void); //--- Return (1) a message, (2) a code in the "(code)" format
クラス本体の外側で実装します。
//+------------------------------------------------------------------+ //| Stop playing any sound | //+------------------------------------------------------------------+ bool CMessage::StopPlaySound(void) { bool res=::PlaySound(NULL); CMessage::m_global_error=(res ? ERR_SUCCESS : ::GetLastError()); return res; } //+------------------------------------------------------------------+
ここではすべてが簡単です。NULL定数をファイル名として渡すと、 PlaySound()標準関数は現在アクティブな音声ファイルの再生を停止します。
ターミナル配信に含まれる標準の音声ファイルを再生できるようにするには、ファイル名(ファイルの標準の場所: terminal_folder\Soundsから音声を再生する)を指定するか、
二重スラッシュと非標準の音声ファイルを格納するサブフォルダを含むプレフィックスを指定します。
よって、PlaySound()メソッドを改善します。
//+------------------------------------------------------------------+ //| Play an audio file | //+------------------------------------------------------------------+ bool CMessage::PlaySound(const string file_name) { if(file_name==NULL) return true; string pref=(file_name==SND_ALERT || file_name==SND_ALERT2 || file_name==SND_CONNECT || file_name==SND_DISCONNECT || file_name==SND_EMAIL || file_name==SND_EXPERT || file_name==SND_NEWS || file_name==SND_OK || file_name==SND_REQUEST || file_name==SND_STOPS || file_name==SND_TICK || file_name==SND_TIMEOUT || file_name==SND_WAIT ? "" : "\\Files\\"); bool res=::PlaySound(pref+file_name); CMessage::m_global_error=(res ? ERR_SUCCESS : ::GetLastError()); return res; } //+------------------------------------------------------------------+
まとめてみましょう。
ファイル名が標準音声ファイルの名前を含む場合、ファイル名のプレフィックスに空の文字列を書き込みます。
そのほかの場合、二重スラッシュとライブラリ音声を含むサブフォルダの名前とをプレフィックスに追加します。
その場合、ファイル名は、プレフィックスとメソッドに渡される名前で構成されます。PlaySound()に名前を渡すとき、音声ファイルの場所が自動的に選択され(標準の音声フォルダまたはライブラリ音声ファイルフォルダ)、適切なファイルが再生されます。
これで、新しい取引サーバの戻りコードができました。IDによってテキスト配列からメッセージを受信するメソッド(void CMessage::GetTextByID()) サーバ戻りコードの上限に1を追加して変更します(10044->10045)。
//--- Runtime errors (Economic calendar 5400 - 5402) msg_id>5399 && msg_id<5403 ? messages_runtime_calendar[msg_id-5400][m_lang_num] : //--- Trade server return codes (10004 - 10045) msg_id>10003 && msg_id<10046 ? messages_ts_ret_code[msg_id-10004][m_lang_num] : #else // MQL4 msg_id>0 && msg_id<10 ? messages_ts_ret_code_mql4[msg_id][m_lang_num] : msg_id>63 && msg_id<66 ? messages_ts_ret_code_mql4[msg_id-54][m_lang_num] : msg_id>127 && msg_id<151 ? messages_ts_ret_code_mql4[msg_id-116][m_lang_num] : msg_id<4000 ? messages_ts_ret_code_mql4[26][m_lang_num] : //--- MQL4 runtime errors (4000 - 4030) msg_id<4031 ? messages_runtime_4000_4030[msg_id-4000][m_lang_num] : //--- MQL4 runtime errors (4050 - 4075) msg_id>4049 && msg_id<4076 ? messages_runtime_4050_4075[msg_id-4050][m_lang_num] : //--- MQL4 runtime errors (4099 - 4112) msg_id>4098 && msg_id<4113 ? messages_runtime_4099_4112[msg_id-4099][m_lang_num] : //--- MQL4 runtime errors (4200 - 4220) msg_id>4199 && msg_id<4221 ? messages_runtime_4200_4220[msg_id-4200][m_lang_num] : //--- MQL4 runtime errors (4250 - 4266) msg_id>4249 && msg_id<4267 ? messages_runtime_4250_4266[msg_id-4250][m_lang_num] : //--- MQL4 runtime errors (5001 - 5029) msg_id>5000 && msg_id<5030 ? messages_runtime_5001_5029[msg_id-5001][m_lang_num] : //--- MQL4 runtime errors (5200 - 5203) msg_id>5199 && msg_id<5204 ? messages_runtime_5200_5203[msg_id-5200][m_lang_num] : #endif //--- Library messages (ERR_USER_ERROR_FIRST) msg_id>ERR_USER_ERROR_FIRST-1 ? messages_library[msg_id-ERR_USER_ERROR_FIRST][m_lang_num] : messages_library[MSG_LIB_SYS_ERROR_CODE_OUT_OF_RANGE-ERR_USER_ERROR_FIRST][m_lang_num] );
これで、ライブラリメッセージクラスの変更は完成です。
場合によっては、注文がアクティブになったときに注文の種類を使用してポジションの方向を見つける必要があります。ORDER_TYPE_BUY_LIMIT型の指値注文を設定するとします。注文が発動するとすぐに、ORDER_TYPE_BUY成行注文が出され、DEAL_TYPE_BUY型のDEAL_ENTRY_IN取引が行われます。取引は、POSITION_TYPE_BUY型のポジションにつながります。
未決注文の型によってポジションの方向を確認するには、成行注文型を受け取る必要があります(現在の例ではORDER_TYPE_BUYです)。
以前は、未決注文の型と比較しながら、三項演算子を使用して定義していたのですが、これは、確認された注文の型を2で割って超過分を単純に取得することによって、より簡単に行うことができます。0型(ORDER_TYPE_BUY)は常に偶数の注文に対して返され、1型(ORDER_TYPE_SELL)は奇数の注文に対して返されます。いくつかの関数とメソッドでそれを実装しました。
(\MQL5\Include\DoEasy\Objects\Orders\Order.mqh)抽象注文クラスでは、以下のようになります。
//+------------------------------------------------------------------+ //| 方向別に型を返す | //+------------------------------------------------------------------+ long COrder::OrderTypeByDirection(void) const { ENUM_ORDER_STATUS status=(ENUM_ORDER_STATUS)this.GetProperty(ORDER_PROP_STATUS); if(status==ORDER_STATUS_MARKET_POSITION) { return (ENUM_ORDER_TYPE)this.OrderType(); } else if(status==ORDER_STATUS_MARKET_PENDING || status==ORDER_STATUS_HISTORY_PENDING) { return ENUM_ORDER_TYPE(this.OrderType()%2); } else if(status==ORDER_STATUS_MARKET_ORDER || status==ORDER_STATUS_HISTORY_ORDER) { return this.OrderType(); } else if(status==ORDER_STATUS_DEAL) { return ( (ENUM_DEAL_TYPE)this.TypeOrder()==DEAL_TYPE_BUY ? ORDER_TYPE_BUY : (ENUM_DEAL_TYPE)this.TypeOrder()==DEAL_TYPE_SELL ? ORDER_TYPE_SELL : WRONG_VALUE ); } return WRONG_VALUE; } //+------------------------------------------------------------------+
サービス関数のライブラリ(\MQL5\Include\DoEasy\Services\DELib.mqh)では、以下のようになります。
//+------------------------------------------------------------------+ //| Return position type by order type | //+------------------------------------------------------------------+ ENUM_POSITION_TYPE PositionTypeByOrderType(ENUM_ORDER_TYPE type_order) { if(type_order==ORDER_TYPE_CLOSE_BY) return WRONG_VALUE; return ENUM_POSITION_TYPE(type_order%2); } //+------------------------------------------------------------------+
注文名を返す関数も、サービス関数の同じファイルで変更されました。注文の説明を表示するかどうかを示すフラグが追加されました。フラグに応じて、返された成行注文型は、これが成行注文であるという説明を受け取るか、何も受け取りません。返された未決注文型に注文型の説明が追加されました。
//+------------------------------------------------------------------+ //| Return the order name | //+------------------------------------------------------------------+ string OrderTypeDescription(const ENUM_ORDER_TYPE type,bool as_order=true,bool need_prefix=true) { string pref= ( !need_prefix ? "" : #ifdef __MQL5__ CMessage::Text(MSG_ORD_MARKET) #else/*__MQL4__*/(as_order ? CMessage::Text(MSG_ORD_MARKET) : CMessage::Text(MSG_ORD_POSITION)) #endif ); return ( type==ORDER_TYPE_BUY_LIMIT ? CMessage::Text(MSG_ORD_PENDING)+" Buy Limit" : type==ORDER_TYPE_BUY_STOP ? CMessage::Text(MSG_ORD_PENDING)+" Buy Stop" : type==ORDER_TYPE_SELL_LIMIT ? CMessage::Text(MSG_ORD_PENDING)+" Sell Limit" : type==ORDER_TYPE_SELL_STOP ? CMessage::Text(MSG_ORD_PENDING)+" Sell Stop" : #ifdef __MQL5__ type==ORDER_TYPE_BUY_STOP_LIMIT ? CMessage::Text(MSG_ORD_PENDING)+" Buy Stop Limit" : type==ORDER_TYPE_SELL_STOP_LIMIT ? CMessage::Text(MSG_ORD_PENDING)+" Sell Stop Limit" : type==ORDER_TYPE_CLOSE_BY ? CMessage::Text(MSG_ORD_CLOSE_BY) : #else type==ORDER_TYPE_BALANCE ? CMessage::Text(MSG_LIB_PROP_BALANCE) : type==ORDER_TYPE_CREDIT ? CMessage::Text(MSG_LIB_PROP_CREDIT) : #endif type==ORDER_TYPE_BUY ? pref+" Buy" : type==ORDER_TYPE_SELL ? pref+" Sell" : CMessage::Text(MSG_ORD_UNKNOWN_TYPE) ); } //+------------------------------------------------------------------+
新しい銘柄および口座オブジェクトプロパティの導入により、これらのプロパティをオブジェクトに追加する必要があります。
\MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqhを開いて必要な変更を追加します。
クラスのprotectedセクションに、2つの新しいプロパティを受け取るためのメソッドの定義を追加します。
protected: //--- 保護されたパラメトリックコンストラクタ CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name,const int index); //--- Get and return integer properties of a selected symbol from its parameters bool SymbolExists(const string name) const; 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 SymbolExpirationMode(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 SymbolDigitsLot(void); int SymbolDigitsBySwap(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; bool SymbolMarginLong(void); bool SymbolMarginShort(void); bool SymbolMarginBuyStop(void); bool SymbolMarginBuyLimit(void); bool SymbolMarginBuyStopLimit(void); bool SymbolMarginSellStop(void); bool SymbolMarginSellLimit(void); bool SymbolMarginSellStopLimit(void); //--- 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; string SymbolCategory(void) const; string SymbolExchange(void) const; //--- Search for a symbol and return the flag indicating its presence on the server bool Exist(void) const; public:
クラスのpublicセクションのオブジェクトプロパティを簡単に受信するためのブロックで、2つの新しいメソッドの定義を追加します。
public: //+------------------------------------------------------------------+ //| Methods of a simplified access to the order object properties | //+------------------------------------------------------------------+ //--- Integer properties long Status(void) const { return this.GetProperty(SYMBOL_PROP_STATUS); } int IndexInMarketWatch(void) const { return (int)this.GetProperty(SYMBOL_PROP_INDEX_MW); } bool IsCustom(void) const { return (bool)this.GetProperty(SYMBOL_PROP_CUSTOM); } color ColorBackground(void) const { return (color)this.GetProperty(SYMBOL_PROP_BACKGROUND_COLOR); } ENUM_SYMBOL_CHART_MODE ChartMode(void) const { return (ENUM_SYMBOL_CHART_MODE)this.GetProperty(SYMBOL_PROP_CHART_MODE); } bool IsExist(void) const { return (bool)this.GetProperty(SYMBOL_PROP_EXIST); } bool IsExist(const string name) const { return this.SymbolExists(name); } bool IsSelect(void) const { return (bool)this.GetProperty(SYMBOL_PROP_SELECT); } bool IsVisible(void) const { return (bool)this.GetProperty(SYMBOL_PROP_VISIBLE); } long SessionDeals(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_DEALS); } long SessionBuyOrders(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_BUY_ORDERS); } long SessionSellOrders(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_SELL_ORDERS); } long Volume(void) const { return this.GetProperty(SYMBOL_PROP_VOLUME); } long VolumeHigh(void) const { return this.GetProperty(SYMBOL_PROP_VOLUMEHIGH); } long VolumeLow(void) const { return this.GetProperty(SYMBOL_PROP_VOLUMELOW); } 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 MarginLongInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_LONG_INITIAL); } double MarginBuyStopInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL); } double MarginBuyLimitInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL); } double MarginBuyStopLimitInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL); } double MarginLongMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_LONG_MAINTENANCE); } double MarginBuyStopMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE); } double MarginBuyLimitMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE); } double MarginBuyStopLimitMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE); } double MarginShortInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SHORT_INITIAL); } double MarginSellStopInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL); } double MarginSellLimitInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL); } double MarginSellStopLimitInitial(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL); } double MarginShortMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE); } double MarginSellStopMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE); } double MarginSellLimitMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE); } double MarginSellStopLimitMaintenance(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE); } double SessionVolume(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_VOLUME); } double SessionTurnover(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_TURNOVER); } double SessionInterest(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_INTEREST); } double SessionBuyOrdersVolume(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME); } double SessionSellOrdersVolume(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME); } double SessionOpen(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_OPEN); } double SessionClose(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_CLOSE); } double SessionAW(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_AW); } double SessionPriceSettlement(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT); } double SessionPriceLimitMin(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN); } double SessionPriceLimitMax(void) const { return this.GetProperty(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX); } double MarginHedged(void) const { return this.GetProperty(SYMBOL_PROP_MARGIN_HEDGED); } double NormalizedPrice(const double price) const; double NormalizedLot(const double volume) const; double BidLast(void) const; double BidLastHigh(void) const; double BidLastLow(void) const; //--- String properties string Name(void) const { return this.GetProperty(SYMBOL_PROP_NAME); } string Basis(void) const { return this.GetProperty(SYMBOL_PROP_BASIS); } string CurrencyBase(void) const { return this.GetProperty(SYMBOL_PROP_CURRENCY_BASE); } string CurrencyProfit(void) const { return this.GetProperty(SYMBOL_PROP_CURRENCY_PROFIT); } string CurrencyMargin(void) const { return this.GetProperty(SYMBOL_PROP_CURRENCY_MARGIN); } string Bank(void) const { return this.GetProperty(SYMBOL_PROP_BANK); } string Description(void) const { return this.GetProperty(SYMBOL_PROP_DESCRIPTION); } string Formula(void) const { return this.GetProperty(SYMBOL_PROP_FORMULA); } string ISIN(void) const { return this.GetProperty(SYMBOL_PROP_ISIN); } string Page(void) const { return this.GetProperty(SYMBOL_PROP_PAGE); } string Path(void) const { return this.GetProperty(SYMBOL_PROP_PATH); } string Category(void) const { return this.GetProperty(SYMBOL_PROP_CATEGORY); } string Exchange(void) const { return this.GetProperty(SYMBOL_PROP_EXCHANGE); } //+------------------------------------------------------------------+
閉じたパラメトリッククラスコンストラクタにこれらの新しいプロパティの受け取りを追加します。
//--- 文字列プロパティを保存する this.m_string_prop[this.IndexProp(SYMBOL_PROP_NAME)] = this.m_name; this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_BASE)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_BASE); this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_PROFIT)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_PROFIT); this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_MARGIN)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_MARGIN); this.m_string_prop[this.IndexProp(SYMBOL_PROP_DESCRIPTION)] = ::SymbolInfoString(this.m_name,SYMBOL_DESCRIPTION); this.m_string_prop[this.IndexProp(SYMBOL_PROP_PATH)] = ::SymbolInfoString(this.m_name,SYMBOL_PATH); this.m_string_prop[this.IndexProp(SYMBOL_PROP_BASIS)] = this.SymbolBasis(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_BANK)] = this.SymbolBank(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_ISIN)] = this.SymbolISIN(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_FORMULA)] = this.SymbolFormula(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_PAGE)] = this.SymbolPage(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_CATEGORY)] = this.SymbolCategory(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_EXCHANGE)] = this.SymbolExchange(); //--- 追加の整数型プロパティを保存する
クラス本体の外部で2つの新しいプロパティを受け取るためのメソッドを実装します。
//+------------------------------------------------------------------+ //| Return a symbol category | //+------------------------------------------------------------------+ string CSymbol::SymbolCategory(void) const { return ( #ifdef __MQL5__ ( ::TerminalInfoInteger(TERMINAL_BUILD)<2155 ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MT5_LESS_2155) : ::SymbolInfoString(this.m_name,SYMBOL_CATEGORY) ) #else ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif ); } //+------------------------------------------------------------------+ //| Return an exchange name | //| a symbol is traded on | //+------------------------------------------------------------------+ string CSymbol::SymbolExchange(void) const { return ( #ifdef __MQL5__ ( ::TerminalInfoInteger(TERMINAL_BUILD)<2155 ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MT5_LESS_2155) : ::SymbolInfoString(this.m_name,SYMBOL_EXCHANGE) ) #else ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED_MQL4) #endif ); } //+------------------------------------------------------------------+
ここで、MQL5のターミナルビルドを確認します。2155以下ならば, 現在のプロパティが2155より下のバージョンではサポートされていないことを通知し、そのほかの場合は新しい
SYMBOL_EXCHANGEプロパティを返します。
MQL4の場合、MQL4ではプロパティがサポートされていないことを通知します。
銘柄文字列プロパティの説明を返すメソッドの実装に2つの新しいプロパティの説明の戻り値を追加します。
//+------------------------------------------------------------------+ //| Return the description of a symbol string property | //+------------------------------------------------------------------+ string CSymbol::GetPropertyDescription(ENUM_SYMBOL_PROP_STRING property) { return ( property==SYMBOL_PROP_NAME ? CMessage::Text(MSG_SYM_PROP_NAME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetProperty(property) ) : property==SYMBOL_PROP_BASIS ? CMessage::Text(MSG_SYM_PROP_BASIS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_CURRENCY_BASE ? CMessage::Text(MSG_SYM_PROP_CURRENCY_BASE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_CURRENCY_PROFIT ? CMessage::Text(MSG_SYM_PROP_CURRENCY_PROFIT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_CURRENCY_MARGIN ? CMessage::Text(MSG_SYM_PROP_CURRENCY_MARGIN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_BANK ? CMessage::Text(MSG_SYM_PROP_BANK)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_DESCRIPTION ? CMessage::Text(MSG_SYM_PROP_DESCRIPTION)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_FORMULA ? CMessage::Text(MSG_SYM_PROP_FORMULA)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_ISIN ? CMessage::Text(MSG_SYM_PROP_ISIN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_PAGE ? CMessage::Text(MSG_SYM_PROP_PAGE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_PATH ? CMessage::Text(MSG_SYM_PROP_PATH)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_CATEGORY ? CMessage::Text(MSG_SYM_PROP_CAYEGORY)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : property==SYMBOL_PROP_EXCHANGE ? CMessage::Text(MSG_SYM_PROP_EXCHANGE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : (this.GetProperty(property)=="" || this.GetProperty(property)==NULL ? ": ("+CMessage::Text(MSG_LIB_PROP_EMPTY)+")" : ": \""+this.GetProperty(property)+"\"") ) : "" ); } //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Objects\Accounts\Account.mqhで、口座オブジェクトに新しいプロパティを追加しましょう。
口座プロパティ構造体に新しいフィールドを書きます。
//+------------------------------------------------------------------+ //| Account class | //+------------------------------------------------------------------+ class CAccount : public CBaseObj { private: struct SData { //--- Account integer properties long login; // ACCOUNT_LOGIN (Account number) int trade_mode; // ACCOUNT_TRADE_MODE (Trading account type) long leverage; // ACCOUNT_LEVERAGE (Leverage) int limit_orders; // ACCOUNT_LIMIT_ORDERS (Maximum allowed number of active pending orders) int margin_so_mode; // ACCOUNT_MARGIN_SO_MODE (Mode of setting the minimum available margin level) bool trade_allowed; // ACCOUNT_TRADE_ALLOWED (Permission to trade for the current account from the server side) bool trade_expert; // ACCOUNT_TRADE_EXPERT (Permission to trade for an EA from the server side) int margin_mode; // ACCOUNT_MARGIN_MODE (Margin calculation mode) int currency_digits; // ACCOUNT_CURRENCY_DIGITS (Number of decimal places for the account currency) int server_type; // Trade server type (MetaTrader 5, MetaTrader 4) bool fifo_close; // The flag indicating that positions can be closed only by the FIFO rule //--- Account real properties double balance; // ACCOUNT_BALANCE (Account balance in a deposit currency) double credit; // ACCOUNT_CREDIT (Credit in a deposit currency) double profit; // ACCOUNT_PROFIT (Current profit on an account in the account currency) double equity; // ACCOUNT_EQUITY (Equity on an account in the deposit currency) double margin; // ACCOUNT_MARGIN (Reserved margin on an account in a deposit currency) double margin_free; // ACCOUNT_MARGIN_FREE (Free funds available for opening a position in a deposit currency) double margin_level; // ACCOUNT_MARGIN_LEVEL (Margin level on an account in %) double margin_so_call; // ACCOUNT_MARGIN_SO_CALL (MarginCall) double margin_so_so; // ACCOUNT_MARGIN_SO_SO (StopOut) double margin_initial; // ACCOUNT_MARGIN_INITIAL (Funds reserved on an account to ensure a guarantee amount for all pending orders) double margin_maintenance; // ACCOUNT_MARGIN_MAINTENANCE (Funds reserved on an account to ensure a minimum amount for all open positions) double assets; // ACCOUNT_ASSETS (Current assets on an account) double liabilities; // ACCOUNT_LIABILITIES (Current liabilities on an account) double comission_blocked; // ACCOUNT_COMMISSION_BLOCKED (Current sum of blocked commissions on an account) //--- Account string properties uchar name[128]; // ACCOUNT_NAME (Client name) uchar server[64]; // ACCOUNT_SERVER (Trade server name) uchar currency[32]; // ACCOUNT_CURRENCY (Deposit currency) uchar company[128]; // ACCOUNT_COMPANY (Name of a company serving an account) }; SData m_struct_obj; // Account object structure
クラスのpublicセクションのオブジェクトプロパティを簡単にアクセスするためのブロックで、新しいプロパティを戻すメソッドを追加します。
//+------------------------------------------------------------------+ //| Methods of a simplified access to the account object properties | //+------------------------------------------------------------------+ //--- Return the account's integer properties ENUM_ACCOUNT_TRADE_MODE TradeMode(void) const { return (ENUM_ACCOUNT_TRADE_MODE)this.GetProperty(ACCOUNT_PROP_TRADE_MODE); } ENUM_ACCOUNT_STOPOUT_MODE MarginSOMode(void) const { return (ENUM_ACCOUNT_STOPOUT_MODE)this.GetProperty(ACCOUNT_PROP_MARGIN_SO_MODE); } ENUM_ACCOUNT_MARGIN_MODE MarginMode(void) const { return (ENUM_ACCOUNT_MARGIN_MODE)this.GetProperty(ACCOUNT_PROP_MARGIN_MODE); } long Login(void) const { return this.GetProperty(ACCOUNT_PROP_LOGIN); } long Leverage(void) const { return this.GetProperty(ACCOUNT_PROP_LEVERAGE); } long LimitOrders(void) const { return this.GetProperty(ACCOUNT_PROP_LIMIT_ORDERS); } long TradeAllowed(void) const { return this.GetProperty(ACCOUNT_PROP_TRADE_ALLOWED); } long TradeExpert(void) const { return this.GetProperty(ACCOUNT_PROP_TRADE_EXPERT); } long CurrencyDigits(void) const { return this.GetProperty(ACCOUNT_PROP_CURRENCY_DIGITS); } long ServerType(void) const { return this.GetProperty(ACCOUNT_PROP_SERVER_TYPE); } long FIFOClose(void) const { return this.GetProperty(ACCOUNT_PROP_FIFO_CLOSE); } //--- Return the account's real properties
クラスコンストラクタに新しい口座オブジェクトプロパティの保存を追加します。
//+------------------------------------------------------------------+ //| コンストラクタ | //+------------------------------------------------------------------+ CAccount::CAccount(void) { //--- Initialize control data this.SetControlDataArraySizeLong(ACCOUNT_PROP_INTEGER_TOTAL); this.SetControlDataArraySizeDouble(ACCOUNT_PROP_DOUBLE_TOTAL); this.ResetChangesParams(); this.ResetControlsParams(); //--- 整数型プロパティを保存する this.m_long_prop[ACCOUNT_PROP_LOGIN] = ::AccountInfoInteger(ACCOUNT_LOGIN); this.m_long_prop[ACCOUNT_PROP_TRADE_MODE] = ::AccountInfoInteger(ACCOUNT_TRADE_MODE); this.m_long_prop[ACCOUNT_PROP_LEVERAGE] = ::AccountInfoInteger(ACCOUNT_LEVERAGE); this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS] = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS); this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE] = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE); this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED] = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED); this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT] = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT); this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ; this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ; this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE] = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4); this.m_long_prop[ACCOUNT_PROP_FIFO_CLOSE] = (#ifdef __MQL5__::TerminalInfoInteger(TERMINAL_BUILD)<2155 ? false : ::AccountInfoInteger(ACCOUNT_FIFO_CLOSE) #else false #endif ); //--- 実数型プロパティを保存する
ターミナルビルドが2155未満の場合は、falseを入力します。その他の場合、ACCOUNT_FIFO_CLOSE口座プロパティ値を書きます。
また、プロパティの保存をRefresh()口座更新メソッドに追加します。
//+------------------------------------------------------------------+ //| Update all account data | //+------------------------------------------------------------------+ void CAccount::Refresh(void) { //--- Initialize event data this.m_is_event=false; this.m_hash_sum=0; //--- Update integer properties this.m_long_prop[ACCOUNT_PROP_LOGIN] = ::AccountInfoInteger(ACCOUNT_LOGIN); this.m_long_prop[ACCOUNT_PROP_TRADE_MODE] = ::AccountInfoInteger(ACCOUNT_TRADE_MODE); this.m_long_prop[ACCOUNT_PROP_LEVERAGE] = ::AccountInfoInteger(ACCOUNT_LEVERAGE); this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS] = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS); this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE] = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE); this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED] = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED); this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT] = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT); this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ; this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ; this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE] = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4); this.m_long_prop[ACCOUNT_PROP_FIFO_CLOSE] = (#ifdef __MQL5__::TerminalInfoInteger(TERMINAL_BUILD)<2155 ? false : ::AccountInfoInteger(ACCOUNT_FIFO_CLOSE) #else false #endif ); //--- Update real properties
構造体から口座オブジェクトを作成するメソッドに新しいプロパティの記入を追加します。
//+------------------------------------------------------------------+ //| Create the account object from the structure | //+------------------------------------------------------------------+ void CAccount::StructToObject(void) { //--- 整数型プロパティを保存する this.m_long_prop[ACCOUNT_PROP_LOGIN] = this.m_struct_obj.login; this.m_long_prop[ACCOUNT_PROP_TRADE_MODE] = this.m_struct_obj.trade_mode; this.m_long_prop[ACCOUNT_PROP_LEVERAGE] = this.m_struct_obj.leverage; this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS] = this.m_struct_obj.limit_orders; this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE] = this.m_struct_obj.margin_so_mode; this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED] = this.m_struct_obj.trade_allowed; this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT] = this.m_struct_obj.trade_expert; this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE] = this.m_struct_obj.margin_mode; this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS] = this.m_struct_obj.currency_digits; this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE] = this.m_struct_obj.server_type; this.m_long_prop[ACCOUNT_PROP_FIFO_CLOSE] = this.m_struct_obj.fifo_close; //--- 実数型プロパティを保存する
口座オブジェクトの整数プロパティの説明を返すメソッドに新しいプロパティの説明の表示を追加します。
//+------------------------------------------------------------------+ //| Return the description of the account integer property | //+------------------------------------------------------------------+ string CAccount::GetPropertyDescription(ENUM_ACCOUNT_PROP_INTEGER property) { return ( property==ACCOUNT_PROP_LOGIN ? CMessage::Text(MSG_ACC_PROP_LOGIN)+": "+(string)this.GetProperty(property) : property==ACCOUNT_PROP_TRADE_MODE ? CMessage::Text(MSG_ACC_PROP_TRADE_MODE)+": "+this.TradeModeDescription() : property==ACCOUNT_PROP_LEVERAGE ? CMessage::Text(MSG_ACC_PROP_LEVERAGE)+": "+(string)this.GetProperty(property) : property==ACCOUNT_PROP_LIMIT_ORDERS ? CMessage::Text(MSG_ACC_PROP_LIMIT_ORDERS)+": "+(string)this.GetProperty(property) : property==ACCOUNT_PROP_MARGIN_SO_MODE ? CMessage::Text(MSG_ACC_PROP_MARGIN_SO_MODE)+": "+this.MarginSOModeDescription() : property==ACCOUNT_PROP_TRADE_ALLOWED ? CMessage::Text(MSG_ACC_PROP_TRADE_ALLOWED)+": "+ (this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) : property==ACCOUNT_PROP_TRADE_EXPERT ? CMessage::Text(MSG_ACC_PROP_TRADE_EXPERT)+": "+ (this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) : property==ACCOUNT_PROP_MARGIN_MODE ? CMessage::Text(MSG_ACC_PROP_MARGIN_MODE)+": "+this.MarginModeDescription() : property==ACCOUNT_PROP_CURRENCY_DIGITS ? CMessage::Text(MSG_ACC_PROP_CURRENCY_DIGITS)+": "+(string)this.GetProperty(property) : property==ACCOUNT_PROP_SERVER_TYPE ? CMessage::Text(MSG_ACC_PROP_SERVER_TYPE)+": "+(string)this.GetProperty(property) : property==ACCOUNT_PROP_FIFO_CLOSE ? CMessage::Text(MSG_ACC_PROP_FIFO_CLOSE)+": "+(string)this.GetProperty(property) : "" ); } //+------------------------------------------------------------------+
口座オブジェクトに新しいプロパティを追加すると、以前にすべての端末の共通フォルダに保存された口座オブジェクトが無効になることに注意してください。読み取りエラーを回避するには、\DoEasy\Accounts\サブフォルダ内のすべての端末共通フォルダにある以前に作成されたすべての口座ファイルを削除します。その後、口座を新しい口座に置き換えると、ライブラリは口座オブジェクトを新しい形式で独自に保存します。
すべての端末の共通フォルダを開くには、エディタコマンド[ファイル]->
[共通データフォルダを開く]を使用します。エクスプローラウィンドウで、Filesフォルダに移動し「\DoEasy\Accounts\」に入ります。
クラスのpublicセクションで、指定されたポジションを開くか指値注文を出すために必要な証拠金を返すメソッドの定義を追加します。
public: //--- コンストラクタ CAccount(void); //--- Set account's (1) integer, (2) real and (3) string properties void SetProperty(ENUM_ACCOUNT_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_ACCOUNT_PROP_DOUBLE property,double value) { this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_ACCOUNT_PROP_STRING property,string value) { this.m_string_prop[this.IndexProp(property)]=value; } //--- Return (1) integer, (2) real and (3) string order properties from the account string property long GetProperty(ENUM_ACCOUNT_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_ACCOUNT_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_ACCOUNT_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Return the flag of calculating MarginCall and StopOut levels in % bool IsPercentsForSOLevels(void) const { return this.MarginSOMode()==ACCOUNT_STOPOUT_MODE_PERCENT; } //--- Return the flag of supporting the property by the account object virtual bool SupportProperty(ENUM_ACCOUNT_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_ACCOUNT_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_ACCOUNT_PROP_STRING property) { return true; } //--- Compare CAccount objects by all possible properties (for sorting the lists by a specified account object property) virtual int Compare(const CObject *node,const int mode=0) const; //--- Compare CAccount objects by account properties (to search for equal account objects) bool IsEqual(CAccount* compared_account) const; //--- Update all account data virtual void Refresh(void); //--- (1) Save the account object to the file, (2), download the account object from the file virtual bool Save(const int file_handle); virtual bool Load(const int file_handle); //--- Return the margin required for opening a position or placing a pending order double MarginForAction(const ENUM_ORDER_TYPE action,const string symbol,const double volume,const double price) const; //+------------------------------------------------------------------+
クラス本体の外側で実装します。
//+------------------------------------------------------------------+ //| Return the margin required for opening a position | //| or placing a pending order | //+------------------------------------------------------------------+ double CAccount::MarginForAction(const ENUM_ORDER_TYPE action,const string symbol,const double volume,const double price) const { double margin=EMPTY_VALUE; #ifdef __MQL5__ return(!::OrderCalcMargin(action,symbol,volume,price,margin) ? EMPTY_VALUE : margin); #else return this.MarginFree()-::AccountFreeMarginCheck(symbol,action,volume); #endif } //+------------------------------------------------------------------+
MQL5では、OrderCalcMargin()関数を使用して、新しいポジションを開くか指値注文を出すために必要な証拠金を取得します。何らかの理由で関数がエラーを返した場合、最大値DBL_MAX
(EMPTY_VALUE定数の値)を返します。それ以外の場合は、計算された必要証拠金を返します。
MQL4では、指定されたポジションを開いた後、 AccountFreeMarginCheck()関数を使用して計算された注文を行った後に残っている資金を差し引いた既存の余剰証拠金を返します。
これで、口座オブジェクトクラスの改善は終わりです。
それでは、取引オブジェクトの基本クラスを改善しましょう。取引イベントを通知するための音声を設定する機能を追加する必要があります。
データを格納するクラスのprivateセクションで、さまざまなイベントで音声を使用するフラグと音声ファイル名を保存する構造体を作成します。
//+------------------------------------------------------------------+ //| Trading object class | //+------------------------------------------------------------------+ class CTradeObj { private: struct SActionsFlags { private: bool m_use_sound_open; // The flag of using the position opening/order placing sound bool m_use_sound_close; // The flag of using the position closing/order removal sound bool m_use_sound_modify_sl; // The flag of using the StopLoss position/order modification sound bool m_use_sound_modify_tp; // The flag of using the TakeProfit position/order modification sound bool m_use_sound_modify_price; // The flag of using the order placement price modification sound //--- string m_sound_open; // Position opening/order placing sound string m_sound_close; // Position closing/order removal sound string m_sound_modify_sl; // StopLoss position/order modification sound string m_sound_modify_tp; // TakeProfit position/order modification sound string m_sound_modify_price; // Order placement price modification sound //--- string m_sound_open_err; // Position opening/order placing error sound string m_sound_close_err; // Position closing/order removal error sound string m_sound_modify_sl_err; // StopLoss position/order modification error sound string m_sound_modify_tp_err; // TakeProfit position/order modification error sound string m_sound_modify_price_err; // Order placement price modification error sound public: //--- Method of placing/accessing flags and file names void UseSoundOpen(const bool flag) { this.m_use_sound_open=flag; } void UseSoundClose(const bool flag) { this.m_use_sound_close=flag; } void UseSoundModifySL(const bool flag) { this.m_use_sound_modify_sl=flag; } void UseSoundModifyTP(const bool flag) { this.m_use_sound_modify_tp=flag; } void UseSoundModifyPrice(const bool flag) { this.m_use_sound_modify_price=flag; } bool UseSoundOpen(void) const { return this.m_use_sound_open; } bool UseSoundClose(void) const { return this.m_use_sound_close; } bool UseSoundModifySL(void) const { return this.m_use_sound_modify_sl; } bool UseSoundModifyTP(void) const { return this.m_use_sound_modify_tp; } bool UseSoundModifyPrice(void) const { return this.m_use_sound_modify_price; } //--- void SoundOpen(const string sound) { this.m_sound_open=sound; } void SoundClose(const string sound) { this.m_sound_close=sound; } void SoundModifySL(const string sound) { this.m_sound_modify_sl=sound; } void SoundModifyTP(const string sound) { this.m_sound_modify_tp=sound; } void SoundModifyPrice(const string sound) { this.m_sound_modify_price=sound; } string SoundOpen(void) const { return this.m_sound_open; } string SoundClose(void) const { return this.m_sound_close; } string SoundModifySL(void) const { return this.m_sound_modify_sl; } string SoundModifyTP(void) const { return this.m_sound_modify_tp; } string SoundModifyPrice(void) const { return this.m_sound_modify_price; } //--- void SoundErrorOpen(const string sound) { this.m_sound_open_err=sound; } void SoundErrorClose(const string sound) { this.m_sound_close_err=sound; } void SoundErrorModifySL(const string sound) { this.m_sound_modify_sl_err=sound; } void SoundErrorModifyTP(const string sound) { this.m_sound_modify_tp_err=sound; } void SoundErrorModifyPrice(const string sound) { this.m_sound_modify_price_err=sound; } string SoundErrorOpen(void) const { return this.m_sound_open_err; } string SoundErrorClose(void) const { return this.m_sound_close_err; } string SoundErrorModifySL(void) const { return this.m_sound_modify_sl_err; } string SoundErrorModifyTP(void) const { return this.m_sound_modify_tp_err; } string SoundErrorModifyPrice(void) const { return this.m_sound_modify_price_err; } }; struct SActions { SActionsFlags Buy; SActionsFlags BuyStop; SActionsFlags BuyLimit; SActionsFlags BuyStopLimit; SActionsFlags Sell; SActionsFlags SellStop; SActionsFlags SellLimit; SActionsFlags SellStopLimit; }; SActions m_datas;
構造体は、2つのネストされた構造体(フラグとフラグ名のデータを含むSActionsFlagsと、各ポジションおよび注文タイプのSActionsFlags構造体型のデータを特徴とするSActionsm_dataで構成されます。これにより、任意の注文またはポジションのフラグとフラグ名を使用して構造体フィールドにアクセスできるようになり、イベントの音声を設定および使用する際の柔軟性が向上します。
また、クラスのprivateセクションで、取引イベントの音声使用フラグを格納する取引オブジェクトのクラスメンバ変数を宣言します。
bool m_use_sound; // The flag of using sounds of the object trading events
このフラグは、銘柄取引オブジェクトのすべての取引イベントに音声を使用するための共通のオン/オフスイッチです。このフラグは、銘柄取引オブジェクトのすべての取引イベントに音声を使用するための共通のオン/オフスイッチです。
クラスのpublicセクションで、銘柄基本取引オブジェクトのすべての取引イベントに音声を使用するフラグと音声ファイル名を設定および受信するために必要なすべてのメソッドを宣言します。
public: //--- コンストラクタ CTradeObj(); //--- Set default values void Init(const string symbol, const ulong magic, const double volume, const ulong deviation, const int stoplimit, const datetime expiration, const bool async_mode, const ENUM_ORDER_TYPE_FILLING type_filling, const ENUM_ORDER_TYPE_TIME type_expiration, ENUM_LOG_LEVEL log_level); //--- Set default sounds and flags of using sounds, void InitSounds(const bool use_sound=false, const string sound_open=NULL, const string sound_close=NULL, const string sound_sl=NULL, const string sound_tp=NULL, const string sound_price=NULL, const string sound_error=NULL); //--- Allow working with sounds and set standard sounds void SetSoundsStandart(void); //--- Set the flag of using the sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type void UseSoundOpen(const ENUM_ORDER_TYPE action,const bool flag); void UseSoundClose(const ENUM_ORDER_TYPE action,const bool flag); void UseSoundModifySL(const ENUM_ORDER_TYPE action,const bool flag); void UseSoundModifyTP(const ENUM_ORDER_TYPE action,const bool flag); void UseSoundModifyPrice(const ENUM_ORDER_TYPE action,const bool flag); //--- Return the flag of using the sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type bool UseSoundOpen(const ENUM_ORDER_TYPE action) const; bool UseSoundClose(const ENUM_ORDER_TYPE action) const; bool UseSoundModifySL(const ENUM_ORDER_TYPE action) const; bool UseSoundModifyTP(const ENUM_ORDER_TYPE action) const; bool UseSoundModifyPrice(const ENUM_ORDER_TYPE action) const; //--- Set the sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type void SetSoundOpen(const ENUM_ORDER_TYPE action,const string sound); void SetSoundClose(const ENUM_ORDER_TYPE action,const string sound); void SetSoundModifySL(const ENUM_ORDER_TYPE action,const string sound); void SetSoundModifyTP(const ENUM_ORDER_TYPE action,const string sound); void SetSoundModifyPrice(const ENUM_ORDER_TYPE action,const string sound); //--- Set the error sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type void SetSoundErrorOpen(const ENUM_ORDER_TYPE action,const string sound); void SetSoundErrorClose(const ENUM_ORDER_TYPE action,const string sound); void SetSoundErrorModifySL(const ENUM_ORDER_TYPE action,const string sound); void SetSoundErrorModifyTP(const ENUM_ORDER_TYPE action,const string sound); void SetSoundErrorModifyPrice(const ENUM_ORDER_TYPE action,const string sound); //--- Return the sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type string GetSoundOpen(const ENUM_ORDER_TYPE action) const; string GetSoundClose(const ENUM_ORDER_TYPE action) const; string GetSoundModifySL(const ENUM_ORDER_TYPE action) const; string GetSoundModifyTP(const ENUM_ORDER_TYPE action) const; string GetSoundModifyPrice(const ENUM_ORDER_TYPE action) const; //--- Return the error sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type string GetSoundErrorOpen(const ENUM_ORDER_TYPE action) const; string GetSoundErrorClose(const ENUM_ORDER_TYPE action) const; string GetSoundErrorModifySL(const ENUM_ORDER_TYPE action) const; string GetSoundErrorModifyTP(const ENUM_ORDER_TYPE action) const; string GetSoundErrorModifyPrice(const ENUM_ORDER_TYPE action) const; //--- Play the sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type void PlaySoundOpen(const ENUM_ORDER_TYPE action); void PlaySoundClose(const ENUM_ORDER_TYPE action); void PlaySoundModifySL(const ENUM_ORDER_TYPE action); void PlaySoundModifyTP(const ENUM_ORDER_TYPE action); void PlaySoundModifyPrice(const ENUM_ORDER_TYPE action); //--- Play the error sound of (1) opening/placing a specified position/order type, //--- (2) closing/removal of a specified position/order type, (3) StopLoss modification for a specified position/order type, //--- (4) TakeProfit modification for a specified position/order type, (5) placement price modification for a specified order type void PlaySoundErrorOpen(const ENUM_ORDER_TYPE action); void PlaySoundErrorClose(const ENUM_ORDER_TYPE action); void PlaySoundErrorModifySL(const ENUM_ORDER_TYPE action); void PlaySoundErrorModifyTP(const ENUM_ORDER_TYPE action); void PlaySoundErrorModifyPrice(const ENUM_ORDER_TYPE action); //--- Set/return the flag of using sounds void SetUseSound(const bool flag) { this.m_use_sound=flag; } bool IsUseSound(void) const { return this.m_use_sound; } //--- (1) Return the margin calculation mode, (2) hedge account flag
クラスコンストラクタで音声を使用する一般的なフラグをリセット し、音声とオーディオファイルを使用するフラグをデフォルト値に初期化して、音声を無効にして空のファイル名を指定します。
//+------------------------------------------------------------------+ //| コンストラクタ | //+------------------------------------------------------------------+ CTradeObj::CTradeObj(void) : m_magic(0), m_deviation(5), m_stop_limit(0), m_expiration(0), m_async_mode(false), m_type_filling(ORDER_FILLING_FOK), m_type_expiration(ORDER_TIME_GTC), m_comment(::MQLInfoString(MQL_PROGRAM_NAME)+" by DoEasy"), m_log_level(LOG_LEVEL_ERROR_MSG) { //--- Margin calculation mode this.m_margin_mode= ( #ifdef __MQL5__ (ENUM_ACCOUNT_MARGIN_MODE)::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else /* MQL4 */ ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ); //--- Set default sounds and flags of using sounds this.m_use_sound=false; this.InitSounds(); } //+------------------------------------------------------------------+
音声使用フラグおよび音声ファイル名の設定を初期化するメソッドをクラス本体の外に実装します。
//+------------------------------------------------------------------+ //| Set default sounds and flags of using sounds | //+------------------------------------------------------------------+ void CTradeObj::InitSounds(const bool use_sound=false, const string sound_open=NULL, const string sound_close=NULL, const string sound_sl=NULL, const string sound_tp=NULL, const string sound_price=NULL, const string sound_error=NULL) { this.m_datas.Buy.UseSoundOpen(use_sound); this.m_datas.Buy.UseSoundClose(use_sound); this.m_datas.Buy.UseSoundModifySL(use_sound); this.m_datas.Buy.UseSoundModifyTP(use_sound); this.m_datas.Buy.UseSoundModifyPrice(use_sound); this.m_datas.Buy.SoundOpen(sound_open); this.m_datas.Buy.SoundClose(sound_close); this.m_datas.Buy.SoundModifySL(sound_sl); this.m_datas.Buy.SoundModifyTP(sound_tp); this.m_datas.Buy.SoundModifyPrice(sound_price); this.m_datas.Buy.SoundErrorClose(sound_error); this.m_datas.Buy.SoundErrorOpen(sound_error); this.m_datas.Buy.SoundErrorModifySL(sound_error); this.m_datas.Buy.SoundErrorModifyTP(sound_error); this.m_datas.Buy.SoundErrorModifyPrice(sound_error); this.m_datas.BuyStop.UseSoundOpen(use_sound); this.m_datas.BuyStop.UseSoundClose(use_sound); this.m_datas.BuyStop.UseSoundModifySL(use_sound); this.m_datas.BuyStop.UseSoundModifyTP(use_sound); this.m_datas.BuyStop.UseSoundModifyPrice(use_sound); this.m_datas.BuyStop.SoundOpen(sound_open); this.m_datas.BuyStop.SoundClose(sound_close); this.m_datas.BuyStop.SoundModifySL(sound_sl); this.m_datas.BuyStop.SoundModifyTP(sound_tp); this.m_datas.BuyStop.SoundModifyPrice(sound_price); this.m_datas.BuyStop.SoundErrorClose(sound_error); this.m_datas.BuyStop.SoundErrorOpen(sound_error); this.m_datas.BuyStop.SoundErrorModifySL(sound_error); this.m_datas.BuyStop.SoundErrorModifyTP(sound_error); this.m_datas.BuyStop.SoundErrorModifyPrice(sound_error); this.m_datas.BuyLimit.UseSoundOpen(use_sound); this.m_datas.BuyLimit.UseSoundClose(use_sound); this.m_datas.BuyLimit.UseSoundModifySL(use_sound); this.m_datas.BuyLimit.UseSoundModifyTP(use_sound); this.m_datas.BuyLimit.UseSoundModifyPrice(use_sound); this.m_datas.BuyLimit.SoundOpen(sound_open); this.m_datas.BuyLimit.SoundClose(sound_close); this.m_datas.BuyLimit.SoundModifySL(sound_sl); this.m_datas.BuyLimit.SoundModifyTP(sound_tp); this.m_datas.BuyLimit.SoundModifyPrice(sound_price); this.m_datas.BuyLimit.SoundErrorClose(sound_error); this.m_datas.BuyLimit.SoundErrorOpen(sound_error); this.m_datas.BuyLimit.SoundErrorModifySL(sound_error); this.m_datas.BuyLimit.SoundErrorModifyTP(sound_error); this.m_datas.BuyLimit.SoundErrorModifyPrice(sound_error); this.m_datas.BuyStopLimit.UseSoundOpen(use_sound); this.m_datas.BuyStopLimit.UseSoundClose(use_sound); this.m_datas.BuyStopLimit.UseSoundModifySL(use_sound); this.m_datas.BuyStopLimit.UseSoundModifyTP(use_sound); this.m_datas.BuyStopLimit.UseSoundModifyPrice(use_sound); this.m_datas.BuyStopLimit.SoundOpen(sound_open); this.m_datas.BuyStopLimit.SoundClose(sound_close); this.m_datas.BuyStopLimit.SoundModifySL(sound_sl); this.m_datas.BuyStopLimit.SoundModifyTP(sound_tp); this.m_datas.BuyStopLimit.SoundModifyPrice(sound_price); this.m_datas.BuyStopLimit.SoundErrorClose(sound_error); this.m_datas.BuyStopLimit.SoundErrorOpen(sound_error); this.m_datas.BuyStopLimit.SoundErrorModifySL(sound_error); this.m_datas.BuyStopLimit.SoundErrorModifyTP(sound_error); this.m_datas.BuyStopLimit.SoundErrorModifyPrice(sound_error); this.m_datas.Sell.UseSoundOpen(use_sound); this.m_datas.Sell.UseSoundClose(use_sound); this.m_datas.Sell.UseSoundModifySL(use_sound); this.m_datas.Sell.UseSoundModifyTP(use_sound); this.m_datas.Sell.UseSoundModifyPrice(use_sound); this.m_datas.Sell.SoundOpen(sound_open); this.m_datas.Sell.SoundClose(sound_close); this.m_datas.Sell.SoundModifySL(sound_sl); this.m_datas.Sell.SoundModifyTP(sound_tp); this.m_datas.Sell.SoundModifyPrice(sound_price); this.m_datas.Sell.SoundErrorClose(sound_error); this.m_datas.Sell.SoundErrorOpen(sound_error); this.m_datas.Sell.SoundErrorModifySL(sound_error); this.m_datas.Sell.SoundErrorModifyTP(sound_error); this.m_datas.Sell.SoundErrorModifyPrice(sound_error); this.m_datas.SellStop.UseSoundOpen(use_sound); this.m_datas.SellStop.UseSoundClose(use_sound); this.m_datas.SellStop.UseSoundModifySL(use_sound); this.m_datas.SellStop.UseSoundModifyTP(use_sound); this.m_datas.SellStop.UseSoundModifyPrice(use_sound); this.m_datas.SellStop.SoundOpen(sound_open); this.m_datas.SellStop.SoundClose(sound_close); this.m_datas.SellStop.SoundModifySL(sound_sl); this.m_datas.SellStop.SoundModifyTP(sound_tp); this.m_datas.SellStop.SoundModifyPrice(sound_price); this.m_datas.SellStop.SoundErrorClose(sound_error); this.m_datas.SellStop.SoundErrorOpen(sound_error); this.m_datas.SellStop.SoundErrorModifySL(sound_error); this.m_datas.SellStop.SoundErrorModifyTP(sound_error); this.m_datas.SellStop.SoundErrorModifyPrice(sound_error); this.m_datas.SellLimit.UseSoundOpen(use_sound); this.m_datas.SellLimit.UseSoundClose(use_sound); this.m_datas.SellLimit.UseSoundModifySL(use_sound); this.m_datas.SellLimit.UseSoundModifyTP(use_sound); this.m_datas.SellLimit.UseSoundModifyPrice(use_sound); this.m_datas.SellLimit.SoundOpen(sound_open); this.m_datas.SellLimit.SoundClose(sound_close); this.m_datas.SellLimit.SoundModifySL(sound_sl); this.m_datas.SellLimit.SoundModifyTP(sound_tp); this.m_datas.SellLimit.SoundModifyPrice(sound_price); this.m_datas.SellLimit.SoundErrorClose(sound_error); this.m_datas.SellLimit.SoundErrorOpen(sound_error); this.m_datas.SellLimit.SoundErrorModifySL(sound_error); this.m_datas.SellLimit.SoundErrorModifyTP(sound_error); this.m_datas.SellLimit.SoundErrorModifyPrice(sound_error); this.m_datas.SellStopLimit.UseSoundOpen(use_sound); this.m_datas.SellStopLimit.UseSoundClose(use_sound); this.m_datas.SellStopLimit.UseSoundModifySL(use_sound); this.m_datas.SellStopLimit.UseSoundModifyTP(use_sound); this.m_datas.SellStopLimit.UseSoundModifyPrice(use_sound); this.m_datas.SellStopLimit.SoundOpen(sound_open); this.m_datas.SellStopLimit.SoundClose(sound_close); this.m_datas.SellStopLimit.SoundModifySL(sound_sl); this.m_datas.SellStopLimit.SoundModifyTP(sound_tp); this.m_datas.SellStopLimit.SoundModifyPrice(sound_price); this.m_datas.SellStopLimit.SoundErrorClose(sound_error); this.m_datas.SellStopLimit.SoundErrorOpen(sound_error); this.m_datas.SellStopLimit.SoundErrorModifySL(sound_error); this.m_datas.SellStopLimit.SoundErrorModifyTP(sound_error); this.m_datas.SellStopLimit.SoundErrorModifyPrice(sound_error); } //+------------------------------------------------------------------+
メソッドは、取引オブジェクトイベントによる音声使用フラグ、発注、決済、ストップロスおよびテイクプロフィットの変更、注文価格、エラーで使用される音声ファイル名を受け取ります。次に、各取引イベントの構造体フィールドは、渡された値によってサーバに送信される各注文タイプに入力されます。
音声を使用するフラグとエラー音声ファイル名は、列挙されたすべての取引イベントに対して1に設定されますが、各イベントの取引イベントの場合、音声は個別に設定されます。ただし、必要に応じて、上記の方法を使用して特定のイベントのエラー音声にカスタム音声を設定したり、オブジェクトの各取引イベントに個別に音声を使用するためのフラグを設定したりすることもできます。デフォルトでは音声は無効になっておりファイル名は空です。
また、このクラスは、すべてのオブジェクトの取引イベントの標準音声を設定し、各取引イベントでの使用を許可するメソッドを備えています。
//+------------------------------------------------------------------+ //| Allow working with sounds and set standard sounds | //+------------------------------------------------------------------+ void CTradeObj::SetSoundsStandart(void) { this.m_datas.Buy.UseSoundClose(true); this.m_datas.Buy.UseSoundOpen(true); this.m_datas.Buy.UseSoundModifySL(true); this.m_datas.Buy.UseSoundModifyTP(true); this.m_datas.Buy.UseSoundModifyPrice(true); this.m_datas.Buy.SoundOpen(SND_OK); this.m_datas.Buy.SoundClose(SND_OK); this.m_datas.Buy.SoundModifySL(SND_OK); this.m_datas.Buy.SoundModifyTP(SND_OK); this.m_datas.Buy.SoundModifyPrice(SND_OK); this.m_datas.Buy.SoundErrorClose(SND_TIMEOUT); this.m_datas.Buy.SoundErrorOpen(SND_TIMEOUT); this.m_datas.Buy.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.Buy.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.Buy.SoundErrorModifyPrice(SND_TIMEOUT); this.m_datas.BuyStop.UseSoundClose(true); this.m_datas.BuyStop.UseSoundOpen(true); this.m_datas.BuyStop.UseSoundModifySL(true); this.m_datas.BuyStop.UseSoundModifyTP(true); this.m_datas.BuyStop.UseSoundModifyPrice(true); this.m_datas.BuyStop.SoundOpen(SND_OK); this.m_datas.BuyStop.SoundClose(SND_OK); this.m_datas.BuyStop.SoundModifySL(SND_OK); this.m_datas.BuyStop.SoundModifyTP(SND_OK); this.m_datas.BuyStop.SoundModifyPrice(SND_OK); this.m_datas.BuyStop.SoundErrorClose(SND_TIMEOUT); this.m_datas.BuyStop.SoundErrorOpen(SND_TIMEOUT); this.m_datas.BuyStop.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.BuyStop.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.BuyStop.SoundErrorModifyPrice(SND_TIMEOUT); this.m_datas.BuyLimit.UseSoundClose(true); this.m_datas.BuyLimit.UseSoundOpen(true); this.m_datas.BuyLimit.UseSoundModifySL(true); this.m_datas.BuyLimit.UseSoundModifyTP(true); this.m_datas.BuyLimit.UseSoundModifyPrice(true); this.m_datas.BuyLimit.SoundOpen(SND_OK); this.m_datas.BuyLimit.SoundClose(SND_OK); this.m_datas.BuyLimit.SoundModifySL(SND_OK); this.m_datas.BuyLimit.SoundModifyTP(SND_OK); this.m_datas.BuyLimit.SoundModifyPrice(SND_OK); this.m_datas.BuyLimit.SoundErrorClose(SND_TIMEOUT); this.m_datas.BuyLimit.SoundErrorOpen(SND_TIMEOUT); this.m_datas.BuyLimit.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.BuyLimit.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.BuyLimit.SoundErrorModifyPrice(SND_TIMEOUT); this.m_datas.BuyStopLimit.UseSoundClose(true); this.m_datas.BuyStopLimit.UseSoundOpen(true); this.m_datas.BuyStopLimit.UseSoundModifySL(true); this.m_datas.BuyStopLimit.UseSoundModifyTP(true); this.m_datas.BuyStopLimit.UseSoundModifyPrice(true); this.m_datas.BuyStopLimit.SoundOpen(SND_OK); this.m_datas.BuyStopLimit.SoundClose(SND_OK); this.m_datas.BuyStopLimit.SoundModifySL(SND_OK); this.m_datas.BuyStopLimit.SoundModifyTP(SND_OK); this.m_datas.BuyStopLimit.SoundModifyPrice(SND_OK); this.m_datas.BuyStopLimit.SoundErrorClose(SND_TIMEOUT); this.m_datas.BuyStopLimit.SoundErrorOpen(SND_TIMEOUT); this.m_datas.BuyStopLimit.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.BuyStopLimit.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.BuyStopLimit.SoundErrorModifyPrice(SND_TIMEOUT); this.m_datas.Sell.UseSoundClose(true); this.m_datas.Sell.UseSoundOpen(true); this.m_datas.Sell.UseSoundModifySL(true); this.m_datas.Sell.UseSoundModifyTP(true); this.m_datas.Sell.UseSoundModifyPrice(true); this.m_datas.Sell.SoundOpen(SND_OK); this.m_datas.Sell.SoundClose(SND_OK); this.m_datas.Sell.SoundModifySL(SND_OK); this.m_datas.Sell.SoundModifyTP(SND_OK); this.m_datas.Sell.SoundModifyPrice(SND_OK); this.m_datas.Sell.SoundErrorClose(SND_TIMEOUT); this.m_datas.Sell.SoundErrorOpen(SND_TIMEOUT); this.m_datas.Sell.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.Sell.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.Sell.SoundErrorModifyPrice(SND_TIMEOUT); this.m_datas.SellStop.UseSoundClose(true); this.m_datas.SellStop.UseSoundOpen(true); this.m_datas.SellStop.UseSoundModifySL(true); this.m_datas.SellStop.UseSoundModifyTP(true); this.m_datas.SellStop.UseSoundModifyPrice(true); this.m_datas.SellStop.SoundOpen(SND_OK); this.m_datas.SellStop.SoundClose(SND_OK); this.m_datas.SellStop.SoundModifySL(SND_OK); this.m_datas.SellStop.SoundModifyTP(SND_OK); this.m_datas.SellStop.SoundModifyPrice(SND_OK); this.m_datas.SellStop.SoundErrorClose(SND_TIMEOUT); this.m_datas.SellStop.SoundErrorOpen(SND_TIMEOUT); this.m_datas.SellStop.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.SellStop.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.SellStop.SoundErrorModifyPrice(SND_TIMEOUT); this.m_datas.SellLimit.UseSoundClose(true); this.m_datas.SellLimit.UseSoundOpen(true); this.m_datas.SellLimit.UseSoundModifySL(true); this.m_datas.SellLimit.UseSoundModifyTP(true); this.m_datas.SellLimit.UseSoundModifyPrice(true); this.m_datas.SellLimit.SoundOpen(SND_OK); this.m_datas.SellLimit.SoundClose(SND_OK); this.m_datas.SellLimit.SoundModifySL(SND_OK); this.m_datas.SellLimit.SoundModifyTP(SND_OK); this.m_datas.SellLimit.SoundModifyPrice(SND_OK); this.m_datas.SellLimit.SoundErrorClose(SND_TIMEOUT); this.m_datas.SellLimit.SoundErrorOpen(SND_TIMEOUT); this.m_datas.SellLimit.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.SellLimit.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.SellLimit.SoundErrorModifyPrice(SND_TIMEOUT); this.m_datas.SellStopLimit.UseSoundClose(true); this.m_datas.SellStopLimit.UseSoundOpen(true); this.m_datas.SellStopLimit.UseSoundModifySL(true); this.m_datas.SellStopLimit.UseSoundModifyTP(true); this.m_datas.SellStopLimit.UseSoundModifyPrice(true); this.m_datas.SellStopLimit.SoundOpen(SND_OK); this.m_datas.SellStopLimit.SoundClose(SND_OK); this.m_datas.SellStopLimit.SoundModifySL(SND_OK); this.m_datas.SellStopLimit.SoundModifyTP(SND_OK); this.m_datas.SellStopLimit.SoundModifyPrice(SND_OK); this.m_datas.SellStopLimit.SoundErrorClose(SND_TIMEOUT); this.m_datas.SellStopLimit.SoundErrorOpen(SND_TIMEOUT); this.m_datas.SellStopLimit.SoundErrorModifySL(SND_TIMEOUT); this.m_datas.SellStopLimit.SoundErrorModifyTP(SND_TIMEOUT); this.m_datas.SellStopLimit.SoundErrorModifyPrice(SND_TIMEOUT); } //+------------------------------------------------------------------+
クラス本体の外で、特定の取引イベントタイプで音声を再生し、フラグと音声を設定するメソッドを実装します。
//+------------------------------------------------------------------+ //| Set the flag of using sounds | //| of opening/placing a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::UseSoundOpen(const ENUM_ORDER_TYPE action,const bool flag) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.UseSoundOpen(flag); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.UseSoundOpen(flag); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.UseSoundOpen(flag); break; case ORDER_TYPE_SELL : this.m_datas.Sell.UseSoundOpen(flag); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.UseSoundOpen(flag); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.UseSoundOpen(flag); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.UseSoundOpen(flag); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.UseSoundOpen(flag); break; default: break; } } //+------------------------------------------------------------------+ //| Set the flag of using a sound | //| of closing/removal of a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::UseSoundClose(const ENUM_ORDER_TYPE action,const bool flag) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.UseSoundClose(flag); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.UseSoundClose(flag); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.UseSoundClose(flag); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.UseSoundClose(flag); break; case ORDER_TYPE_SELL : this.m_datas.Sell.UseSoundClose(flag); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.UseSoundClose(flag); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.UseSoundClose(flag); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.UseSoundClose(flag); break; default: break; } } //+------------------------------------------------------------------+ //| Set the flag of using a sound | //| of StopLoss modification for a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::UseSoundModifySL(const ENUM_ORDER_TYPE action,const bool flag) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.UseSoundModifySL(flag); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.UseSoundModifySL(flag); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.UseSoundModifySL(flag); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.UseSoundModifySL(flag); break; case ORDER_TYPE_SELL : this.m_datas.Sell.UseSoundModifySL(flag); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.UseSoundModifySL(flag); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.UseSoundModifySL(flag); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.UseSoundModifySL(flag); break; default: break; } } //+------------------------------------------------------------------+ //| Set the flag of using a sound | //| of TakeProfit modification for a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::UseSoundModifyTP(const ENUM_ORDER_TYPE action,const bool flag) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.UseSoundModifyTP(flag); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.UseSoundModifyTP(flag); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.UseSoundModifyTP(flag); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.UseSoundModifyTP(flag); break; case ORDER_TYPE_SELL : this.m_datas.Sell.UseSoundModifyTP(flag); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.UseSoundModifyTP(flag); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.UseSoundModifyTP(flag); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.UseSoundModifyTP(flag); break; default: break; } } //+------------------------------------------------------------------+ //| Set the flag of using a modification sound | //| of the placement price for a specified order type | //+------------------------------------------------------------------+ void CTradeObj::UseSoundModifyPrice(const ENUM_ORDER_TYPE action,const bool flag) { int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.UseSoundModifyPrice(flag); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.UseSoundModifyPrice(flag); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.UseSoundModifyPrice(flag); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.UseSoundModifyPrice(flag); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.UseSoundModifyPrice(flag); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.UseSoundModifyPrice(flag); break; default: break; } } //+------------------------------------------------------------------+ //| Return the flag of using the sound of opening/placing | //| a specified position/order type | //+------------------------------------------------------------------+ bool CTradeObj::UseSoundOpen(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.UseSoundOpen(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.UseSoundOpen(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.UseSoundOpen(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.UseSoundOpen(); case ORDER_TYPE_SELL : return this.m_datas.Sell.UseSoundOpen(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.UseSoundOpen(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.UseSoundOpen(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.UseSoundOpen(); default: return false; } } //+------------------------------------------------------------------+ //| Return the flag of using the sound of closing/removal of | //| a specified position/order type | //+------------------------------------------------------------------+ bool CTradeObj::UseSoundClose(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.UseSoundClose(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.UseSoundClose(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.UseSoundClose(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.UseSoundClose(); case ORDER_TYPE_SELL : return this.m_datas.Sell.UseSoundClose(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.UseSoundClose(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.UseSoundClose(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.UseSoundClose(); default: return false; } } //+------------------------------------------------------------------+ //| Return the flag of using a sound | //| of StopLoss modification for a specified position/order type | //+------------------------------------------------------------------+ bool CTradeObj::UseSoundModifySL(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.UseSoundModifySL(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.UseSoundModifySL(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.UseSoundModifySL(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.UseSoundModifySL(); case ORDER_TYPE_SELL : return this.m_datas.Sell.UseSoundModifySL(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.UseSoundModifySL(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.UseSoundModifySL(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.UseSoundModifySL(); default: return false; } } //+------------------------------------------------------------------+ //| Return the flag of using a sound | //| of TakeProfit modification for a specified position/order type | //+------------------------------------------------------------------+ bool CTradeObj::UseSoundModifyTP(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.UseSoundModifyTP(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.UseSoundModifyTP(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.UseSoundModifyTP(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.UseSoundModifyTP(); case ORDER_TYPE_SELL : return this.m_datas.Sell.UseSoundModifyTP(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.UseSoundModifyTP(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.UseSoundModifyTP(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.UseSoundModifyTP(); default: return false; } } //+------------------------------------------------------------------+ //| Return the flag of using a modification sound | //| of the placement price for a specified order type | //+------------------------------------------------------------------+ bool CTradeObj::UseSoundModifyPrice(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.UseSoundModifyPrice(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.UseSoundModifyPrice(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.UseSoundModifyPrice(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.UseSoundModifyPrice(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.UseSoundModifyPrice(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.UseSoundModifyPrice(); default: return false; } } //+------------------------------------------------------------------+ //| Set the sound of opening/placing | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundOpen(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundOpen(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundOpen(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundOpen(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundOpen(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundOpen(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundOpen(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundOpen(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundOpen(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set the sound of closing/removal of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundClose(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundClose(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundClose(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundClose(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundClose(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundClose(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundClose(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundClose(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundClose(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set StopLoss modification sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundModifySL(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundModifySL(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundModifySL(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundModifySL(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundModifySL(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundModifySL(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundModifySL(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundModifySL(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundModifySL(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set TakeProfit modification sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundModifyTP(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundModifyTP(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundModifyTP(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundModifyTP(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundModifyTP(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundModifyTP(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundModifyTP(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundModifyTP(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundModifyTP(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set price modification sound | //| for a specified order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundModifyPrice(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundModifyPrice(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundModifyPrice(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundModifyPrice(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundModifyPrice(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundModifyPrice(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundModifyPrice(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set the error sound of opening/placing | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundErrorOpen(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundErrorOpen(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundErrorOpen(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundErrorOpen(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundErrorOpen(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundErrorOpen(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundErrorOpen(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundErrorOpen(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundErrorOpen(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set the error sound of closing/removal of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundErrorClose(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundErrorClose(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundErrorClose(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundErrorClose(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundErrorClose(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundErrorClose(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundErrorClose(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundErrorClose(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundErrorClose(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set StopLoss modification error sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundErrorModifySL(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundErrorModifySL(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundErrorModifySL(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundErrorModifySL(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundErrorModifySL(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundErrorModifySL(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundErrorModifySL(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundErrorModifySL(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundErrorModifySL(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set TakeProfit modification error sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundErrorModifyTP(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY : this.m_datas.Buy.SoundErrorModifyTP(sound); break; case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundErrorModifyTP(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundErrorModifyTP(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundErrorModifyTP(sound); break; case ORDER_TYPE_SELL : this.m_datas.Sell.SoundErrorModifyTP(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundErrorModifyTP(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundErrorModifyTP(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundErrorModifyTP(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Set price modification error sound | //| for a specified order type | //+------------------------------------------------------------------+ void CTradeObj::SetSoundErrorModifyPrice(const ENUM_ORDER_TYPE action,const string sound) { int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : this.m_datas.BuyStop.SoundErrorModifyPrice(sound); break; case ORDER_TYPE_BUY_LIMIT : this.m_datas.BuyLimit.SoundErrorModifyPrice(sound); break; case ORDER_TYPE_BUY_STOP_LIMIT : this.m_datas.BuyStopLimit.SoundErrorModifyPrice(sound); break; case ORDER_TYPE_SELL_STOP : this.m_datas.SellStop.SoundErrorModifyPrice(sound); break; case ORDER_TYPE_SELL_LIMIT : this.m_datas.SellLimit.SoundErrorModifyPrice(sound); break; case ORDER_TYPE_SELL_STOP_LIMIT : this.m_datas.SellStopLimit.SoundErrorModifyPrice(sound); break; default: break; } } //+------------------------------------------------------------------+ //| Return the sound of opening/placing | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundOpen(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundOpen(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundOpen(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundOpen(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundOpen(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundOpen(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundOpen(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundOpen(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundOpen(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return the sound of closing/removal of | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundClose(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundClose(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundClose(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundClose(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundClose(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundClose(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundClose(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundClose(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundClose(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return StopLoss modification sound of | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundModifySL(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundModifySL(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundModifySL(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundModifySL(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundModifySL(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundModifySL(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundModifySL(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundModifySL(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundModifySL(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return TakeProfit modification sound of | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundModifyTP(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundModifyTP(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundModifyTP(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundModifyTP(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundModifyTP(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundModifyTP(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundModifyTP(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundModifyTP(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundModifyTP(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return price modification sound | //| for a specified order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundModifyPrice(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundModifyPrice(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundModifyPrice(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundModifyPrice(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundModifyPrice(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundModifyPrice(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundModifyPrice(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return the error sound of opening/placing | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundErrorOpen(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundErrorOpen(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundErrorOpen(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundErrorOpen(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundErrorOpen(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundErrorOpen(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundErrorOpen(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundErrorOpen(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundErrorOpen(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return the error sound of closing/removal of | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundErrorClose(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundErrorClose(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundErrorClose(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundErrorClose(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundErrorClose(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundErrorClose(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundErrorClose(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundErrorClose(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundErrorClose(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return StopLoss modification error sound of | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundErrorModifySL(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundErrorModifySL(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundErrorModifySL(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundErrorModifySL(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundErrorModifySL(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundErrorModifySL(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundErrorModifySL(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundErrorModifySL(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundErrorModifySL(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return TakeProfit modification error sound of | //| a specified position/order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundErrorModifyTP(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY : return this.m_datas.Buy.SoundErrorModifyTP(); case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundErrorModifyTP(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundErrorModifyTP(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundErrorModifyTP(); case ORDER_TYPE_SELL : return this.m_datas.Sell.SoundErrorModifyTP(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundErrorModifyTP(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundErrorModifyTP(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundErrorModifyTP(); default: return NULL; } } //+------------------------------------------------------------------+ //| Return price modification error sound | //| for a specified order type | //+------------------------------------------------------------------+ string CTradeObj::GetSoundErrorModifyPrice(const ENUM_ORDER_TYPE action) const { int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : return this.m_datas.BuyStop.SoundErrorModifyPrice(); case ORDER_TYPE_BUY_LIMIT : return this.m_datas.BuyLimit.SoundErrorModifyPrice(); case ORDER_TYPE_BUY_STOP_LIMIT : return this.m_datas.BuyStopLimit.SoundErrorModifyPrice(); case ORDER_TYPE_SELL_STOP : return this.m_datas.SellStop.SoundErrorModifyPrice(); case ORDER_TYPE_SELL_LIMIT : return this.m_datas.SellLimit.SoundErrorModifyPrice(); case ORDER_TYPE_SELL_STOP_LIMIT : return this.m_datas.SellStopLimit.SoundErrorModifyPrice(); default: return NULL; } } //+------------------------------------------------------------------+ //| Play the sound of opening/placing | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundOpen(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundOpen()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundOpen()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundOpen()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundOpen()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundOpen()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundOpen()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundOpen()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundOpen()); break; default: break; } } //+------------------------------------------------------------------+ //| Play the sound of closing/removal of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundClose(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundClose()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundClose()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundClose()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundClose()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundClose()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundClose()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundClose()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundClose()); break; default: break; } } //+------------------------------------------------------------------+ //| Play StopLoss modification sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundModifySL(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundModifySL()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundModifySL()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundModifySL()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundModifySL()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundModifySL()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundModifySL()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundModifySL()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundModifySL()); break; default: break; } } //+------------------------------------------------------------------+ //| Play TakeProfit modification sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundModifyTP(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundModifyTP()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundModifyTP()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundModifyTP()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundModifyTP()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundModifyTP()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundModifyTP()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundModifyTP()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundModifyTP()); break; default: break; } } //+------------------------------------------------------------------+ //| Play price modification sound | //| for a specified order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundModifyPrice(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundModifyPrice()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundModifyPrice()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundModifyPrice()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundModifyPrice()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundModifyPrice()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundModifyPrice()); break; default: break; } } //+------------------------------------------------------------------+ //| Play the error sound of opening/placing | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundErrorOpen(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundErrorOpen()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundErrorOpen()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundErrorOpen()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundErrorOpen()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundErrorOpen()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundErrorOpen()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundErrorOpen()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundErrorOpen()); break; default: break; } } //+------------------------------------------------------------------+ //| Play the error sound of closing/removal of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundErrorClose(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundErrorClose()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundErrorClose()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundErrorClose()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundErrorClose()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundErrorClose()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundErrorClose()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundErrorClose()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundErrorClose()); break; default: break; } } //+------------------------------------------------------------------+ //| Play StopLoss modification error sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundErrorModifySL(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundErrorModifySL()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundErrorModifySL()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundErrorModifySL()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundErrorModifySL()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundErrorModifySL()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundErrorModifySL()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundErrorModifySL()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundErrorModifySL()); break; default: break; } } //+------------------------------------------------------------------+ //| Play TakeProfit modification error sound of | //| a specified position/order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundErrorModifyTP(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY : CMessage::PlaySound(this.m_datas.Buy.SoundErrorModifyTP()); break; case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundErrorModifyTP()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundErrorModifyTP()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundErrorModifyTP()); break; case ORDER_TYPE_SELL : CMessage::PlaySound(this.m_datas.Sell.SoundErrorModifyTP()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundErrorModifyTP()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundErrorModifyTP()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundErrorModifyTP()); break; default: break; } } //+------------------------------------------------------------------+ //| Play price modification error sound | //| for a specified order type | //+------------------------------------------------------------------+ void CTradeObj::PlaySoundErrorModifyPrice(const ENUM_ORDER_TYPE action) { if(!this.m_use_sound) return; int index=action; switch(index) { case ORDER_TYPE_BUY_STOP : CMessage::PlaySound(this.m_datas.BuyStop.SoundErrorModifyPrice()); break; case ORDER_TYPE_BUY_LIMIT : CMessage::PlaySound(this.m_datas.BuyLimit.SoundErrorModifyPrice()); break; case ORDER_TYPE_BUY_STOP_LIMIT : CMessage::PlaySound(this.m_datas.BuyStopLimit.SoundErrorModifyPrice()); break; case ORDER_TYPE_SELL_STOP : CMessage::PlaySound(this.m_datas.SellStop.SoundErrorModifyPrice()); break; case ORDER_TYPE_SELL_LIMIT : CMessage::PlaySound(this.m_datas.SellLimit.SoundErrorModifyPrice()); break; case ORDER_TYPE_SELL_STOP_LIMIT : CMessage::PlaySound(this.m_datas.SellStopLimit.SoundErrorModifyPrice()); break; default: break; } } //+------------------------------------------------------------------+
ここではすべてがすべてのメソッドで似ており、一見してすべてが明確です。名前に取引イベントのタイプが含まれるメソッドは、イベントの設定、リターン、または再生が必要な注文のタイプ(ポジションの成行注文タイプ)を受け取ります 。次に、ポジション/注文タイプに応じて、指定された取引イベントの音声が設定/返送/再生されます。
これで、銘柄基本取引オブジェクトの改善は終わりです。基本取引クラスを開発する時が来ました。
正しい操作のために、取引クラスは以前に作成されたコレクションへのポインタを受け取ります。これを行うには、コレクションオブジェクトへのポインタを返すメソッドを各コレクションクラスに追加します。
以下は、履歴コレクションオブジェクトの場合です。
public: //--- Return itself CHistoryCollection *GetObject(void) { return &this; }
以下は、市場コレクションオブジェクトの場合です。
public: //--- Return itself CMarketCollection *GetObject(void) { return &this; }
以下は、銘柄コレクションの場合です。
public: //--- Return itself CSymbolsCollection *GetObject(void) { return &this; }
現在開発されている取引クラスは、取引操作への集中アクセスを提供するものです。このクラスは、取引注文を送信する前にすべての検証を蓄積し、取引サーバの応答を処理し、取引サーバの応答とクラス取引メソッドの動作の設定に応じてさらなるアクションを決定します。
本稿では、後にさらに開発されるクラスの基礎を作成しますが、まず、プログラム、ターミナル、口座、銘柄の各側面から取引の制限を確認しましょう。
取引クラス
\MQL5\Include\DoEasy\で、Trading.mqh ファイルに新しいCTrading クラスを作成します。
クラスを機能させるには事前に作成されたコレクションのリストが必要です。一方、アクセス許可を確認するさいにエラーを保存するには、標準ライブラリのintまたはuint変数を含む動的配列のオブジェクト
が必要です。
直ちにクラスファイルにインクルードしましょう。
//+------------------------------------------------------------------+ //| Trading.mqh | //| Copyright 2019, MetaQuotes Software Corp. | //| https://mql5.com/ja/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2019, MetaQuotes Software Corp." #property link "https://mql5.com/ja/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| ファイルをインクルードする | //+------------------------------------------------------------------+ #include <Arrays\ArrayInt.mqh> #include "Objects\Trade\TradeObj.mqh" #include "Collections\AccountsCollection.mqh" #include "Collections\SymbolsCollection.mqh" #include "Collections\MarketCollection.mqh" #include "Collections\HistoryCollection.mqh" //+------------------------------------------------------------------+ //| Trading class | //+------------------------------------------------------------------+
クラス本体の完全なリストを見て、その構成を分析しましょう。
//+------------------------------------------------------------------+ //| Trading.mqh | //| Copyright 2019, MetaQuotes Software Corp. | //| https://mql5.com/ja/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2019, MetaQuotes Software Corp." #property link "https://mql5.com/ja/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| ファイルをインクルードする | //+------------------------------------------------------------------+ #include <Arrays\ArrayInt.mqh> #include "Objects\Trade\TradeObj.mqh" #include "Collections\AccountsCollection.mqh" #include "Collections\SymbolsCollection.mqh" #include "Collections\MarketCollection.mqh" #include "Collections\HistoryCollection.mqh" //+------------------------------------------------------------------+ //| Trading class | //+------------------------------------------------------------------+ class CTrading { private: CAccount *m_account; // Pointer to the current account object CSymbolsCollection *m_symbols; // Pointer to the symbol collection list CMarketCollection *m_market; // Pointer to the list of the collection of market orders and positions CHistoryCollection *m_history; // Pointer to the list of the collection of historical orders and deals CArrayInt m_list_errors; // Error list bool m_is_trade_enable; // Flag enabling trading ENUM_LOG_LEVEL m_log_level; // Logging level //--- Add the error code to the list bool AddErrorCodeToList(const int error_code); //--- Return the symbol object by (1) position, (2) order ticket CSymbol *GetSymbolObjByPosition(const ulong ticket,const string source_method); CSymbol *GetSymbolObjByOrder(const ulong ticket,const string source_method); //--- Return a symbol trading object by (1) position, (2) order ticket, (3) symbol name CTradeObj *GetTradeObjByPosition(const ulong ticket,const string source_method); CTradeObj *GetTradeObjByOrder(const ulong ticket,const string source_method); CTradeObj *GetTradeObjBySymbol(const string symbol,const string source_method); //--- Return the number of (1) all positions, (2) buy, (3) sell positions int PositionsTotalAll(void) const; int PositionsTotalLong(void) const; int PositionsTotalShort(void) const; //--- Return the number of (1) all pending orders, (2) buy, (3) sell pending orders int OrdersTotalAll(void) const; int OrdersTotalLong(void) const; int OrdersTotalShort(void) const; //--- Return the total volume of (1) buy, (2) sell positions double PositionsTotalVolumeLong(void) const; double PositionsTotalVolumeShort(void) const; //--- Return the total volume of (1) buy, (2) sell orders double OrdersTotalVolumeLong(void) const; double OrdersTotalVolumeShort(void) const; //--- Return the order direction by an operation type ENUM_ORDER_TYPE DirectionByActionType(ENUM_ACTION_TYPE action) const; //--- Check the presence of a (1) position, (2) order by ticket bool CheckPositionAvailablity(const ulong ticket,const string source_method); bool CheckOrderAvailablity(const ulong ticket,const string source_method); //--- Set the desired sound for a trading object void SetSoundByMode(const ENUM_MODE_SET_SOUND mode,const ENUM_ORDER_TYPE action,const string sound,CTradeObj *trade_obj); public: //--- コンストラクタ CTrading(); //--- Get the pointers to the lists (make sure to call the method in program's OnInit() since the symbol collection list is created there) void OnInit(CAccount *account,CSymbolsCollection *symbols,CMarketCollection *market,CHistoryCollection *history) { this.m_account=account; this.m_symbols=symbols; this.m_market=market; this.m_history=history; } //--- Return the error list CArrayInt *GetListErrors(void) { return &this.m_list_errors; } //--- Check trading limitations bool CheckTradeConstraints(const double volume, const ENUM_ACTION_TYPE action_type, const CSymbol *symbol_obj, const string source_method, double sl=0, double tp=0); //--- Check if the funds are sufficient bool CheckMoneyFree(const ENUM_ORDER_TYPE order_type,const double volume,const double price,const CSymbol *symbol_obj,const string source_method) const; //--- Set the following for symbol trading objects: //--- (1) correct filling policy, (2) filling policy, //--- (3) correct order expiration type, (4) order expiration type, //--- (5) magic number, (6) comment, (7) slippage, (8) volume, (9) order expiration date, //--- (10) the flag of asynchronous sending of a trading request, (11) logging level void SetCorrectTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol=NULL); void SetTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol=NULL); void SetCorrectTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol=NULL); void SetTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol=NULL); void SetMagic(const ulong magic,const string symbol=NULL); void SetComment(const string comment,const string symbol=NULL); void SetDeviation(const ulong deviation,const string symbol=NULL); void SetVolume(const double volume=0,const string symbol=NULL); void SetExpiration(const datetime expiration=0,const string symbol=NULL); void SetAsyncMode(const bool mode=false,const string symbol=NULL); void SetLogLevel(const ENUM_LOG_LEVEL log_level=LOG_LEVEL_ERROR_MSG,const string symbol=NULL); //--- Set standard sounds (1 symbol=NULL) for trading objects of all symbols, (2 symbol!=NULL) for a symbol trading object void SetSoundsStandart(const string symbol=NULL); //--- Set a sound for a specified order/position type and symbol //--- 'mode' specifies an event a sound is set for //--- (symbol=NULL) for trading objects of all symbols, //--- (symbol!=NULL) for a trading object of a specified symbol void SetSound(const ENUM_MODE_SET_SOUND mode,const ENUM_ORDER_TYPE action,const string sound,const string symbol=NULL); //--- Open (1) Buy, (2) Sell position bool OpenBuy(const double volume,const string symbol,const ulong magic=ULONG_MAX,double sl=0,double tp=0,const string comment=NULL); bool OpenSell(const double volume,const string symbol,const ulong magic=ULONG_MAX,double sl=0,double tp=0,const string comment=NULL); //--- Modify a position bool ModifyPosition(const ulong ticket,const double sl=WRONG_VALUE,const double tp=WRONG_VALUE); //--- Close a position (1) fully, (2) partially, (3) by an opposite one bool ClosePosition(const ulong ticket); bool ClosePositionPartially(const ulong ticket,const double volume); bool ClosePositionBy(const ulong ticket,const ulong ticket_by); //--- Set (1) BuyStop, (2) BuyLimit, (3) BuyStopLimit pending order bool PlaceBuyStop(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=ULONG_MAX, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC); bool PlaceBuyLimit(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=ULONG_MAX, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC); bool PlaceBuyStopLimit(const double volume, const string symbol, const double price_stop, const double price_limit, const double sl=0, const double tp=0, const ulong magic=ULONG_MAX, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC); //--- Set (1) SellStop, (2) SellLimit, (3) SellStopLimit pending order bool PlaceSellStop(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=ULONG_MAX, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC); bool PlaceSellLimit(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=ULONG_MAX, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC); bool PlaceSellStopLimit(const double volume, const string symbol, const double price_stop, const double price_limit, const double sl=0, const double tp=0, const ulong magic=ULONG_MAX, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC); //--- Modify a pending order bool ModifyOrder(const ulong ticket, const double price=WRONG_VALUE, const double sl=WRONG_VALUE, const double tp=WRONG_VALUE, const double stoplimit=WRONG_VALUE, datetime expiration=WRONG_VALUE, ENUM_ORDER_TYPE_TIME type_time=WRONG_VALUE); //--- Remove a pending order bool DeleteOrder(const ulong ticket); }; //+------------------------------------------------------------------+
各クラスメソッドには説明のコメントが付いているため、クラスメソッドの構造についての追加の説明は必要ないと思います。
クラスの取引メソッドは、銘柄基本取引オブジェクトのメソッドとほぼ同じシグネチャを持ちます。唯一の違いは、ポジションを開くメソッドと指値注文の発注で、取引操作が実行される銘柄の名前の存在です。
クラスメソッドの実装を考えてみましょう。
一度にいくつかの制限がある可能性があるため、各エラーのコードをリストに配置し、検出された制限のリストを必要なすべての条件を確認した後に表示する必要があります。制限値(検証コードのさまざまなフラグメントで検出された)をリストに2回配置しないようにするには、リスト内の適切な制限の存在を確認し、存在しない場合にのみ配置します。この場合、各制限タイプは一度リストに配置されます。
次のメソッドを使用して、リスト内の制限タイプの存在を確認し、リストに追加します。
//+------------------------------------------------------------------+ //| Add the error code to the list | //+------------------------------------------------------------------+ bool CTrading::AddErrorCodeToList(const int error_code) { this.m_list_errors.Sort(); if(this.m_list_errors.Search(error_code)==WRONG_VALUE) return this.m_list_errors.Add(error_code); return false; } //+------------------------------------------------------------------+
メソッドはエラーコードを受け取り、取引制限の理由を特定します。並び替え済みリストフラグが設定され,
リストにそのようなコードがない場合が確認されます。確認が成功すると、Add()メソッド
を使用してリストにコードを追加した結果が返されます。
コードが既にリストに存在する場合、falseを返します。
取引オブジェクトは銘柄に属しているため(各銘柄には取引オブジェクトがあります)、多くの取引メソッドは注文/ポジションチケットで機能しますが、そのようなポジションまたは注文が存在する銘柄をチケットで定義する必要があります。
ポジションチケットによって銘柄オブジェクトを返すメソッドでこのタスクを解決します。
//+------------------------------------------------------------------+ //| Return a symbol object by a position ticket | //+------------------------------------------------------------------+ CSymbol *CTrading::GetSymbolObjByPosition(const ulong ticket,const string source_method) { //--- Get the list of open positions CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_POSITION,EQUAL); //--- If failed to get the list of open positions, display the message and return NULL if(list==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_ENG_FAILED_GET_MARKET_POS_LIST)); return NULL; } //--- If the list is empty (no open positions), display the message and return NULL if(list.Total()==0) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(source_method,CMessage::Text(MSG_ENG_NO_OPEN_POSITIONS)); return NULL; } //--- Sort the list by a ticket list=CSelect::ByOrderProperty(list,ORDER_PROP_TICKET,ticket,EQUAL); //--- If failed to get the list of open positions, display the message and return NULL if(list==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_ENG_FAILED_GET_MARKET_POS_LIST)); return NULL; } //--- If the list is empty (no required ticket), display the message and return NULL if(list.Total()==0) { //--- Error. No open position with #ticket if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(source_method,CMessage::Text(MSG_LIB_SYS_ERROR_NO_OPEN_POSITION_WITH_TICKET),(string)ticket); return NULL; } //--- Get a position with #ticket from the obtained list COrder *pos=list.At(0); //--- If failed to get the position object, display the message and return NULL if(pos==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_POS_OBJ)); return NULL; } //--- Get a symbol object by name CSymbol * symbol_obj=this.m_symbols.GetSymbolObjByName(pos.Symbol()); //--- If failed to get the symbol object, display the message and return NULL if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return NULL; } //--- Return a symbol object return symbol_obj; } //+------------------------------------------------------------------+
以下は、注文チケットによります。
//+------------------------------------------------------------------+ //| Return a symbol object by an order ticket | //+------------------------------------------------------------------+ CSymbol *CTrading::GetSymbolObjByOrder(const ulong ticket,const string source_method) { //--- Get the list of placed orders CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_PENDING,EQUAL); //--- If failed to get the list of placed orders, display the message and return NULL if(list==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_ENG_FAILED_GET_PENDING_ORD_LIST)); return NULL; } //--- If the list is empty (no placed orders), display the message and return NULL if(list.Total()==0) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(source_method,CMessage::Text(MSG_ENG_NO_PLACED_ORDERS)); return NULL; } //--- Sort the list by a ticket list=CSelect::ByOrderProperty(list,ORDER_PROP_TICKET,ticket,EQUAL); //--- If failed to get the list of placed orders, display the message and return NULL if(list==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_ENG_FAILED_GET_PENDING_ORD_LIST)); return NULL; } //--- If the list is empty (no required ticket), display the message and return NULL if(list.Total()==0) { //--- Error. No placed order with #ticket if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(source_method,CMessage::Text(MSG_LIB_SYS_ERROR_NO_PLACED_ORDER_WITH_TICKET),(string)ticket); return NULL; } //--- Get an order with #ticket from the obtained list COrder *ord=list.At(0); //--- If failed to get an object order, display the message and return NULL if(ord==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_ORD_OBJ)); return NULL; } //--- Get a symbol object by name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(ord.Symbol()); //--- If failed to get the symbol object, display the message and return NULL if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return NULL; } //--- Return a symbol object return symbol_obj; } //+------------------------------------------------------------------+
これら2つのメソッドはほとんど同じです。唯一の違いは、最初のメソッドではチケットでポジションを検索し、2番目メソッドではチケットで注文を検索することです。メソッドは、目的のポジションまたは注文のチケットと、メソッドを呼び出したメソッドの名前を受け取ります。これにより、エラーが発生した場合に操作ログでメソッド名を確認できます。補助メソッドの名前は、エラーが発生した場所を見つけるためのデータを提供しません(銘柄オブジェクトの検索が呼び出されたメソッドを指定する必要があります)。
クラスメソッドの操作では、ポジションチケット、注文チケット、または銘柄名で銘柄取引オブジェクトを受け取ることが必要になる場合があります。
//+------------------------------------------------------------------+ //| Return a symbol trading object by a position ticket | //+------------------------------------------------------------------+ CTradeObj *CTrading::GetTradeObjByPosition(const ulong ticket,const string source_method) { //--- Get a symbol object by a position ticket CSymbol * symbol_obj=this.GetSymbolObjByPosition(ticket,DFUN); //--- If failed to get the symbol object, display the message and return NULL if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return NULL; } //--- Get and return the trading object from the symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); return trade_obj; } //+------------------------------------------------------------------+ //| Return a symbol trading object by an order ticket | //+------------------------------------------------------------------+ CTradeObj *CTrading::GetTradeObjByOrder(const ulong ticket,const string source_method) { //--- Get a symbol object by an order ticket CSymbol * symbol_obj=this.GetSymbolObjByOrder(ticket,source_method); //--- If failed to get the symbol object, display the message and return NULL if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return NULL; } //--- Get and return the trading object from the symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); return trade_obj; } //+------------------------------------------------------------------+ //| Return a symbol trading object by a symbol name | //+------------------------------------------------------------------+ CTradeObj *CTrading::GetTradeObjBySymbol(const string symbol,const string source_method) { //--- Get a symbol object by its name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return NULL if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_NOT_SYMBOL_ON_LIST)); return NULL; } //--- Get and return the trading object from the symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); return trade_obj; } //+------------------------------------------------------------------+
3つの補助メソッドはすべて、さらなる作業のために取引オブジェクトを返します。すべてのアクションはメソッドリストでコメントされます。
いくつかの制限を確認して取引の決定を下すには、両方向のポジションと注文の数を知る必要があります。
以下は、口座のポジション数を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the number of positions | //+------------------------------------------------------------------+ int CTrading::PositionsTotalAll(void) const { CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_POSITION,EQUAL); return(list==NULL ? 0 : list.Total()); } //+------------------------------------------------------------------+
ここではすべてのポジションと出された注文のリストを受け取り「市場ポジション」注文ステータスによってリストを並び替えます。
取得したリスト内のオブジェクトの数を返します。リストの取得に失敗した場合、ゼロを返します。
以下は、口座の買いポジションの数を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the number of buy positions | //+------------------------------------------------------------------+ int CTrading::PositionsTotalLong(void) const { CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_POSITION,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_TYPE,POSITION_TYPE_BUY,EQUAL); return(list==NULL ? 0 : list.Total()); } //+------------------------------------------------------------------+
ここではすべてのポジションと出された注文のリストを受け取り「市場ポジション」注文ステータスによってリストを並び替えます。
取得したリストは、買いポジションの種類別に並び替えられます。
取得したリスト内のオブジェクトの数を返します。リストが取得できなかった場合は、ゼロを返します。
以下は、口座の売りポジションの数を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the number of sell positions | //+------------------------------------------------------------------+ int CTrading::PositionsTotalShort(void) const { CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_POSITION,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_TYPE,POSITION_TYPE_SELL,EQUAL); return(list==NULL ? 0 : list.Total()); } //+------------------------------------------------------------------+
ここではすべてのポジションと出された注文のリストを受け取り「市場ポジション」注文ステータスによってリストを並び替えます。
取得したリストは、売りポジションの種類別に並び替えられます。
取得したリスト内のオブジェクトの数を返します。リストが取得できなかった場合は、ゼロを返します。
以下は、口座の市場未決注文(売買とも)のリストを受け取るメソッドです。
//+------------------------------------------------------------------+ //| Returns the number of pending orders | //+------------------------------------------------------------------+ int CTrading::OrdersTotalAll(void) const { CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_PENDING,EQUAL); return(list==NULL ? 0 : list.Total()); } //+------------------------------------------------------------------+ //| Return the number of buy pending orders | //+------------------------------------------------------------------+ int CTrading::OrdersTotalLong(void) const { CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_PENDING,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_DIRECTION,ORDER_TYPE_BUY,EQUAL); return(list==NULL ? 0 : list.Total()); } //+------------------------------------------------------------------+ //| Return the number of sell pending orders | //+------------------------------------------------------------------+ int CTrading::OrdersTotalShort(void) const { CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_PENDING,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_DIRECTION,ORDER_TYPE_SELL,EQUAL); return(list==NULL ? 0 : list.Total()); } //+------------------------------------------------------------------+
これらの3つの補助メソッドは、上記の3つのメソッドと同じです。唯一の違いは、ここでは「アクティブな未決注文」ステータスと売買注文タイプの方向でリストを並び変える
また、いくつかの制限を定義するために、ポジションと未決注文の合計数量を知る必要があります。
以下は、買いポジションの合計数量を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the total volume of buy positions | //+------------------------------------------------------------------+ double CTrading::PositionsTotalVolumeLong(void) const { double vol=0; CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_POSITION,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_TYPE,POSITION_TYPE_BUY,EQUAL); if(list==NULL || list.Total()==0) return 0; for(int i=0;i<list.Total();i++) { COrder *obj=list.At(i); if(obj==NULL) continue; vol+=obj.Volume(); } return vol; } //+------------------------------------------------------------------+
ここではすべてのポジションと出された注文のリストを受け取り「市場ポジション」注文ステータスによってリストを並び替えます。
取得したリストは、買いポジションの種類別に並び替えられます。
リストが空の場合はゼロを返します。
取得したリストによるループで、次の注文オブジェクトを取得して
vol変数値にその数量を追加します。
ループの完了時に、取得された値をvol変数に返します
以下は、売りポジションの合計数量を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the total volume of sell positions | //+------------------------------------------------------------------+ double CTrading::PositionsTotalVolumeShort(void) const { double vol=0; CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_POSITION,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_TYPE,POSITION_TYPE_SELL,EQUAL); if(list==NULL || list.Total()==0) return 0; for(int i=0;i<list.Total();i++) { COrder *obj=list.At(i); if(obj==NULL) continue; vol+=obj.Volume(); } return vol; } //+------------------------------------------------------------------+
このメソッドは、売りポジションによる並び替えを除いて、前のメソッドと似ています。
以下は、買いおよび売り未決注文の合計数量を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the total volume of buy orders | //+------------------------------------------------------------------+ double CTrading::OrdersTotalVolumeLong(void) const { double vol=0; CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_PENDING,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_DIRECTION,ORDER_TYPE_BUY,EQUAL); if(list==NULL || list.Total()==0) return 0; for(int i=0;i<list.Total();i++) { COrder *obj=list.At(i); if(obj==NULL) continue; vol+=obj.Volume(); } return vol; } //+------------------------------------------------------------------+ //| Return the total volume of sell orders | //+------------------------------------------------------------------+ double CTrading::OrdersTotalVolumeShort(void) const { double vol=0; CArrayObj *list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_PENDING,EQUAL); list=CSelect::ByOrderProperty(list,ORDER_PROP_DIRECTION,ORDER_TYPE_SELL,EQUAL); if(list==NULL || list.Total()==0) return 0; for(int i=0;i<list.Total();i++) { COrder *obj=list.At(i); if(obj==NULL) continue; vol+=obj.Volume(); } return vol; } //+------------------------------------------------------------------+
このメソッドは、総ポジション数量メソッドと同じです。ただし、リストは「市場の未決注文」タイプと注文の方向(買いまたは売り)で並び替えられます。
以下は、取引操作の種類によって注文の方向を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the order direction by an operation type | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE CTrading::DirectionByActionType(ENUM_ACTION_TYPE action) const { if(action>ACTION_TYPE_SELL_STOP_LIMIT) return WRONG_VALUE; return ENUM_ORDER_TYPE(action%2); } //+------------------------------------------------------------------+
「close by」または「modification」タイプを受け取った場合、メソッドは -1を返します。それ以外の場合、取引操作タイプを2で割った超過分を返します。最終的には0(ORDER_TYPE_BUY)または1(ORDER_TYPE_SELL)になります。
以下は、チケットによってポジションの存在を確認するメソッドです。
//+------------------------------------------------------------------+ //| Check if a position is present by ticket | //+------------------------------------------------------------------+ bool CTrading::CheckPositionAvailablity(const ulong ticket,const string source_method) { CArrayObj* list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_POSITION,EQUAL); list.Sort(SORT_BY_ORDER_TICKET); list=CSelect::ByOrderProperty(list,ORDER_PROP_TICKET,ticket,EQUAL); if(list.Total()==1) return true; if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(source_method,CMessage::Text(MSG_LIB_SYS_ERROR_NO_OPEN_POSITION_WITH_TICKET),(string)ticket); return false; } //+------------------------------------------------------------------+
ここで、メソッドは確認されたポジションのチケットとソース名を受け取ります。
すべてのポジションと注文のリストを取得して、注文の「市場ポジション」ステータスでリストを並び替えます.
リストのチケットによる並び替えのフラグを設定します。
取得したリストは、入力によって渡されたチケットで並び替えられます。
リストに単一のオブジェクト(目的のチケットがあるポジション)が含まれている場合、
trueを返します。
その他の場合、ポジションがないことを通知して
falseを返します。
以下は、チケットによって未決注文の存在を確認するメソッドです。
//+------------------------------------------------------------------+ //| Check the presence of an order by ticket | //+------------------------------------------------------------------+ bool CTrading::CheckOrderAvailablity(const ulong ticket,const string source_method) { CArrayObj* list=this.m_market.GetList(); list=CSelect::ByOrderProperty(list,ORDER_PROP_STATUS,ORDER_STATUS_MARKET_PENDING,EQUAL); list.Sort(SORT_BY_ORDER_TICKET); list=CSelect::ByOrderProperty(list,ORDER_PROP_TICKET,ticket,EQUAL); if(list.Total()==1) return true; if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(source_method,CMessage::Text(MSG_LIB_SYS_ERROR_NO_PLACED_ORDER_WITH_TICKET),(string)ticket); return false; } //+------------------------------------------------------------------+
このメソッドは、 リストが「市場未決注文」ステータスによって並び替えられていることを除いて、前のメソッドと同じです。
以下は、指定された音声を取引オブジェクトに割り当てるメソッドです。
//+------------------------------------------------------------------+ //| Set a necessary sound to a trading object | //+------------------------------------------------------------------+ void CTrading::SetSoundByMode(const ENUM_MODE_SET_SOUND mode,const ENUM_ORDER_TYPE action,const string sound,CTradeObj *trade_obj) { switch(mode) { case MODE_SET_SOUND_OPEN : trade_obj.SetSoundOpen(action,sound); break; case MODE_SET_SOUND_CLOSE : trade_obj.SetSoundClose(action,sound); break; case MODE_SET_SOUND_MODIFY_SL : trade_obj.SetSoundModifySL(action,sound); break; case MODE_SET_SOUND_MODIFY_TP : trade_obj.SetSoundModifyTP(action,sound); break; case MODE_SET_SOUND_MODIFY_PRICE : trade_obj.SetSoundModifyPrice(action,sound); break; case MODE_SET_SOUND_ERROR_OPEN : trade_obj.SetSoundErrorOpen(action,sound); break; case MODE_SET_SOUND_ERROR_CLOSE : trade_obj.SetSoundErrorClose(action,sound); break; case MODE_SET_SOUND_ERROR_MODIFY_SL : trade_obj.SetSoundErrorModifySL(action,sound); break; case MODE_SET_SOUND_ERROR_MODIFY_TP : trade_obj.SetSoundErrorModifyTP(action,sound); break; case MODE_SET_SOUND_ERROR_MODIFY_PRICE : trade_obj.SetSoundErrorModifyPrice(action,sound); break; default: break; } } //+------------------------------------------------------------------+
メソッドは音声設定モード(各取引イベントで独自の音声)、音声が設定される取引イベントの注文タイプ、音声ファイル名(注文またはポジション取引イベントに割り当てられる音声)、音声を配置する取引オブジェクトへのポインタ(ターゲット銘柄カスタム取引イベント音声が設定されます)を受け取ります。
メソッドに渡されたモードに応じて、取引オブジェクトの音声を配置する適切な方法が設定されています。
以下は、前の記事で検討した銘柄取引オブジェクトパラメータを配置するメソッドと、ライブラリCEngine基本オブジェクトクラスに一時的に実装されたメソッドです。
void TradingSetCorrectTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL); void TradingSetTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL); void TradingSetCorrectTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL); void TradingSetTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL); void TradingSetMagic(const ulong magic,const string symbol_name=NULL); void TradingSetComment(const string comment,const string symbol_name=NULL); void TradingSetDeviation(const ulong deviation,const string symbol_name=NULL); void TradingSetVolume(const double volume=0,const string symbol_name=NULL); void TradingSetExpiration(const datetime expiration=0,const string symbol_name=NULL); void TradingSetAsyncMode(const bool mode=false,const string symbol_name=NULL); void TradingSetLogLevel(const ENUM_LOG_LEVEL log_level=LOG_LEVEL_ERROR_MSG,const string symbol_name=NULL);
これらは取引クラスに移動され、CEngineクラスで修正されました(ここにあるメソッドを単に呼び出します)。これらのメソッドは以前に検討したことがあるので、ここで説明する意味はありません。以下に添付されているファイルで実装をご覧になれます。
以下は、標準取引オブジェクトを設定するメソッドです。
//+------------------------------------------------------------------+ //| Set standard sounds for a symbol trading object | //+------------------------------------------------------------------+ void CTrading::SetSoundsStandart(const string symbol=NULL) { //--- Declare an empty symbol object CSymbol *symbol_obj=NULL; //--- If NULL is passed as a symbol name, set sounds for trading objects of all symbols if(symbol==NULL) { //--- Get the symbol list CArrayObj *list=this.m_symbols.GetList(); if(list==NULL || list.Total()==0) return; //--- In a loop by the list of symbols int total=list.Total(); for(int i=0;i<total;i++) { //--- get the next symbol object symbol_obj=list.At(i); if(symbol_obj==NULL) continue; //--- get a symbol trading object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) continue; //--- set standard sounds for a trading object trade_obj.SetSoundsStandart(); } } //--- If a symbol name is passed else { //--- get a symbol trading object CTradeObj *trade_obj=this.GetTradeObjBySymbol(symbol,DFUN); if(trade_obj==NULL) return; //--- set standard sounds for a trading object trade_obj.SetSoundsStandart(); } } //+------------------------------------------------------------------+
以下は、指定された注文に対して指定された取引イベントの音声を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set a sound for a specified order/position type and symbol | //| 'mode' specifies an event a sound is set for | //| (symbol=NULL) for trading objects of all symbols, | //| (symbol!=NULL) for a trading object of a specified symbol | //+------------------------------------------------------------------+ void CTrading::SetSound(const ENUM_MODE_SET_SOUND mode,const ENUM_ORDER_TYPE action,const string sound,const string symbol=NULL) { //--- Declare an empty symbol object CSymbol *symbol_obj=NULL; //--- If NULL is passed as a symbol name, set sounds for trading objects of all symbols if(symbol==NULL) { //--- Get the symbol list CArrayObj *list=this.m_symbols.GetList(); if(list==NULL || list.Total()==0) return; //--- In a loop by the list of symbols int total=list.Total(); for(int i=0;i<total;i++) { //--- get the next symbol object symbol_obj=list.At(i); if(symbol_obj==NULL) continue; //--- get a symbol trading object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) continue; //--- set a sound of a necessary event for a trading object this.SetSoundByMode(mode,action,sound,trade_obj); } } //--- If a symbol name is passed else { //--- get a symbol trading object CTradeObj *trade_obj=this.GetTradeObjBySymbol(symbol,DFUN); if(trade_obj==NULL) return; //--- set a sound of a necessary event for a trading object this.SetSoundByMode(mode,action,sound,trade_obj); } } //+------------------------------------------------------------------+
両方のメソッドのすべてのアクションは、コードのコメントで説明されています。
本稿では、取引制限を検証をする初期的メソッドを作成します。このカテゴリには何を割り当てることができるかと言えば、取引操作を行うために資金が十分であるかの確認です。資金が不足している場合、リクエストを送信しても意味がありません。このタイプの制限の除去には時間がかかります。使用できる資金の増加(取引戦略に応じた計画的なポジション決済と利益(損失)の獲得による、ポジションをサポートするために必要な証拠金の解放、または損失を強制的に決済することで証拠金のみを返す、または口座への入金)を待つ必要があります。現時点では、ここで取引リクエストを実行できないというフラグを返す方がはるかに簡単です。
さらに、ターミナルでの自動取引の無効化、設定でのEAの自動取引の無効化、サーバ側または特定の銘柄の自動取引の無効化、およびその他の追加要因もあります。
この記事で取引クラスに実装するのはこれだけです。
以下は、取引操作を実行するために資金が十分であるかを確認するメソッドです。
//+------------------------------------------------------------------+ //| Check if the funds are sufficient | //+------------------------------------------------------------------+ bool CTrading::CheckMoneyFree(const ENUM_ORDER_TYPE order_type,const double volume,const double price,const CSymbol *symbol_obj,const string source_method) const { ::ResetLastError(); //--- Get the type of a market order by a trading operation type ENUM_ORDER_TYPE action=this.DirectionByActionType((ENUM_ACTION_TYPE)order_type); //--- Get the value of free funds to be left after conducting a trading operation double money_free= ( //--- For MQL5, calculate the difference between free funds and the funds required to conduct a trading operation #ifdef __MQL5__ this.m_account.MarginFree()-this.m_account.MarginForAction(action,symbol_obj.Name(),volume,price) //--- For MQL4, use the operation result of the standard function returning the amount of funds left #else/*__MQL4__*/::AccountFreeMarginCheck(symbol_obj.Name(),order_type,volume) #endif ); //--- If no free funds are left, inform of that and return 'false' if(money_free<=0 #ifdef __MQL4__ || ::GetLastError()==134 #endif ) { if(this.m_log_level>LOG_LEVEL_NO_MSG) { //--- create a message text string message= ( symbol_obj.Name()+" "+::DoubleToString(volume,symbol_obj.DigitsLot())+" "+ ( order_type>ORDER_TYPE_SELL ? OrderTypeDescription(order_type,false,false) : PositionTypeDescription(PositionTypeByOrderType(order_type)) )+" ("+::DoubleToString(money_free,(int)this.m_account.CurrencyDigits())+")" ); //--- display a journal message if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(source_method,CMessage::Text(MSG_LIB_TEXT_NOT_ENOUTH_MONEY_FOR),message); } return false; } //--- Verification successful return true; } //+------------------------------------------------------------------+
以下は、取引操作を行うための制限を確認するメソッドです。
//+------------------------------------------------------------------+ //| Check trading limitations | //+------------------------------------------------------------------+ bool CTrading::CheckTradeConstraints(const double volume, const ENUM_ACTION_TYPE action_type, const CSymbol *symbol_obj, const string source_method, double sl=0, double tp=0) { //--- the result of conducting all checks bool res=true; //--- Clear the error list (codes of found limitations) this.m_list_errors.Clear(); this.m_list_errors.Sort(); //--- Check connection with the trade server (not in the test mode) if(!::TerminalInfoInteger(TERMINAL_CONNECTED)) { if(!::MQLInfoInteger(MQL_TESTER)) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_TERMINAL_NOT_CONNECTED); res &=false; } } //--- Check if trading is enabled for an account (if there is a connection with the trade server) else if(!this.m_account.TradeAllowed()) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_ACCOUNT_NOT_TRADE_ENABLED); res &=false; } //--- Check if trading is allowed for any EAs/scripts for the current account if(!this.m_account.TradeExpert()) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_ACCOUNT_EA_NOT_TRADE_ENABLED); res &=false; } //--- Check if auto trading is allowed in the terminal. //--- AutoTrading button (Options --> Expert Advisors --> "Allowed automated trading") if(!::TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_TERMINAL_NOT_TRADE_ENABLED); res &=false; } //--- Check if auto trading is allowed for the current EA. //--- (F7 --> Common --> Allow Automated Trading) if(!::MQLInfoInteger(MQL_TRADE_ALLOWED)) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_EA_NOT_TRADE_ENABLED); res &=false; } //--- Check if trading is enabled on a symbol. //--- If trading is disabled, add the error code to the list and write 'false' to the result if(symbol_obj.TradeMode()==SYMBOL_TRADE_MODE_DISABLED) { this.AddErrorCodeToList(MSG_SYM_TRADE_MODE_DISABLED); res &=false; } //--- If not closing/removal/modification if(action_type>WRONG_VALUE && action_type<ACTION_TYPE_CLOSE_BY) { //--- In case of close-only, add the error code to the list and write 'false' to the result if(symbol_obj.TradeMode()==SYMBOL_TRADE_MODE_CLOSEONLY) { this.AddErrorCodeToList(MSG_SYM_TRADE_MODE_CLOSEONLY); res &=false; } //--- Check the minimum volume if(volume<symbol_obj.LotsMin()) { //--- The volume in a request is less than the minimum allowed one //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_REQ_VOL_LESS_MIN_VOLUME); res &=false; } //--- Check the maximum volume else if(volume>symbol_obj.LotsMax()) { //--- The volume in the request exceeds the maximum acceptable one //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_REQ_VOL_MORE_MAX_VOLUME); res &=false; } //--- Check the minimum volume gradation double step=symbol_obj.LotsStep(); if(fabs((int)round(volume/step)*step-volume)>0.0000001) { //--- The volume in the request is not a multiple of the minimum gradation of the lot change step //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_INVALID_VOLUME_STEP); res &=false; } } //--- When opening a position if(action_type>WRONG_VALUE && action_type<ACTION_TYPE_BUY_LIMIT) { //--- Check if sending market orders is allowed on a symbol. //--- If trading market orders is disabled, add the error code to the list and write 'false' to the result if(!symbol_obj.IsMarketOrdersAllowed()) { this.AddErrorCodeToList(MSG_SYM_MARKET_ORDER_DISABLED); res &=false; } } //--- When placing a pending order else if(action_type>ACTION_TYPE_SELL && action_type<ACTION_TYPE_CLOSE_BY) { //--- If there is a limitation on the number of pending orders on the account //--- and placing a new order exceeds the acceptable number if(this.m_account.LimitOrders()>0 && this.OrdersTotalAll()+1 > this.m_account.LimitOrders()) { //--- The maximum number of pending orders is reached //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(10033); res &=false; } //--- Check if placing limit orders is allowed on a symbol. if(action_type==ACTION_TYPE_BUY_LIMIT || action_type==ACTION_TYPE_SELL_LIMIT) { //--- If it is not, add the error code to the list and write 'false' to the result if(!symbol_obj.IsLimitOrdersAllowed()) { this.AddErrorCodeToList(MSG_SYM_LIMIT_ORDER_DISABLED); res &=false; } } //--- Check if placing stop orders is allowed on a symbol. else if(action_type==ACTION_TYPE_BUY_STOP || action_type==ACTION_TYPE_SELL_STOP) { //--- If placing stop orders is disabled, add the error code to the list and write 'false' to the result if(!symbol_obj.IsStopOrdersAllowed()) { this.AddErrorCodeToList(MSG_SYM_STOP_ORDER_DISABLED); res &=false; } } //--- For MQL5, check if placing stop limit orders is allowed on a symbol. #ifdef __MQL5__ else if(action_type==ACTION_TYPE_BUY_STOP_LIMIT || action_type==ACTION_TYPE_SELL_STOP_LIMIT) { //--- If it is not, add the error code to the list and write 'false' to the result if(!symbol_obj.IsStopLimitOrdersAllowed()) { this.AddErrorCodeToList(MSG_SYM_STOP_LIMIT_ORDER_DISABLED); res &=false; } } #endif } //--- In case of opening/placing/modification if(action_type>WRONG_VALUE && action_type!=ACTION_TYPE_CLOSE_BY) { //--- If not modification if(action_type!=ACTION_TYPE_MODIFY) { //--- When buying, check if long trading is enabled on a symbol if(this.DirectionByActionType(action_type)==ORDER_TYPE_BUY) { //--- If only selling is allowed, add the error code to the list and write 'false' to the result if(symbol_obj.TradeMode()==SYMBOL_TRADE_MODE_SHORTONLY) { this.AddErrorCodeToList(MSG_SYM_TRADE_MODE_SHORTONLY); res &=false; } //--- If a symbol has the limitation on the total volume of an open position and pending orders in the same direction if(symbol_obj.VolumeLimit()>0) { //--- (If the total volume of placed long orders and open long positions)+open volume exceed the maximum one if(this.OrdersTotalVolumeLong()+this.PositionsTotalVolumeLong()+volume > symbol_obj.VolumeLimit()) { //--- Exceeded maximum allowed aggregate volume of orders and positions in one direction //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_MAX_VOLUME_LIMIT_EXCEEDED); res &=false; } } } //--- When selling, check if short trading is enabled on a symbol else if(this.DirectionByActionType(action_type)==ORDER_TYPE_SELL) { //--- If only buying is allowed, add the error code to the list and write 'false' to the result if(symbol_obj.TradeMode()==SYMBOL_TRADE_MODE_LONGONLY) { this.AddErrorCodeToList(MSG_SYM_TRADE_MODE_LONGONLY); res &=false; } //--- If a symbol has the limitation on the total volume of an open position and pending orders in the same direction if(symbol_obj.VolumeLimit()>0) { //--- (If the total volume of placed short orders and open short positions)+open volume exceed the maximum one if(this.OrdersTotalVolumeShort()+this.PositionsTotalVolumeShort()+volume > symbol_obj.VolumeLimit()) { //--- Exceeded maximum allowed aggregate volume of orders and positions in one direction //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_MAX_VOLUME_LIMIT_EXCEEDED); res &=false; } } } } //--- If the request features StopLoss and its placing is not allowed if(sl>0 && !symbol_obj.IsStopLossOrdersAllowed()) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_SYM_SL_ORDER_DISABLED); res &=false; } //--- If the request features TakeProfit and its placing is not allowed if(tp>0 && !symbol_obj.IsTakeProfitOrdersAllowed()) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_SYM_TP_ORDER_DISABLED); res &=false; } } //--- 反対ポジションによる決済 else if(action_type==ACTION_TYPE_CLOSE_BY) { //--- When closing by an opposite position is disabled if(!symbol_obj.IsCloseByOrdersAllowed()) { //--- add the error code to the list and write 'false' to the result this.AddErrorCodeToList(MSG_LIB_TEXT_CLOSE_BY_ORDERS_DISABLED); res &=false; } } //--- If there are limitations, display the header and the error list if(!res) { //--- Request was rejected before sending to the server due to: int total=this.m_list_errors.Total(); if(this.m_log_level>LOG_LEVEL_NO_MSG) { //--- For MQL5, first display the list header followed by the error list #ifdef __MQL5__ ::Print(source_method,CMessage::Text(MSG_LIB_TEXT_REQUEST_REJECTED_DUE)); for(int i=0;i<total;i++) ::Print((total>1 ? string(i+1)+". " : ""),CMessage::Text(m_list_errors.At(i))); //--- For MQL4, the journal messages are displayed in the reverse order: the error list is followed by the list header #else for(int i=total-1;i>WRONG_VALUE;i--) ::Print((total>1 ? string(i+1)+". " : ""),CMessage::Text(m_list_errors.At(i))); ::Print(source_method,CMessage::Text(MSG_LIB_TEXT_REQUEST_REJECTED_DUE)); #endif } } return res; } //+------------------------------------------------------------------+
このメソッドは非常に長いですが、すべてがすでにここでよく知られています。制限される可能性のあるプログラム、ターミナル、口座、銘柄のプロパティを確認して、制限がある場合は、検出された制限のコードをリストに追加し、結果フラグにfalseを追加します。すべてを確認した後で、変数にfalseが含まれている場合、検出された制限のリストのヘッダを表示し、制限コードのリストによってループ内のヘッダの下に検出されたすべての取引制限を表示します。確認結果を保存する変数にtrue(初期値)がある場合、すべてのチェックに合格したのでtrueが返されます。
現在のバージョンの取引クラスでは、この時点で止めます。後にエラー処理メソッドを作成する際に、制限およびエラーに対応するすべてのアクションはこのクラスで処理されます。
以下は、クラス取引メソッドです。
//+------------------------------------------------------------------+ //| Open Buy position | //+------------------------------------------------------------------+ bool CTrading::OpenBuy(const double volume,const string symbol,const ulong magic=ULONG_MAX,double sl=0,double tp=0,const string comment=NULL) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_BUY,symbol_obj,DFUN,sl,tp)) { return false; } //--- If the funds are insufficient, inform of that and exit if(!this.CheckMoneyFree(ORDER_TYPE_BUY,volume,symbol_obj.Ask(),symbol_obj,DFUN)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.OpenPosition(POSITION_TYPE_BUY,volume,sl,tp,magic,trade_obj.GetDeviation(),comment); } //+------------------------------------------------------------------+ //| Open a Sell position | //+------------------------------------------------------------------+ bool CTrading::OpenSell(const double volume,const string symbol,const ulong magic=ULONG_MAX,double sl=0,double tp=0,const string comment=NULL) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_SELL,symbol_obj,DFUN,sl,tp)) { return false; } //--- If the funds are insufficient, inform of that and exit if(!this.CheckMoneyFree(ORDER_TYPE_SELL,volume,symbol_obj.Bid(),symbol_obj,DFUN)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.OpenPosition(POSITION_TYPE_SELL,volume,sl,tp,magic,trade_obj.GetDeviation(),comment); } //+------------------------------------------------------------------+ //| Modify a position | //+------------------------------------------------------------------+ bool CTrading::ModifyPosition(const ulong ticket,const double sl=WRONG_VALUE,const double tp=WRONG_VALUE) { //--- Get a symbol object by a position ticket CSymbol *symbol_obj=this.GetSymbolObjByPosition(ticket,DFUN); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(0,ACTION_TYPE_MODIFY,symbol_obj,DFUN,sl,tp)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.ModifyPosition(ticket,sl,tp); } //+------------------------------------------------------------------+ //| Close a position in full | //+------------------------------------------------------------------+ bool CTrading::ClosePosition(const ulong ticket) { //--- Get a symbol object by a position ticket CSymbol *symbol_obj=this.GetSymbolObjByPosition(ticket,DFUN); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(0,WRONG_VALUE,symbol_obj,DFUN)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.ClosePosition(ticket); } //+------------------------------------------------------------------+ //| Close a position partially | //+------------------------------------------------------------------+ bool CTrading::ClosePositionPartially(const ulong ticket,const double volume) { //--- Get a symbol object by a position ticket CSymbol *symbol_obj=this.GetSymbolObjByPosition(ticket,DFUN); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(0,WRONG_VALUE,symbol_obj,DFUN)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.ClosePositionPartially(ticket,symbol_obj.NormalizedLot(volume)); } //+------------------------------------------------------------------+ //| Close a position by an opposite one | //+------------------------------------------------------------------+ bool CTrading::ClosePositionBy(const ulong ticket,const ulong ticket_by) { //--- Get a symbol object by a position ticket CSymbol *symbol_obj=this.GetSymbolObjByPosition(ticket,DFUN); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(0,ACTION_TYPE_CLOSE_BY,symbol_obj,DFUN)) { return false; } //--- trading object of a closed position CTradeObj *trade_obj_pos=this.GetTradeObjByPosition(ticket,DFUN); if(trade_obj_pos==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- check the presence of an opposite position if(!this.CheckPositionAvailablity(ticket_by,DFUN)) return false; //--- trading object of an opposite position CTradeObj *trade_obj_pos_by=this.GetTradeObjByPosition(ticket_by,DFUN); if(trade_obj_pos_by==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- If a symbol of a closed position is not equal to an opposite position's one, inform of that and exit if(symbol_obj.Name()!=trade_obj_pos_by.GetSymbol()) { //--- Symbols of opposite positions are not equal if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_TEXT_CLOSE_BY_SYMBOLS_UNEQUAL)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj_pos.ClosePositionBy(ticket,ticket_by); } //+------------------------------------------------------------------+ //| Place BuyStop pending order | //+------------------------------------------------------------------+ bool CTrading::PlaceBuyStop(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_BUY_STOP,symbol_obj,DFUN,sl,tp)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.SetOrder(ORDER_TYPE_BUY_STOP,volume,price,sl,tp,0,magic,expiration,type_time,comment); } //+------------------------------------------------------------------+ //| Place BuyLimit pending order | //+------------------------------------------------------------------+ bool CTrading::PlaceBuyLimit(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_BUY_LIMIT,symbol_obj,DFUN,sl,tp)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.SetOrder(ORDER_TYPE_BUY_LIMIT,volume,price,sl,tp,0,magic,expiration,type_time,comment); } //+------------------------------------------------------------------+ //| Place BuyStopLimit pending order | //+------------------------------------------------------------------+ bool CTrading::PlaceBuyStopLimit(const double volume, const string symbol, const double price_stop, const double price_limit, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_BUY_STOP_LIMIT,symbol_obj,DFUN,sl,tp)) { return false; } #ifdef __MQL5__ //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.SetOrder(ORDER_TYPE_BUY_STOP_LIMIT,volume,price_stop,sl,tp,price_limit,magic,expiration,type_time,comment); //--- MQL4 #else return true; #endif } //+------------------------------------------------------------------+ //| Place SellStop pending order | //+------------------------------------------------------------------+ bool CTrading::PlaceSellStop(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_SELL_STOP,symbol_obj,DFUN,sl,tp)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.SetOrder(ORDER_TYPE_SELL_STOP,volume,price,sl,tp,0,magic,expiration,type_time,comment); } //+------------------------------------------------------------------+ //| Place SellLimit pending order | //+------------------------------------------------------------------+ bool CTrading::PlaceSellLimit(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_SELL_LIMIT,symbol_obj,DFUN,sl,tp)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.SetOrder(ORDER_TYPE_SELL_LIMIT,volume,price,sl,tp,0,magic,expiration,type_time,comment); } //+------------------------------------------------------------------+ //| Place SellStopLimit pending order | //+------------------------------------------------------------------+ bool CTrading::PlaceSellStopLimit(const double volume, const string symbol, const double price_stop, const double price_limit, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { //--- Get a symbol object by a symbol name CSymbol *symbol_obj=this.m_symbols.GetSymbolObjByName(symbol); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(volume,ACTION_TYPE_SELL_STOP_LIMIT,symbol_obj,DFUN,sl,tp)) { return false; } #ifdef __MQL5__ //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.SetOrder(ORDER_TYPE_SELL_STOP_LIMIT,volume,price_stop,sl,tp,price_limit,magic,expiration,type_time,comment); //--- MQL4 #else return true; #endif } //+------------------------------------------------------------------+ //| Modify a pending order | //+------------------------------------------------------------------+ bool CTrading::ModifyOrder(const ulong ticket, const double price=WRONG_VALUE, const double sl=WRONG_VALUE, const double tp=WRONG_VALUE, const double stoplimit=WRONG_VALUE, datetime expiration=WRONG_VALUE, ENUM_ORDER_TYPE_TIME type_time=WRONG_VALUE) { //--- Get a symbol object by an order ticket CSymbol *symbol_obj=this.GetSymbolObjByOrder(ticket,DFUN); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(0,ACTION_TYPE_MODIFY,symbol_obj,DFUN,sl,tp)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.ModifyOrder(ticket,price,sl,tp,stoplimit,expiration,type_time); } //+------------------------------------------------------------------+ //| Remove a pending order | //+------------------------------------------------------------------+ bool CTrading::DeleteOrder(const ulong ticket) { //--- Get a symbol object by an order ticket CSymbol *symbol_obj=this.GetSymbolObjByOrder(ticket,DFUN); //--- If failed to get the symbol object, display the message and return 'false' if(symbol_obj==NULL) { if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_SYM_OBJ)); return false; } //--- Update symbol quotes symbol_obj.RefreshRates(); //--- If there are trading limitations, inform of that and exit if(!this.CheckTradeConstraints(0,WRONG_VALUE,symbol_obj,DFUN)) { return false; } //--- get a trading object from a symbol object CTradeObj *trade_obj=symbol_obj.GetTradeObj(); if(trade_obj==NULL) { //--- Error. Failed to get trading object if(this.m_log_level>LOG_LEVEL_NO_MSG) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_ERROR_FAILED_GET_TRADE_OBJ)); return false; } //--- Return the result of sending a trading request in a symbol trading object return trade_obj.DeleteOrder(ticket); } //+------------------------------------------------------------------+
以前の記事で基本取引オブジェクトを作成する際に、取引メソッド(サーバへの取引リクエストの送信)を検討しました。ここでは、同様の署名を持つメソッドは、取引リクエストの必要なパラメータを受け取り、上で検討した取引制限が確認され、銘柄基本取引オブジェクトの適切なメソッドが呼び出されます。作業メソッドの結果がプログラムに返されます。
この段階では、これらは取引リクエストを送信する前に行われるすべての確認です。取引リクエストパラメータの有効性を確認して処理する必要があるため、これらをさらに拡張します。ここで、すべてのパラメータが既に有効であると想定されています。
これで、現在の実装の取引クラスに計画された機能が備わりました。
次に、ライブラリCEngine基本オブジェクトからアクセスし、それを介してクラス取引メソッドを使用する必要があります。
\MQL5\Include\DoEasy\Engine.mqhを開いて、必要な変更を加えます。
まず、取引クラスをインクルードします。
//+------------------------------------------------------------------+ //| Engine.mqh | //| Copyright 2019, MetaQuotes Software Corp. | //| https://mql5.com/ja/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2019, MetaQuotes Software Corp." #property link "https://mql5.com/ja/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| ファイルをインクルードする | //+------------------------------------------------------------------+ #include "Services\TimerCounter.mqh" #include "Collections\HistoryCollection.mqh" #include "Collections\MarketCollection.mqh" #include "Collections\EventsCollection.mqh" #include "Collections\AccountsCollection.mqh" #include "Collections\SymbolsCollection.mqh" #include "Collections\ResourceCollection.mqh" #include "Trading.mqh" //+------------------------------------------------------------------+
クラスのprivateセクションで取引クラスオブジェクトを宣言します。
//+------------------------------------------------------------------+ //| ライブラリ基本クラス | //+------------------------------------------------------------------+ class CEngine { private: CHistoryCollection m_history; // 過去の注文と取引のコレクション CMarketCollection m_market; // 注文と取引のコレクション CEventsCollection m_events; // Event collection CAccountsCollection m_accounts; // Account collection CSymbolsCollection m_symbols; // Symbol collection CResourceCollection m_resource; // Resource list CTrading m_trading; // Trading class object CArrayObj m_list_counters; // タイマーカウンタのリスト int m_global_error; // Global error code bool m_first_start; // 初期実行フラグ bool m_is_hedge; // ヘッジ勘定フラグ bool m_is_tester; // Flag of working in the tester bool m_is_market_trade_event; // 口座取引イベントフラグ bool m_is_history_trade_event; // 口座過去の取引イベントフラグ bool m_is_account_event; // Account change event flag bool m_is_symbol_event; // Symbol change event flag ENUM_TRADE_EVENT m_last_trade_event; // Last account trading event int m_last_account_event; // Last event in the account properties int m_last_symbol_event; // Last event in the symbol properties //--- IDによるカウンタインデックスを返す
以下のメソッド
//--- Set the following for the trading classes: //--- (1) correct filling policy, (2) filling policy, //--- (3) correct order expiration type, (4) order expiration type, //--- (5) magic number, (6) comment, (7) slippage, (8) volume, (9) order expiration date, //--- (10) the flag of asynchronous sending of a trading request, (11) logging level void SetTradeCorrectTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL); void SetTradeTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL); void SetTradeCorrectTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL); void SetTradeTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL); void SetTradeMagic(const ulong magic,const string symbol_name=NULL); void SetTradeComment(const string comment,const string symbol_name=NULL); void SetTradeDeviation(const ulong deviation,const string symbol_name=NULL); void SetTradeVolume(const double volume=0,const string symbol_name=NULL); void SetTradeExpiration(const datetime expiration=0,const string symbol_name=NULL); void SetTradeAsyncMode(const bool mode=false,const string symbol_name=NULL); void SetTradeLogLevel(const ENUM_LOG_LEVEL log_level=LOG_LEVEL_ERROR_MSG,const string symbol_name=NULL);
が以下に名前変更されます。
//--- Set the following for the trading classes: //--- (1) correct filling policy, (2) filling policy, //--- (3) correct order expiration type, (4) order expiration type, //--- (5) magic number, (6) comment, (7) slippage, (8) volume, (9) order expiration date, //--- (10) the flag of asynchronous sending of a trading request, (11) logging level void TradingSetCorrectTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL); void TradingSetTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL); void TradingSetCorrectTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL); void TradingSetTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL); void TradingSetMagic(const ulong magic,const string symbol_name=NULL); void TradingSetComment(const string comment,const string symbol_name=NULL); void TradingSetDeviation(const ulong deviation,const string symbol_name=NULL); void TradingSetVolume(const double volume=0,const string symbol_name=NULL); void TradingSetExpiration(const datetime expiration=0,const string symbol_name=NULL); void TradingSetAsyncMode(const bool mode=false,const string symbol_name=NULL); void TradingSetLogLevel(const ENUM_LOG_LEVEL log_level=LOG_LEVEL_ERROR_MSG,const string symbol_name=NULL);
これで、名前が取引クラスへの所属を示すようになります。
クラスのpublicセクションで、標準音声を設定するためのメソッド、指定されたポジション/注文タイプおよび取引イベントの音声および必要なすべてのコレクションリストへのポインタを取引クラスに送信するメソッドを追加します。また、説明によってサウンドを再生するメソッドを宣言します。
//--- Set standard sounds (symbol==NULL) for a symbol trading object, (symbol!=NULL) for trading objects of all symbols void SetSoundsStandart(const string symbol=NULL) { this.m_trading.SetSoundsStandart(symbol); } //--- Set a sound for a specified order/position type and symbol. 'mode' specifies an event a sound is set for //--- (symbol=NULL) for trading objects of all symbols, (symbol!=NULL) for a trading object of a specified symbol void SetSound(const ENUM_MODE_SET_SOUND mode,const ENUM_ORDER_TYPE action,const string sound,const string symbol=NULL) { this.m_trading.SetSound(mode,action,sound,symbol); } //--- Play a sound by its description bool PlaySoundByDescription(const string sound_description); //--- Pass the pointers to all the necessary collections to the trading class void TradingOnInit(void) { this.m_trading.OnInit(this.GetAccountCurrent(),m_symbols.GetObject(),m_market.GetObject(),m_history.GetObject()); }
3つのメソッドは、同じ名前の取引クラスメソッドを呼び出すだけです。以下の説明により、音声を再生するメソッドを考えてみましょう。
//+------------------------------------------------------------------+ //| Play a sound by its description | //+------------------------------------------------------------------+ bool CEngine::PlaySoundByDescription(const string sound_description) { string file_name=NULL; //--- Get the list of resources CArrayObj* list=this.GetListResource(); if(list==NULL) return false; //--- Get an index of a resource object by its description int index=this.m_resource.GetIndexResObjByDescription(sound_description); //--- If a resource object with a specified description is found in the list if(index>WRONG_VALUE) { //--- Get a resource object by its index in the list CResObj *res_obj=list.At(index); if(res_obj==NULL) return false; //--- Get a resource object file name file_name=res_obj.FileName(); } //--- If there is no resource object with a specified description in the list, attempt to play the file by the name written in its description //--- To do this, make sure that either a standard audio file (macro substitution of its name), //--- or a name of a new *.wav audio file is passed as a description else if(::StringFind(sound_description,"SND_")==0 || StringSubstr(sound_description,StringLen(sound_description)-4)==".wav") file_name=sound_description; //--- Return the file playing result return(file_name!=NULL ? CMessage::PlaySound(file_name) : false); } //+------------------------------------------------------------------+
以前は、音声ファイルと画像ファイルを保存できるリソースオブジェクトを作成しました。その種類の各リソースに説明を追加する機能を追加したため、再生する音声ファイルを指定するのが簡単になりました。例えば、名前よりもパーソナライズされたファイルの記述を覚える方がはるかに簡単なため、ファイル名に「特徴がない」(sound_01.wavなど)場合、「EURUSDを買う音」などの説明を設定できます。
このメソッドでは、パラメータで必要なファイルの説明を指定できます。一致する説明を持つリソースオブジェクトを検出し、音声を再生します。オプションで、このメソッドは、Defines.mqhで作成した名前と未知の音声ファイルのマクロ置換によって標準音声を再生できます。その名前を説明として渡すだけです。このようなファイルは、端末サンドボックスに配置され、wav拡張子を持ち、名前に正しいパスが指定されている必要があります。
CEngineクラスに一時的に配置した取引メソッド、および取引オブジェクトのパラメータを設定するメソッドとCEngineに一時的に配置されたメソッドが変更されました。これらすべてのメソッドとその実装は、取引クラスに移動され、< b0>適切な取引クラスメソッドがCEngineクラスメソッドから単に呼び出されます。
//+------------------------------------------------------------------+ //| Open Buy position | //+------------------------------------------------------------------+ bool CEngine::OpenBuy(const double volume,const string symbol,const ulong magic=ULONG_MAX,double sl=0,double tp=0,const string comment=NULL) { return this.m_trading.OpenBuy(volume,symbol,magic,sl,tp,comment); } //+------------------------------------------------------------------+ //| Open a Sell position | //+------------------------------------------------------------------+ bool CEngine::OpenSell(const double volume,const string symbol,const ulong magic=ULONG_MAX,double sl=0,double tp=0,const string comment=NULL) { return this.m_trading.OpenSell(volume,symbol,magic,sl,tp,comment); } //+------------------------------------------------------------------+ //| Modify a position | //+------------------------------------------------------------------+ bool CEngine::ModifyPosition(const ulong ticket,const double sl=WRONG_VALUE,const double tp=WRONG_VALUE) { return this.m_trading.ModifyPosition(ticket,sl,tp); } //+------------------------------------------------------------------+ //| Close a position in full | //+------------------------------------------------------------------+ bool CEngine::ClosePosition(const ulong ticket) { return this.m_trading.ClosePosition(ticket); } //+------------------------------------------------------------------+ //| Close a position partially | //+------------------------------------------------------------------+ bool CEngine::ClosePositionPartially(const ulong ticket,const double volume) { return this.m_trading.ClosePositionPartially(ticket,volume); } //+------------------------------------------------------------------+ //| Close a position by an opposite one | //+------------------------------------------------------------------+ bool CEngine::ClosePositionBy(const ulong ticket,const ulong ticket_by) { return this.m_trading.ClosePositionBy(ticket,ticket_by); } //+------------------------------------------------------------------+ //| Place BuyStop pending order | //+------------------------------------------------------------------+ bool CEngine::PlaceBuyStop(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { return this.m_trading.PlaceBuyStop(volume,symbol,price,sl,tp,magic,comment,expiration,type_time); } //+------------------------------------------------------------------+ //| Place BuyLimit pending order | //+------------------------------------------------------------------+ bool CEngine::PlaceBuyLimit(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { return this.m_trading.PlaceBuyLimit(volume,symbol,price,sl,tp,magic,comment,expiration,type_time); } //+------------------------------------------------------------------+ //| Place BuyStopLimit pending order | //+------------------------------------------------------------------+ bool CEngine::PlaceBuyStopLimit(const double volume, const string symbol, const double price_stop, const double price_limit, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { return this.m_trading.PlaceBuyStopLimit(volume,symbol,price_stop,price_limit,sl,tp,magic,comment,expiration,type_time); } //+------------------------------------------------------------------+ //| Place SellStop pending order | //+------------------------------------------------------------------+ bool CEngine::PlaceSellStop(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { return this.m_trading.PlaceSellStop(volume,symbol,price,sl,tp,magic,comment,expiration,type_time); } //+------------------------------------------------------------------+ //| Place SellLimit pending order | //+------------------------------------------------------------------+ bool CEngine::PlaceSellLimit(const double volume, const string symbol, const double price, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { return this.m_trading.PlaceSellLimit(volume,symbol,price,sl,tp,magic,comment,expiration,type_time); } //+------------------------------------------------------------------+ //| Place SellStopLimit pending order | //+------------------------------------------------------------------+ bool CEngine::PlaceSellStopLimit(const double volume, const string symbol, const double price_stop, const double price_limit, const double sl=0, const double tp=0, const ulong magic=WRONG_VALUE, const string comment=NULL, const datetime expiration=0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC) { return this.m_trading.PlaceSellStopLimit(volume,symbol,price_stop,price_limit,sl,tp,magic,comment,expiration,type_time); } //+------------------------------------------------------------------+ //| Modify a pending order | //+------------------------------------------------------------------+ bool CEngine::ModifyOrder(const ulong ticket, const double price=WRONG_VALUE, const double sl=WRONG_VALUE, const double tp=WRONG_VALUE, const double stoplimit=WRONG_VALUE, datetime expiration=WRONG_VALUE, ENUM_ORDER_TYPE_TIME type_time=WRONG_VALUE) { return this.m_trading.ModifyOrder(ticket,price,sl,tp,stoplimit,expiration,type_time); } //+------------------------------------------------------------------+ //| Remove a pending order | //+------------------------------------------------------------------+ bool CEngine::DeleteOrder(const ulong ticket) { return this.m_trading.DeleteOrder(ticket); } //+------------------------------------------------------------------+ //| Set the valid filling policy | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetCorrectTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL) { this.m_trading.SetCorrectTypeFilling(type,symbol_name); } //+------------------------------------------------------------------+ //| Set the filling policy | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_FOK,const string symbol_name=NULL) { this.m_trading.SetTypeFilling(type,symbol_name); } //+------------------------------------------------------------------+ //| Set a correct order expiration type | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetCorrectTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL) { this.m_trading.SetCorrectTypeExpiration(type,symbol_name); } //+------------------------------------------------------------------+ //| Set an order expiration type | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetTypeExpiration(const ENUM_ORDER_TYPE_TIME type=ORDER_TIME_GTC,const string symbol_name=NULL) { this.m_trading.SetTypeExpiration(type,symbol_name); } //+------------------------------------------------------------------+ //| Set a magic number for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetMagic(const ulong magic,const string symbol_name=NULL) { this.m_trading.SetMagic(magic,symbol_name); } //+------------------------------------------------------------------+ //| Set a comment for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetComment(const string comment,const string symbol_name=NULL) { this.m_trading.SetComment(comment,symbol_name); } //+------------------------------------------------------------------+ //| Set a slippage | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetDeviation(const ulong deviation,const string symbol_name=NULL) { this.m_trading.SetDeviation(deviation,symbol_name); } //+------------------------------------------------------------------+ //| Set a volume for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetVolume(const double volume=0,const string symbol_name=NULL) { this.m_trading.SetVolume(volume,symbol_name); } //+------------------------------------------------------------------+ //| Set an order expiration date | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetExpiration(const datetime expiration=0,const string symbol_name=NULL) { this.m_trading.SetExpiration(expiration,symbol_name); } //+------------------------------------------------------------------+ //| Set the flag of asynchronous sending of trading requests | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetAsyncMode(const bool mode=false,const string symbol_name=NULL) { this.m_trading.SetAsyncMode(mode,symbol_name); } //+------------------------------------------------------------------+ //| Set a logging level of trading requests | //| for trading objects of all symbols | //+------------------------------------------------------------------+ void CEngine::TradingSetLogLevel(const ENUM_LOG_LEVEL log_level=LOG_LEVEL_ERROR_MSG,const string symbol_name=NULL) { this.m_trading.SetLogLevel(log_level,symbol_name); } //+------------------------------------------------------------------+
これでCEngineクラスの改善は終わりです。次に、このすべての仕組みを確認する必要があります。
テスト
テストを実行するには、前の記事のEAを\MQL5\Experts\TestDoEasy\Part22\でTestDoEasyPart22.mq5として保存します。
前のEAでは、OnInit()ハンドラで操作ログに多くのテキスト検証データを表示しました。これは現在必要ないので、すべての冗長なPrint()を削除し、取引クラスの初期化、マクロ置換による標準音声再生の確認、説明によるカスタム音声を追加します。
//+------------------------------------------------------------------+ //| エキスパート初期化関数 | //+------------------------------------------------------------------+ 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 if working with the full list is selected used_symbols_mode=InpModeUsedSymbols; if((ENUM_SYMBOLS_MODE)used_symbols_mode==SYMBOLS_MODE_ALL) { int total=SymbolsTotal(false); string ru_n="\nКоличество символов на сервере "+(string)total+".\nМаксимальное количество: "+(string)SYMBOLS_COMMON_TOTAL+" символов."; string en_n="\nNumber of symbols on server "+(string)total+".\nMaximum number: "+(string)SYMBOLS_COMMON_TOTAL+" symbols."; string caption=TextByLanguage("Внимание!","Attention!"); string ru="Выбран режим работы с полным списком.\nВ этом режиме первичная подготовка списка коллекции символов может занять длительное время."+ru_n+"\nПродолжить?\n\"Нет\" - работа с текущим символом \""+Symbol()+"\""; string en="Full list mode selected.\nIn this mode, the initial preparation of the collection symbols list may take a long time."+en_n+"\nContinue?\n\"No\" - working with the current symbol \""+Symbol()+"\""; string message=TextByLanguage(ru,en); int flags=(MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2); int mb_res=MessageBox(message,caption,flags); switch(mb_res) { case IDNO : used_symbols_mode=SYMBOLS_MODE_CURRENT; break; default: break; } } //--- Fill in the array of used symbols used_symbols=InpUsedSymbols; CreateUsedSymbolsArray((ENUM_SYMBOLS_MODE)used_symbols_mode,used_symbols,array_used_symbols); //--- Set the type of the used symbol list in the symbol collection engine.SetUsedSymbols(array_used_symbols); //--- Displaying the selected mode of working with the symbol object collection Print(engine.ModeSymbolsListDescription(),TextByLanguage(". Number of used symbols: ",". Number of symbols used: "),engine.GetSymbolsCollectionTotal()); //--- Create resource text files engine.CreateFile(FILE_TYPE_WAV,"sound_array_coin_01",TextByLanguage("Звук упавшей монетки 1","Sound of falling coin 1"),sound_array_coin_01); engine.CreateFile(FILE_TYPE_WAV,"sound_array_coin_02",TextByLanguage("Звук упавших монеток","Falling coins"),sound_array_coin_02); engine.CreateFile(FILE_TYPE_WAV,"sound_array_coin_03",TextByLanguage("Звук монеток","Coins"),sound_array_coin_03); engine.CreateFile(FILE_TYPE_WAV,"sound_array_coin_04",TextByLanguage("Звук упавшей монетки 2","Sound of falling coin 2"),sound_array_coin_04); engine.CreateFile(FILE_TYPE_WAV,"sound_array_click_01",TextByLanguage("Звук щелчка по кнопке 1","Click on button sound 1"),sound_array_click_01); engine.CreateFile(FILE_TYPE_WAV,"sound_array_click_02",TextByLanguage("Звук щелчка по кнопке 2","Click on button sound 1"),sound_array_click_02); engine.CreateFile(FILE_TYPE_WAV,"sound_array_click_03",TextByLanguage("Звук щелчка по кнопке 3","Click on button sound 1"),sound_array_click_03); engine.CreateFile(FILE_TYPE_WAV,"sound_array_cash_machine_01",TextByLanguage("Звук кассового аппарата","Sound of cash machine"),sound_array_cash_machine_01); engine.CreateFile(FILE_TYPE_BMP,"img_array_spot_green",TextByLanguage("Изображение \"Зелёный светодиод\"","Image \"Green Spot lamp\""),img_array_spot_green); engine.CreateFile(FILE_TYPE_BMP,"img_array_spot_red",TextByLanguage("Изображение \"Красный светодиод\"","Image \"Red Spot lamp\""),img_array_spot_red); //--- Pass all existing collections to the trading class engine.TradingOnInit(); //--- Set synchronous passing of orders for all used symbols engine.TradingSetAsyncMode(); //--- Set standard sounds for trading objects of all used symbols engine.SetSoundsStandart(); //--- Check playing a standard sound by macro substitution and a custom sound by description engine.PlaySoundByDescription(SND_OK); Sleep(600); engine.PlaySoundByDescription(TextByLanguage("Звук упавшей монетки 2","Falling coin 2")); //--- Set controlled values for symbols //--- Get the list of all collection symbols CArrayObj *list=engine.GetListAllUsedSymbols(); if(list!=NULL && list.Total()!=0) { //--- In a loop by the list, set the necessary values for tracked symbol properties //--- By default, the LONG_MAX value is set to all properties, which means "Do not track this property" //--- It can be enabled or disabled (by setting the value less than LONG_MAX or vice versa - set the LONG_MAX value) at any time and anywhere in the program for(int i=0;i<list.Total();i++) { CSymbol* symbol=list.At(i); if(symbol==NULL) continue; //--- Set control of the symbol price increase by 100 points symbol.SetControlBidInc(100*symbol.Point()); //--- Set control of the symbol price decrease by 100 points symbol.SetControlBidDec(100*symbol.Point()); //--- Set control of the symbol spread increase by 40 points symbol.SetControlSpreadInc(40); //--- Set control of the symbol spread decrease by 40 points symbol.SetControlSpreadDec(40); //--- Set control of the current spread by the value of 40 points symbol.SetControlSpreadLevel(40); } } //--- Set controlled values for the current account CAccount* account=engine.GetAccountCurrent(); if(account!=NULL) { //--- Set control of the profit increase to 10 account.SetControlledValueINC(ACCOUNT_PROP_PROFIT,10.0); //--- Set control of the funds increase to 15 account.SetControlledValueINC(ACCOUNT_PROP_EQUITY,15.0); //--- Set profit control level to 20 account.SetControlledValueLEVEL(ACCOUNT_PROP_PROFIT,20.0); } //--- 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); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+
EAをコンパイルして起動すると、標準の「ok.wav」サウンドが再生されて、1/6秒後に「Falling coin 2」と説明が付いたカスタム音声が続きます。
取引制限を確認するメソッドの動作を確認するには、制限を人為的に作成する必要があります。
以下は例です。
- インターネットサービスを無効にする(取引サーバへの接続の損失をシミュレートするため)。
- EA設定で取引を無効にする(F7を押し、EA設定ウィンドウの[共通]タブで[自動取引を許可する]をオフにする)。
- ターミナルで自動取引を無効にする(AutoTradingボタン)。
EA取引パネルでポジションを開くボタンをクリックすると、操作ログに以下が表示されます。
2019.09.26 15:07:55.582 CTrading::OpenBuy: Request rejected before being sent to server due to: 2019.09.26 15:07:55.582 1. No permission to conduct trading operations in terminal ("AutoTrading" button disabled) 2019.09.26 15:07:55.582 2. No connection to trade server 2019.09.26 15:07:55.582 3. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")
制限を1つずつ取り除きましょう。
インターネット接続を有効にした後でポジションを開こうとすると、次のメッセージが表示されます。
2019.09.26 15:10:36.766 CTrading::OpenBuy: Request rejected before being sent to server due to: 2019.09.26 15:10:36.766 1. No permission to conduct trading operations in terminal ("AutoTrading" button disabled) 2019.09.26 15:10:36.766 2. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")
ターミナルで[AutoTrading]ボタンをクリックして、自動取引を有効にします。ポジションを開こうとすると、以下が表示されます。
2019.09.26 15:13:03.424 CTrading::OpenBuy: Request rejected before being sent to server due to: 2019.09.26 15:13:03.424 EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")
F7を押して、EAの設定でEAが取引できるようにします。ポジションを開句試みはようやく成功します。
2019.09.26 15:14:32.619 - Position is open: 2019.09.26 11:14:32.711 - 2019.09.26 15:14:32.619 EURUSD Opened 0.10 Buy #455179802 [0.10 Market-order Buy #455179802] at price 1.09441, Magic number 123
他の制限は、制限の1つがアクティブになったときに状況を作成することによってテスターまたはデモ口座で確認できます。例は、口座での未決注文の上限です。
次の段階
次の記事では、取引注文パラメータの有効性の検証を実装します。
現在のバージョンのライブラリのすべてのファイルは、テスト用EAファイルと一緒に以下に添付されているので、テストするにはダウンロードしてください。
質問、コメント、提案はコメント欄にお願いします。
シリーズのこれまでの記事:
第1部: 概念、データ管理
第2部:
過去の注文と取引のコレクション
第3部: 注文と取引のコレクション、検索と並び替え
第4部:
取引イベント概念
第5部: 取引イベントのクラスとコレクション取引イベントのプログラムへの送信
第6部:
ネッティング勘定イベント
第7部: StopLimit注文発動イベント、注文およびポジション変更イベントの機能の準備
第8部:
注文とポジションの変更イベント
第9部: MQL4との互換性 - データの準備
第10部:
MQL4との互換性 - ポジションオープンイベントと指値注文発動イベント
第11部: MQL4との互換性 - ポジション決済イベント
第12部:
口座オブジェクトクラスと口座オブジェクトコレクション
第13部: 口座オブジェクトイベント第14部:
銘柄オブジェクト
第15部: 銘柄オブジェクトコレクション
第16部:
銘柄コレクションイベント
第17部: ライブラリオブジェクトの相互作用
第18部:口座と他のライブラリオブジェクトの相互作用
第19部:ライブラリメッセージのクラス
第20部:プログラムリソースの作成と格納
第21部:とr引きクラス
- 基本クロスプラットフォーム取引オブジェクト
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/7258





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索