//+------------------------------------------------------------------+ //| Article-13052-MQL5-TradeTransactions-Structs-Print.mq5 | //| Copyright 2026, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //--- input parameters input double InpLots = 0.1; /* Lots */ // Объём в запросе input int InpMagic = 1024; /* Magic number */ // Идентификатор эксперта input int InpDistance = 300; /* Orders placement distance */ // Дистанция установки отложенных ордеров input uint InpDeviation = 5; /* Price deviation */ // Допустимое отклонение от цены в запросе input string InpKeyBuy = "B"; /* Key to open Buy */ // Клавиша для открытия позиции Buy (с Shift - Stop, с Ctrl+Shift - Limit) input string InpKeySell = "S"; /* Key to open Sell */ // Клавиша для открытия позиции Sell (с Shift - Stop, с Ctrl+Shift - Limit) input string InpKeyClose = "X"; /* Key to close/delete */ // Клавиша для закрытия позиции (без управляющих клавиш) или удаления ордера (с Shift или Shift+Ctrl) //--- Global variables ushort key_buy; // Клавиша для отправки приказа на покупку ushort key_sell; // Клавиша для отправки приказа на продажу ushort key_close; // Клавиша для закрытия или удаления //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Преобразуем в верхний регистр текст, назначенный на Buy и получаем код первого символа string tmp=InpKeyBuy; tmp.Upper(); key_buy=StringGetCharacter(tmp,0); //--- Преобразуем в верхний регистр текст, назначенный на Sell и получаем код первого символа tmp=InpKeySell; tmp.Upper(); key_sell=StringGetCharacter(tmp,0); //--- Преобразуем в верхний регистр текст, назначенный на Close и получаем код первого символа tmp=InpKeyClose; tmp.Upper(); key_close=StringGetCharacter(tmp,0); //--- Если клавиши, назначенные на Buy и Sell совпадают - сообщаем об этом и уходим с ошибкой if(key_sell==key_buy) { PrintFormat("The key assigned to Sell ('%c') is the same as the key assigned to Buy ('%c')",key_sell,key_buy); return INIT_PARAMETERS_INCORRECT; } //--- Если клавиши, назначенные на Close и Buy совпадают - сообщаем об этом и уходим с ошибкой if(key_close==key_buy) { PrintFormat("The key assigned to Close ('%c') is the same as the key assigned to Buy ('%c')",key_close,key_buy); return INIT_PARAMETERS_INCORRECT; } //--- Если клавиши, назначенные на Close и Sell совпадают - сообщаем об этом и уходим с ошибкой if(key_close==key_sell) { PrintFormat("The key assigned to Close ('%c') is the same as the key assigned to Sell ('%c')",key_close,key_sell); return INIT_PARAMETERS_INCORRECT; } //--- Успешная инициализация. Выведем в лог назначенные клавиши и возвратим успешное выполнение string kb="Key assigned to Buy: "; string ks="Key assigned to Sell: "; string kc="Key assigned to Close: "; PrintFormat("%-23s%c (key code %lu)\n%-23s%c (key code %lu)\n%-23s%c (key code %lu)",kb,key_buy,key_buy,ks,key_sell,key_sell,kc,key_close,key_close); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- Если нажата клавиша на клавиатуре if(id==CHARTEVENT_KEYDOWN) { //--- Если не удерживаются ни Ctrl, ни Shift if(!IsCtrlKeyPressed() && !IsShiftKeyPressed()) { //--- Если кнопка, назначенная на позицию Buy - открываем позицию Buy if(lparam==key_buy) OpenBuy(NULL,InpLots,InpMagic,InpDeviation,"TestMqlTradeTransaction"); //--- Если кнопка, назначенная на позицию Sell - открываем позицию Sell if(lparam==key_sell) OpenSell(NULL,InpLots,InpMagic,InpDeviation,"TestMqlTradeTransaction"); //--- Если кнопка, назначенная на закрытие позиций - закрываем все позиции if(lparam==key_close) ClosePositionsAll(Symbol()); } //--- Если удерживается только Shift if(IsShiftKeyPressed() && !IsCtrlKeyPressed()) { //--- Если кнопка, назначенная на ордер Buy - открываем ордер Buy Stop if(lparam==key_buy) SetBuyStop(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction"); //--- Если кнопка, назначенная на ордер Sell - открываем ордер Sell Stop if(lparam==key_sell) SetSellSellStop(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction"); //--- Если кнопка, назначенная на удаление ордеров - удаляем все ордеры if(lparam==key_close) DeleteOrdersAll(NULL); } //--- Если удерживается Shift вместе с Ctrl if(IsShiftKeyPressed() && IsCtrlKeyPressed()) { //--- Если кнопка, назначенная на ордер Buy - открываем ордер Buy Limit if(lparam==key_buy) SetBuyLimit(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction"); //--- Если кнопка, назначенная на ордер Sell - открываем ордер Sell Limit if(lparam==key_sell) SetSellLimit(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction"); //--- Если кнопка, назначенная на удаление ордеров - удаляем все ордеры if(lparam==key_close) DeleteOrdersAll(Symbol()); } } } //+------------------------------------------------------------------+ //| TradeTransaction function | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { //--- Пишем в журнал все приходящие торговые транзакции TradeTransactionInformer(trans,request,result,18,2,true); } //+------------------------------------------------------------------+ //| Торговые функции | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Открывает позицию Buy | //+------------------------------------------------------------------+ bool OpenBuy(const string symbol,const double lots,const uint magic,const ulong deviation=5,const string comment="") { //--- Устанавливаем символ для запроса string symbol_name=(symbol==NULL ? Symbol() : symbol); //--- Объявляем и инициализируем структуры запроса и результата MqlTradeRequest request={}; MqlTradeResult result={}; //--- Получаем нормализованную цену double price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK),(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS)); //--- параметры запроса request.action = TRADE_ACTION_DEAL; // тип торговой операции request.symbol = symbol_name; // символ request.volume = lots; // объем позиции request.type = ORDER_TYPE_BUY; // тип ордера request.price = price; // цена для открытия request.deviation = deviation; // допустимое отклонение от цены request.magic = magic; // MagicNumber ордера request.comment = comment; // Комментарий ордера //--- Если отправить запрос не удалось - сообщим об этом в журнал и вернём false if(!OrderSend(request,result)) { PrintFormat("%s: OrderSend for %s %s error: %s",__FUNCTION__, TradeActionDescription(request.action),OrderTypeDescription(request.type),RetcodeDescription(result.retcode,true) ); return false; } //--- OrderSend OK, вернём true return true; } //+------------------------------------------------------------------+ //| Открывает позицию Sell | //+------------------------------------------------------------------+ bool OpenSell(const string symbol,const double lots,const uint magic,const ulong deviation=5,const string comment="") { //--- Устанавливаем символ для запроса string symbol_name=(symbol==NULL ? Symbol() : symbol); //--- Объявляем и инициализируем структуры запроса и результата MqlTradeRequest request={}; MqlTradeResult result={}; //--- Получаем нормализованную цену double price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID),(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS)); //--- параметры запроса request.action = TRADE_ACTION_DEAL; // тип торговой операции request.symbol = symbol_name; // символ request.volume = lots; // объем позиции request.type = ORDER_TYPE_SELL; // тип ордера request.price = price; // цена для открытия request.deviation = deviation; // допустимое отклонение от цены request.magic = magic; // MagicNumber ордера request.comment = comment; // Комментарий ордера //--- Если отправить запрос не удалось - сообщим об этом в журнал и вернём false if(!OrderSend(request,result)) { PrintFormat("%s: OrderSend for %s %s error: %s",__FUNCTION__, TradeActionDescription(request.action),OrderTypeDescription(request.type),RetcodeDescription(result.retcode,true) ); return false; } //--- OrderSend OK, вернём true return true; } //+------------------------------------------------------------------+ //| Закрывает позицию по тикету | //+------------------------------------------------------------------+ bool ClosePosition(const ulong ticket,const ulong deviation=5) { //--- Объявляем структуры запроса и результата MqlTradeRequest request; MqlTradeResult result; //--- Если позицию не удалось выбрать по тикету - сообщаем об ошибке и уходим ResetLastError(); if(!PositionSelectByTicket(ticket)) { Print("PositionSelectByTicket failed, error: ",(string)GetLastError()); return false; } //--- Получаем данные закрываемой позиции string position_symbol=PositionGetString(POSITION_SYMBOL); // символ int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // количество знаков после запятой double volume=PositionGetDouble(POSITION_VOLUME); // объем позиции ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // тип позиции ulong magic=PositionGetInteger(POSITION_MAGIC); // MagicNumber позиции //--- Обнуляем значения запроса и результата ZeroMemory(request); ZeroMemory(result); //--- Устанавливаем параметры операции request.action = TRADE_ACTION_DEAL; // тип торговой операции request.position = ticket; // тикет позиции request.symbol = position_symbol; // символ request.volume = volume; // объем позиции request.deviation = deviation; // допустимое отклонение от цены request.magic = magic; // MagicNumber позиции //--- Устанавливаем цену и тип ордера в зависимости от типа позиции if(type==POSITION_TYPE_BUY) { request.price=NormalizeDouble(SymbolInfoDouble(position_symbol,SYMBOL_BID),digits); request.type =ORDER_TYPE_SELL; } else { request.price=NormalizeDouble(SymbolInfoDouble(position_symbol,SYMBOL_ASK),digits); request.type =ORDER_TYPE_BUY; } //--- Если отправить запрос не удалось, сообщим об этом в журнал и вернём false if(!OrderSend(request,result)) { PrintFormat("%s: OrderSend for %s %s #%llu error: %s",__FUNCTION__, TradeActionDescription(request.action),OrderTypeDescription(request.type),ticket,RetcodeDescription(result.retcode,true) ); return false; } //--- OrderSend OK, вернём true return true; } //+------------------------------------------------------------------+ //| Закрывает все позиции по символу | //+------------------------------------------------------------------+ uint ClosePositionsAll(const string symbol,const ulong magic=0) { //--- Объявим переменную для хранения результата и количества закрытых позиций bool res=true; uint num=0; //--- перебор всех открытых позиций int total=PositionsTotal(); // количество открытых позиций for(int i=total-1; i>=0; i--) { ulong position_ticket=PositionGetTicket(i); // тикет позиции if(position_ticket==0) continue; if(PositionGetInteger(POSITION_MAGIC)!=magic) continue; //--- Если MagicNumber не указан (нулевой) или магик позиции соответствует указанному if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic) { //--- если символ позиции совпадает с переданным или передан NULL - закрываем позицию по тикету if(symbol==NULL || PositionGetString(POSITION_SYMBOL)==symbol) { //--- Получаем результат закрытия позиции по тикету и увеличиваем счётчик закрытых при успехе res &=ClosePosition(position_ticket); if(res) num++; } } } if(!res) PrintFormat("%s: Not all positions were able to close without errors",__FUNCTION__); return num; } //+------------------------------------------------------------------+ //| Устанавливает указанный отложенный ордер | //+------------------------------------------------------------------+ bool SetPending(const string symbol,const ENUM_ORDER_TYPE order_type,const double lots,const uint magic,const int distance,const int stoplimit=0,const string comment="") { //--- Устанавливаем символ для запроса string symbol_name=(symbol==NULL ? Symbol() : symbol); //--- Объявляем и инициализируем структуры запроса и результата MqlTradeRequest request={}; MqlTradeResult result={}; //--- Устанавливаем параметры операции request.action = TRADE_ACTION_PENDING; // тип торговой операции request.type = order_type; // тип ордера request.symbol = symbol_name; // символ request.volume = lots; // объем request.magic = magic; // MagicNumber ордера request.comment = comment; // Комментарий ордера //--- Получаем Point и Digits double point=SymbolInfoDouble(symbol_name,SYMBOL_POINT); int digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS); //--- Рассчитываем дистанцию от цены в зависимости от типа ордера //--- Ордер на покупку if(order_type==ORDER_TYPE_BUY_STOP) request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK)+distance*point,digits); // нормализованная цена установки if(order_type==ORDER_TYPE_BUY_LIMIT) request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK)-distance*point,digits); // нормализованная цена установки if(order_type==ORDER_TYPE_BUY_STOP_LIMIT) { request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK)+distance*point,digits); // нормализованная цена срабатывания Stop-ордера request.stoplimit=NormalizeDouble(request.price-stoplimit*point,digits); // нормализованная цена установки Limit-ордера } //--- Ордер на продажу if(order_type==ORDER_TYPE_SELL_STOP) request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID)-distance*point,digits); // нормализованная цена установки if(order_type==ORDER_TYPE_SELL_LIMIT) request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID)+distance*point,digits); // нормализованная цена установки if(order_type==ORDER_TYPE_SELL_STOP_LIMIT) { request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID)-distance*point,digits); // нормализованная цена срабатывания Stop-ордера request.stoplimit=NormalizeDouble(request.price+stoplimit*point,digits); // нормализованная цена установки Limit-ордера } //--- Если отправить запрос не удалось, сообщим об этом в журнал и вернём false if(!OrderSend(request,result)) { PrintFormat("%s: OrderSend for %s %s error: %s",__FUNCTION__, TradeActionDescription(request.action),OrderTypeDescription(request.type),RetcodeDescription(result.retcode,true) ); return false; } //--- OrderSend OK, вернём true return true; } //+------------------------------------------------------------------+ //| Устанавливает отложенный ордер BuyStop | //+------------------------------------------------------------------+ bool SetBuyStop(const string symbol,const double lots,const uint magic,const int distance,const string comment="") { //--- Вызываем функцию SetPending с параметрами для BuyStop return SetPending(symbol,ORDER_TYPE_BUY_STOP,lots,magic,distance,0,comment); } //+------------------------------------------------------------------+ //| Устанавливает отложенный ордер BuyLimit | //+------------------------------------------------------------------+ bool SetBuyLimit(const string symbol,const double lots,const uint magic,const int distance,const string comment="") { //--- Вызываем функцию SetPending с параметрами для BuyLimit return SetPending(symbol,ORDER_TYPE_BUY_LIMIT,lots,magic,distance,0,comment); } //+------------------------------------------------------------------+ //| Устанавливает отложенный ордер BuyStopLimit | //+------------------------------------------------------------------+ bool SetBuyStopLimit(const string symbol,const double lots,const uint magic,const int distance,const int stoplimit,const string comment="") { //--- Вызываем функцию SetPending с параметрами для BuyStopLimit return SetPending(symbol,ORDER_TYPE_BUY_STOP_LIMIT,lots,magic,distance,stoplimit,comment); } //+------------------------------------------------------------------+ //| Устанавливает отложенный ордер SellStop | //+------------------------------------------------------------------+ bool SetSellSellStop(const string symbol,const double lots,const uint magic,const int distance,const string comment="") { //--- Вызываем функцию SetPending с параметрами для SellStop return SetPending(symbol,ORDER_TYPE_SELL_STOP,lots,magic,distance,0,comment); } //+------------------------------------------------------------------+ //| Устанавливает отложенный ордер SellLimit | //+------------------------------------------------------------------+ bool SetSellLimit(const string symbol,const double lots,const uint magic,const int distance,const string comment="") { //--- Вызываем функцию SetPending с параметрами для SellLimit return SetPending(symbol,ORDER_TYPE_SELL_LIMIT,lots,magic,distance,0,comment); } //+------------------------------------------------------------------+ //| Устанавливает отложенный ордер SellStopLimit | //+------------------------------------------------------------------+ bool SetSellStopLimit(const string symbol,const double lots,const uint magic,const int distance,const int stoplimit,const string comment="") { //--- Вызываем функцию SetPending с параметрами для SellStopLimit return SetPending(symbol,ORDER_TYPE_SELL_STOP_LIMIT,lots,magic,distance,stoplimit,comment); } //+------------------------------------------------------------------+ //| Удаляет отложенный ордер по тикету | //+------------------------------------------------------------------+ bool DeleteOrder(const ulong ticket) { //-- объявление и инициализация запроса и результата MqlTradeRequest request={}; MqlTradeResult result={}; ResetLastError(); //--- Если ордер не удалось выбрать по тикету - сообщаем об ошибке и уходим if(!OrderSelect(ticket)) { PrintFormat("%s: OrderSelect failed, error: %d",__FUNCTION__,GetLastError()); return false; } //--- Обнуляем значения запроса и результата ZeroMemory(request); ZeroMemory(result); //--- Устанавливаем параметры операции request.action=TRADE_ACTION_REMOVE; // тип торговой операции request.order = ticket; // тикет ордера //--- Если отправить запрос не удалось, сообщим об этом в журнал и вернём false if(!OrderSend(request,result)) { PrintFormat("%s: OrderSend for %s %s #%llu error: %s",__FUNCTION__, TradeActionDescription(request.action),OrderTypeDescription((ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE)),ticket,RetcodeDescription(result.retcode,true) ); return false; } //--- OrderSend OK, вернём true return true; } //+------------------------------------------------------------------+ //| Удаляет все отложенные ордера по символу | //+------------------------------------------------------------------+ uint DeleteOrdersAll(const string symbol,const long magic=WRONG_VALUE) { //--- Объявим переменную для хранения результата и количества удалённых ордеров bool res=true; uint num=0; //--- перебор всех установленных отложенных ордеров int total=OrdersTotal(); // количество установленных отложенных ордеров for(int i=total-1; i>=0; i--) { ulong order_ticket=OrderGetTicket(i); // тикет ордера if(order_ticket==0) continue; //--- Если MagicNumber не указан (нулевой) или магик ордера соответствует указанному if(magic==WRONG_VALUE || OrderGetInteger(ORDER_MAGIC)==magic) { //--- если символ ордера совпадает с переданным или передан NULL - удаляем ордер по тикету if(symbol==NULL || OrderGetString(ORDER_SYMBOL)==symbol) { res &=DeleteOrder(order_ticket); if(res) num++; } } } if(!res) PrintFormat("%s: Not all orders were able to close without errors",__FUNCTION__); return num; } //+------------------------------------------------------------------+ //| Вспомогательные функции | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Возвращает состояние клавиши Ctrl | //+------------------------------------------------------------------+ bool IsCtrlKeyPressed(void) { return(::TerminalInfoInteger(TERMINAL_KEYSTATE_CONTROL)<0); } //+------------------------------------------------------------------+ //| Возвращает состояние клавиши Shift | //+------------------------------------------------------------------+ bool IsShiftKeyPressed(void) { return(::TerminalInfoInteger(TERMINAL_KEYSTATE_SHIFT)<0); } //+------------------------------------------------------------------+ //| Возвращает описание кода возврата торгового сервера | //+------------------------------------------------------------------+ string RetcodeDescription(const uint retcode,bool ext_descr=false) { switch(retcode) { //--- Выполнено case 0 : return "OK (0)"; //--- Реквота case TRADE_RETCODE_REQUOTE : return "10004 REQUOTE"+(ext_descr ? " (Requote)" : ""); //--- Запрос отклонен case TRADE_RETCODE_REJECT : return "10006 REJECT"+(ext_descr ? " (Request rejected)" : ""); //--- Запрос отменен трейдером case TRADE_RETCODE_CANCEL : return "10007 CANCEL"+(ext_descr ? " (Request canceled by trader)" : ""); //--- Ордер размещен case TRADE_RETCODE_PLACED : return "10008 PLACED"+(ext_descr ? " (Order placed)" : ""); //--- Заявка выполнена case TRADE_RETCODE_DONE : return "10009 DONE"+(ext_descr ? " (Request completed)" : ""); //--- Заявка выполнена частично case TRADE_RETCODE_DONE_PARTIAL : return "10010 DONE_PARTIAL"+(ext_descr ? " (Only part of the request was completed)" : ""); //--- Ошибка обработки запроса case TRADE_RETCODE_ERROR : return "10011 ERROR"+(ext_descr ? " (Request processing error)" : ""); //--- Запрос отменен по истечению времени case TRADE_RETCODE_TIMEOUT : return "10012 TIMEOUT"+(ext_descr ? " (Request canceled by timeout)" : ""); //--- Неправильный запрос case TRADE_RETCODE_INVALID : return "10013 INVALID"+(ext_descr ? " (Invalid request)" : ""); //--- Неправильный объем в запросе case TRADE_RETCODE_INVALID_VOLUME : return "10014 INVALID_VOLUME"+(ext_descr ? " (Invalid volume in the request)" : ""); //--- Неправильная цена в запросе case TRADE_RETCODE_INVALID_PRICE : return "10015 INVALID_PRICE"+(ext_descr ? " (Invalid price in the request)" : ""); //--- Неправильные стопы в запросе case TRADE_RETCODE_INVALID_STOPS : return "10016 INVALID_STOPS"+(ext_descr ? " (Invalid stops in the request)" : ""); //--- Торговля запрещена case TRADE_RETCODE_TRADE_DISABLED : return "10017 TRADE_DISABLED"+(ext_descr ? " (Trade is disabled)" : ""); //--- Рынок закрыт case TRADE_RETCODE_MARKET_CLOSED : return "10018 MARKET_CLOSED"+(ext_descr ? " (Market is closed)" : ""); //--- Нет достаточных денежных средств для выполнения запроса case TRADE_RETCODE_NO_MONEY : return "10019 NO_MONEY"+(ext_descr ? " (There is not enough money to complete the request)" : ""); //--- Цены изменились case TRADE_RETCODE_PRICE_CHANGED : return "10020 PRICE_CHANGED"+(ext_descr ? " (Prices changed)" : ""); //--- Отсутствуют котировки для обработки запроса case TRADE_RETCODE_PRICE_OFF : return "10021 PRICE_OFF"+(ext_descr ? " (There are no quotes to process the request)" : ""); //--- Неверная дата истечения ордера в запросе case TRADE_RETCODE_INVALID_EXPIRATION : return "10022 INVALID_EXPIRATION"+(ext_descr ? " (Invalid order expiration date in the request)" : ""); //--- Состояние ордера изменилось case TRADE_RETCODE_ORDER_CHANGED : return "10023 ORDER_CHANGED"+(ext_descr ? " (Order state changed)" : ""); //--- Слишком частые запросы case TRADE_RETCODE_TOO_MANY_REQUESTS : return "10024 TOO_MANY_REQUESTS"+(ext_descr ? " (Too frequent requests)" : ""); //--- В запросе нет изменений case TRADE_RETCODE_NO_CHANGES : return "10025 NO_CHANGES"+(ext_descr ? " (No changes in request)" : ""); //--- Автотрейдинг запрещен сервером case TRADE_RETCODE_SERVER_DISABLES_AT : return "10026 SERVER_DISABLES_AT"+(ext_descr ? " (Autotrading disabled by server)" : ""); //--- Автотрейдинг запрещен клиентским терминалом case TRADE_RETCODE_CLIENT_DISABLES_AT : return "10027 CLIENT_DISABLES_AT"+(ext_descr ? " (Autotrading disabled by client terminal)" : ""); //--- Запрос заблокирован для обработки case TRADE_RETCODE_LOCKED : return "10028 LOCKED"+(ext_descr ? " (Request locked for processing)" : ""); //--- Ордер или позиция заморожены case TRADE_RETCODE_FROZEN : return "10029 FROZEN"+(ext_descr ? " (Order or position frozen)" : ""); //--- Указан неподдерживаемый тип исполнения ордера по остатку case TRADE_RETCODE_INVALID_FILL : return "10030 INVALID_FILL"+(ext_descr ? " (Invalid order filling type)" : ""); //--- Нет соединения с торговым сервером case TRADE_RETCODE_CONNECTION : return "10031 CONNECTION"+(ext_descr ? " (No connection with the trade server)" : ""); //--- Операция разрешена только для реальных счетов case TRADE_RETCODE_ONLY_REAL : return "10032 ONLY_REAL"+(ext_descr ? " (Operation is allowed only for live accounts)" : ""); //--- Достигнут лимит на количество отложенных ордеров case TRADE_RETCODE_LIMIT_ORDERS : return "10033 LIMIT_ORDERS"+(ext_descr ? " (The number of pending orders has reached the limit)" : ""); //--- Достигнут лимит на объем ордеров и позиций для данного символа case TRADE_RETCODE_LIMIT_VOLUME : return "10034 LIMIT_VOLUME"+(ext_descr ? " (The volume of orders and positions for the symbol has reached the limit)" : ""); //--- Неверный или запрещённый тип ордера case TRADE_RETCODE_INVALID_ORDER : return "10035 INVALID_ORDER"+(ext_descr ? " (Incorrect or prohibited order type)" : ""); //--- Позиция с указанным POSITION_IDENTIFIER уже закрыта case TRADE_RETCODE_POSITION_CLOSED : return "10036 POSITION_CLOSED"+(ext_descr ? " (Position with the specified POSITION_IDENTIFIER has already been closed)" : ""); //--- Закрываемый объем превышает текущий объем позиции case TRADE_RETCODE_INVALID_CLOSE_VOLUME: return "10038 INVALID_CLOSE_VOLUME"+(ext_descr ? " (A close volume exceeds the current position volume)" : ""); //--- Для указанной позиции уже есть ордер на закрытие case TRADE_RETCODE_CLOSE_ORDER_EXIST : return "10039 CLOSE_ORDER_EXIST"+(ext_descr ? " (A close order already exists for a specified position)" : ""); //--- Достигнут лимит на количество позиций case TRADE_RETCODE_LIMIT_POSITIONS : return "10040 LIMIT_POSITIONS"+(ext_descr ? " (The number of positions has reached the limit)" : ""); //--- Запрос на активацию отложенного ордера отклонен, а сам ордер отменен case TRADE_RETCODE_REJECT_CANCEL : return "10041 REJECT_CANCEL"+(ext_descr ? " (The pending order activation request is rejected, the order is canceled)" : ""); //--- Запрос отклонен, так как на символе разрешены только длинные позиции case TRADE_RETCODE_LONG_ONLY : return "10042 LONG_ONLY"+(ext_descr ? " (Only long positions are allowed)" : ""); //--- Запрос отклонен, так как на символе разрешены только короткие позиции case TRADE_RETCODE_SHORT_ONLY : return "10043 SHORT_ONLY"+(ext_descr ? " (Only short positions are allowed)" : ""); //--- Запрос отклонен, так как на символе разрешено только закрывать существующие позиции case TRADE_RETCODE_CLOSE_ONLY : return "10044 CLOSE_ONLY"+(ext_descr ? " (Only position closing is allowed)" : ""); //--- Запрос отклонен, так как для торгового счета разрешено закрывать существующие позиции только по правилу FIFO case TRADE_RETCODE_FIFO_CLOSE : return "10045 FIFO_CLOSE"+(ext_descr ? " (Position closing is allowed only by FIFO rule)" : ""); //--- Запрос отклонен, так как для торгового счета запрещено открывать встречные позиции по одному символу case TRADE_RETCODE_HEDGE_PROHIBITED : return "10046 HEDGE_PROHIBITED"+(ext_descr ? " (Opposite positions on a single symbol are disabled)" : ""); //--- Неизвестный код возврата default : return "Undefined ("+(string)retcode+")"; } } //+------------------------------------------------------------------+ //| Возвращает описание типа ордера | //+------------------------------------------------------------------+ string OrderTypeDescription(const ENUM_ORDER_TYPE type,const bool ext_descr=false) { //--- "Вырезаем" из строки, полученной из enum, только тип ордера string res=StringSubstr(EnumToString(type),11); //--- Преобразуем все полученные символы в нижний регистр и if(res.Lower()) { //--- заменяем первую букву с маленькой на заглавную res.SetChar(0,ushort(res.GetChar(0)-0x20)); int total=(int)res.Length(); // Длина текста int index=0; // индекс начала поиска символов "_" в тексте //--- В цикле по всем символам ищем в тексте знаки нижнего подчёркивания for(int i=0;i0) { //--- заменяем его на пробел и следующую букву переводим в верхний регистр res.SetChar(pos,' '); res.SetChar(pos+1,ushort(res.GetChar(pos+1)-0x20)); //--- Устанавливаем новый индекс начала поиска знаков "_" index=pos; } } } string descr=""; switch(type) { case ORDER_TYPE_BUY : descr=" (Market Buy order)"; break; case ORDER_TYPE_SELL : descr=" (Market Sell order)"; break; case ORDER_TYPE_BUY_LIMIT : descr=" (Buy Limit pending order)"; break; case ORDER_TYPE_SELL_LIMIT : descr=" (Sell Limit pending order)"; break; case ORDER_TYPE_BUY_STOP : descr=" (Buy Stop pending order)"; break; case ORDER_TYPE_SELL_STOP : descr=" (Sell Stop pending order)"; break; case ORDER_TYPE_BUY_STOP_LIMIT : descr=" (Upon reaching the order price, a pending Buy Limit order is placed at the StopLimit price)"; break; case ORDER_TYPE_SELL_STOP_LIMIT : descr=" (Upon reaching the order price, a pending Sell Limit order is placed at the StopLimit price)";break; case ORDER_TYPE_CLOSE_BY : descr=" (Order to close a position by an opposite one)"; break; default: break; } return res+(!ext_descr ? "" : descr); /* Пример вывода: Sell Limit (Sell Limit pending order) */ } //+------------------------------------------------------------------+ //| Возвращает описание типа ордера по исполнению | //+------------------------------------------------------------------+ string OrderTypeFillingDescription(const ENUM_ORDER_TYPE_FILLING type_filling,const bool ext_descr=false) { string res=StringSubstr(EnumToString(type_filling),14); //--- Преобразуем все полученные символы в нижний регистр и заменяем первую букву с маленькой на заглавную (для ORDER_FILLING_RETURN) if(type_filling==ORDER_FILLING_RETURN && res.Lower()) res.SetChar(0,ushort(res.GetChar(0)-0x20)); string descr=""; switch(type_filling) { case ORDER_FILLING_FOK : descr=" (Fill or Kill. An order can be executed in the specified volume only)"; break; case ORDER_FILLING_IOC : descr=" (Immediate or Cancel. A deal with the volume maximally available in the market within that indicated in the order)"; break; case ORDER_FILLING_BOC : descr=" (Passive (Book or Cancel). The order can only be placed in the Depth of Market and cannot be immediately executed)"; break; case ORDER_FILLING_RETURN : descr=" (In case of partial filling, an order with remaining volume is not canceled but processed further)"; break; default: break; } return res+(!ext_descr ? "" : descr); /* Пример вывода: Return (In case of partial filling, an order with remaining volume is not canceled but processed further) */ } //+------------------------------------------------------------------+ //| Возвращает описание типа торговой транзакции | //+------------------------------------------------------------------+ string TradeTransactionTypeDescription(const ENUM_TRADE_TRANSACTION_TYPE transaction,const bool ext_descr=false) { //--- "Вырезаем" из строки, полученной из enum, только тип транзакции string res=StringSubstr(EnumToString(transaction),18); //--- Преобразуем все полученные символы в нижний регистр и заменяем первую букву с маленькой на заглавную if(res.Lower()) res.SetChar(0,ushort(res.GetChar(0)-0x20)); //--- Заменяем в полученной строке все символы подчёркивания на символ пробела StringReplace(res,"_"," "); string descr=""; switch(transaction) { case TRADE_TRANSACTION_ORDER_ADD : descr=" (Adding a new open order)"; break; case TRADE_TRANSACTION_ORDER_UPDATE : descr=" (Updating an open order)"; break; case TRADE_TRANSACTION_ORDER_DELETE : descr=" (Removing an order from the list of the open ones)"; break; case TRADE_TRANSACTION_DEAL_ADD : descr=" (Adding a deal to the history)"; break; case TRADE_TRANSACTION_DEAL_UPDATE : descr=" (Updating a deal in the history)"; break; case TRADE_TRANSACTION_DEAL_DELETE : descr=" (Deleting a deal from the history)"; break; case TRADE_TRANSACTION_HISTORY_ADD : descr=" (Adding an order to the history as a result of execution or cancellation)"; break; case TRADE_TRANSACTION_HISTORY_UPDATE : descr=" (Changing an order located in the orders history)"; break; case TRADE_TRANSACTION_HISTORY_DELETE : descr=" (Deleting an order from the orders history)"; break; case TRADE_TRANSACTION_POSITION : descr=" (Changing a position not related to a deal execution)"; break; case TRADE_TRANSACTION_REQUEST : descr=" (The trade request has been processed by a server and processing result has been received)"; break; default: break; } return res+(!ext_descr ? "" : descr); /* Пример вывода: Order add (Adding a new open order) */ } //+------------------------------------------------------------------+ //| Возвращает описание состояния ордера | //+------------------------------------------------------------------+ string OrderStateDescription(const ENUM_ORDER_STATE state,const bool ext_descr=false) { //--- "Вырезаем" из строки, полученной из enum, только состояние ордера string res=StringSubstr(EnumToString(state),12); //--- Преобразуем все полученные символы в нижний регистр и заменяем первую букву с маленькой на заглавную if(res.Lower()) res.SetChar(0,ushort(res.GetChar(0)-0x20)); //--- Заменяем в полученной строке все символы подчёркивания на символ пробела StringReplace(res,"_"," "); string descr=""; switch(state) { case ORDER_STATE_STARTED : descr=" (Order checked, but not yet accepted by broker)"; break; case ORDER_STATE_PLACED : descr=" (Order accepted)"; break; case ORDER_STATE_CANCELED : descr=" (Order canceled by client)"; break; case ORDER_STATE_PARTIAL : descr=" (Order partially executed)"; break; case ORDER_STATE_FILLED : descr=" (Order fully executed)"; break; case ORDER_STATE_REJECTED : descr=" (Order rejected)"; break; case ORDER_STATE_EXPIRED : descr=" (Order expired)"; break; case ORDER_STATE_REQUEST_ADD : descr=" (Order is being registered (placing to the trading system))";break; case ORDER_STATE_REQUEST_MODIFY : descr=" (Order is being modified (changing its parameters))"; break; case ORDER_STATE_REQUEST_CANCEL : descr=" (Order is being deleted (deleting from the trading system))";break; default: break; } return res+(!ext_descr ? "" : descr); /* Пример вывода: Placed (Order accepted) */ } //+------------------------------------------------------------------+ //| Возвращает описание типа сделки | //+------------------------------------------------------------------+ string DealTypeDescription(const ENUM_DEAL_TYPE type,const bool ext_descr=false) { //--- "Вырезаем" из строки, полученной из enum, только тип сделки string res=StringSubstr(EnumToString(type),(type==DEAL_DIVIDEND || type==DEAL_DIVIDEND_FRANKED || type==DEAL_TAX ? 5 : 10)); //--- Преобразуем все полученные символы в нижний регистр и заменяем первую букву с маленькой на заглавную if(res.Lower()) res.SetChar(0,ushort(res.GetChar(0)-0x20)); //--- Заменяем в полученной строке все символы подчёркивания на символ пробела StringReplace(res,"_"," "); string descr=""; //--- Расширенные описания добавляются только к тем сделкам, чьё описание, полученное из enum, не совпадает с расширенным switch(type) { case DEAL_TYPE_CHARGE : descr=" (Additional charge)"; break; case DEAL_TYPE_COMMISSION : descr=" (Additional commission)"; break; case DEAL_TYPE_COMMISSION_DAILY : descr=" (Daily commission)"; break; case DEAL_TYPE_COMMISSION_MONTHLY : descr=" (Monthly commission)"; break; case DEAL_TYPE_COMMISSION_AGENT_DAILY : descr=" (Daily agent commission)"; break; case DEAL_TYPE_COMMISSION_AGENT_MONTHLY: descr=" (Monthly agent commission)"; break; case DEAL_TYPE_INTEREST : descr=" (Interest rate)"; break; case DEAL_TYPE_BUY_CANCELED : descr=" (Canceled buy deal)"; break; case DEAL_TYPE_SELL_CANCELED : descr=" (Canceled sell deal)"; break; case DEAL_DIVIDEND : descr=" (Dividend operations)"; break; case DEAL_DIVIDEND_FRANKED : descr=" (Franked (non-taxable) dividend operations)"; break; case DEAL_TAX : descr=" (Tax charges)"; break; default: break; } return res+(!ext_descr ? "" : descr); /* Пример вывода: Comission (Additional commission) */ } //+------------------------------------------------------------------+ //| Возвращает описание типа ордера по истечению | //+------------------------------------------------------------------+ string OrderTypeTimeDescription(const ENUM_ORDER_TYPE_TIME type_time,const bool ext_descr=false) { //--- "Вырезаем" из строки, полученной из enum, только тип ордера по истечению string res=StringSubstr(EnumToString(type_time),6); //--- Если тип по истечению ORDER_TIME_GTC, то впишем в res "Time GTC" if(type_time==ORDER_TIME_GTC) res="Time GTC"; //--- Иначе - преобразуем все полученные символы в нижний регистр и заменяем первую букву с маленькой на заглавную else { if(res.Lower()) res.SetChar(0,ushort(res.GetChar(0)-0x20)); //--- Заменяем в полученной строке все символы подчёркивания на символ пробела StringReplace(res,"_"," "); } string descr=""; switch(type_time) { case ORDER_TIME_GTC : descr=" (Good till cancel order)"; break; case ORDER_TIME_DAY : descr=" (Good till current trade day order)"; break; case ORDER_TIME_SPECIFIED : descr=" (Good till expired order)"; break; case ORDER_TIME_SPECIFIED_DAY : descr=" (The order will be effective till 23:59:59 of the specified day)"; break; default: break; } return res+(!ext_descr ? "" : descr); /* Пример вывода: Time GTC (Good till cancel order) */ } //+------------------------------------------------------------------+ //| Определяет и устанавливает значения принадлежности транзакции | //+------------------------------------------------------------------+ void SetTransactionBelong(const ENUM_TRADE_TRANSACTION_TYPE type,bool &request_flag,bool &order_flag,bool &deal_flag,bool &position_flag) { switch(type) { //--- Запрос case TRADE_TRANSACTION_REQUEST : request_flag=true; order_flag=false; deal_flag=false; position_flag=false; break; //--- Ордер case TRADE_TRANSACTION_ORDER_ADD : case TRADE_TRANSACTION_ORDER_UPDATE : case TRADE_TRANSACTION_ORDER_DELETE : case TRADE_TRANSACTION_HISTORY_ADD : case TRADE_TRANSACTION_HISTORY_UPDATE : case TRADE_TRANSACTION_HISTORY_DELETE : request_flag=false; order_flag=true; deal_flag=false; position_flag=false; break; //--- Сделка case TRADE_TRANSACTION_DEAL_ADD : case TRADE_TRANSACTION_DEAL_UPDATE : case TRADE_TRANSACTION_DEAL_DELETE : request_flag=false; order_flag=false; deal_flag=true; position_flag=false; break; //--- Позиция case TRADE_TRANSACTION_POSITION : request_flag=false; order_flag=false; deal_flag=false; position_flag=true; break; //--- default: break; } } //+------------------------------------------------------------------+ //| Возвращает описание типа торговго запроса | //+------------------------------------------------------------------+ string TradeActionDescription(const ENUM_TRADE_REQUEST_ACTIONS action,const bool ext_descr=false) { //--- "Вырезаем" из строки, полученной из enum, только тип операции string res=StringSubstr(EnumToString(action),13); //--- Преобразуем все полученные символы в нижний регистр и заменяем первую букву с маленькой на заглавную (кроме TRADE_ACTION_SLTP) if(action!=TRADE_ACTION_SLTP && res.Lower()) res.SetChar(0,ushort(res.GetChar(0)-0x20)); string descr=""; switch(action) { case TRADE_ACTION_DEAL : descr=" (Place a trade order for an immediate execution with the specified parameters (market order))";break; case TRADE_ACTION_PENDING : descr=" (Place a trade order for the execution under specified conditions (pending order))"; break; case TRADE_ACTION_SLTP : descr=" (Modify Stop Loss and Take Profit values of an opened position)"; break; case TRADE_ACTION_MODIFY : descr=" (Modify the parameters of the order placed previously)"; break; case TRADE_ACTION_REMOVE : descr=" (Delete the pending order placed previously)"; break; case TRADE_ACTION_CLOSE_BY : descr=" (Close a position by an opposite one)"; break; default: break; } return res+(!ext_descr ? "" : descr); /* Пример вывода: Pending (Place a trade order for the execution under specified conditions (pending order)): */ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //|Функции для работы со структурой торгового запроса MqlTradeRequest| //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Возвращает в виде строки тип выполняемого действия | //+------------------------------------------------------------------+ string MqlTradeRequestAction(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Action:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,TradeActionDescription(req.action,ext_descr)); /* Пример вывода: Action: Pending (Place a trade order for the execution under specified conditions (pending order)): */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки штамп эксперта (magic number) | //+------------------------------------------------------------------+ string MqlTradeRequestMagic(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Magic:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.magic); /* Пример вывода: Magic: 1024 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет ордера | //+------------------------------------------------------------------+ string MqlTradeRequestOrder(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Order:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.order); /* Пример вывода: Order: 1835982676 */ } //+------------------------------------------------------------------+ //| Возвращает имя торгового инструмента | //+------------------------------------------------------------------+ string MqlTradeRequestSymbol(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Symbol:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,req.symbol); /* Пример вывода: Symbol: EURUSD */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки запрашиваемый объем сделки в лотах | //+------------------------------------------------------------------+ string MqlTradeRequestVolume(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Volume:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой в значении лота. Если символ не указан, используем 1 int dg=(int)ceil(fabs(log10(SymbolInfoDouble(req.symbol,SYMBOL_VOLUME_STEP)))); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.volume); /* Пример вывода: Volume: 0.10 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки цену | //+------------------------------------------------------------------+ string MqlTradeRequestPrice(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Price:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой int dg=(req.price!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.price); /* Пример вывода: Price: 1.09586 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки уровень StopLimit ордера | //+------------------------------------------------------------------+ string MqlTradeRequestStopLimit(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="StopLimit:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой int dg=(req.stoplimit!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.stoplimit); /* Пример вывода: StopLimit: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки уровень Stop Loss ордера | //+------------------------------------------------------------------+ string MqlTradeRequestStopLoss(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="SL:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой int dg=(req.sl!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.sl); /* Пример вывода: SL: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки уровень Take Profit ордера | //+------------------------------------------------------------------+ string MqlTradeRequestTakeProfit(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="TP:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой int dg=(req.tp!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.tp); /* Пример вывода: TP: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки максимально приемлемое | //| отклонение от запрашиваемой цены | //+------------------------------------------------------------------+ string MqlTradeRequestDeviation(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Deviation:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.deviation); /* Пример вывода: Deviation: 5 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тип ордера | //+------------------------------------------------------------------+ string MqlTradeRequestType(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Type:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,OrderTypeDescription(req.type,ext_descr)); /* Пример вывода: Type: Buy Limit (Buy Limit pending order) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тип ордера по исполнению | //+------------------------------------------------------------------+ string MqlTradeRequestTypeFilling(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Type filling:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,OrderTypeFillingDescription(req.type_filling,ext_descr)); /* Пример вывода: Type filling: Return (In case of partial filling, an order with remaining volume is not canceled but processed further) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тип ордера по времени действия | //+------------------------------------------------------------------+ string MqlTradeRequestTypeTime(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Type time:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,OrderTypeTimeDescription(req.type_time,ext_descr)); /* Пример вывода: Type time: Time GTC (Good till cancel order) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки срок истечения ордера | //+------------------------------------------------------------------+ string MqlTradeRequestExpiration(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Expiration:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,(req.type_time==ORDER_TIME_SPECIFIED || req.type_time==ORDER_TIME_SPECIFIED_DAY ? (string)req.expiration : "0")); /* Пример вывода: Expiration: 0 */ } //+------------------------------------------------------------------+ //| Возвращает комментарий к ордеру | //+------------------------------------------------------------------+ string MqlTradeRequestComment(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Comment:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,req.comment); /* Пример вывода: Comment: TestMqlTradeTransaction */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет позиции | //+------------------------------------------------------------------+ string MqlTradeRequestPosition(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Position:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.position); /* Пример вывода: Position: 1835982676 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет встречной позиции | //+------------------------------------------------------------------+ string MqlTradeRequestPositionBy(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Position by:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.position_by); /* Пример вывода: Position by: 1835987626 */ } //+------------------------------------------------------------------+ //| Выводит в журнал описание торгового запроса | //+------------------------------------------------------------------+ void TradeRequestPrint(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false) { //--- Получаем тип исполнения по символу ENUM_SYMBOL_TRADE_EXECUTION exemode=(ENUM_SYMBOL_TRADE_EXECUTION)SymbolInfoInteger(req.symbol,SYMBOL_TRADE_EXEMODE); //--- Заголовок PrintFormat("Request %s:",TradeActionDescription(req.action,ext_descr)); //--- Установить торговый ордер на немедленное совершение сделки с указанными параметрами (поставить рыночный ордер) if(req.action==TRADE_ACTION_DEAL) { //--- В зависимости от режима заключения сделок switch(exemode) { //--- Торговый ордер на открытие позиции в режиме Request Execution (режим торговли по запросу текущих цен) //--- Торговый ордер на открытие позиции в режиме Instant Execution (режим торговли по потоковым ценам) case SYMBOL_TRADE_EXECUTION_REQUEST : case SYMBOL_TRADE_EXECUTION_INSTANT : Print(MqlTradeRequestSymbol(req,header_width,indent)); Print(MqlTradeRequestVolume(req,header_width,indent)); Print(MqlTradeRequestPrice(req,header_width,indent)); if(req.position==0) // Только для открытия позиции Print(MqlTradeRequestStopLoss(req,header_width,indent)); if(req.position==0) // Только для открытия позиции Print(MqlTradeRequestTakeProfit(req,header_width,indent)); Print(MqlTradeRequestDeviation(req,header_width,indent)); Print(MqlTradeRequestType(req,header_width,indent,ext_descr)); Print(MqlTradeRequestTypeFilling(req,header_width,indent,ext_descr)); Print(MqlTradeRequestMagic(req,header_width,indent)); if(req.position==0) // Только для открытия позиции Print(MqlTradeRequestComment(req,header_width,indent)); //--- Закрытие if(req.position!=0) Print(MqlTradeRequestPosition(req,header_width,indent)); break; //--- Торговый ордер на открытие позиции в режиме Market Execution (режим исполнения торговых приказов по рынку) //--- Торговый ордер на открытие позиции в режиме Exchange Execution (биржевой режим исполнения торговых приказов) case SYMBOL_TRADE_EXECUTION_MARKET : case SYMBOL_TRADE_EXECUTION_EXCHANGE : Print(MqlTradeRequestSymbol(req,header_width,indent)); Print(MqlTradeRequestVolume(req,header_width,indent)); Print(MqlTradeRequestType(req,header_width,indent,ext_descr)); Print(MqlTradeRequestTypeFilling(req,header_width,indent,ext_descr)); Print(MqlTradeRequestMagic(req,header_width,indent)); if(req.position==0) // Только для открытия позиции Print(MqlTradeRequestComment(req,header_width,indent)); //--- Закрытие if(req.position!=0) Print(MqlTradeRequestPosition(req,header_width,indent)); break; default: break; } } //--- Торговый приказ на закрытие позиции встречной if(req.action==TRADE_ACTION_CLOSE_BY) { Print(MqlTradeRequestSymbol(req,header_width,indent)); Print(MqlTradeRequestPosition(req,header_width,indent)); Print(MqlTradeRequestMagic(req,header_width,indent)); Print(MqlTradeRequestComment(req,header_width,indent)); Print(MqlTradeRequestPositionBy(req,header_width,indent)); } //--- Торговый приказ на модификацию уровней StopLoss и/или TakeProfit if(req.action==TRADE_ACTION_SLTP) { Print(MqlTradeRequestSymbol(req,header_width,indent)); Print(MqlTradeRequestStopLoss(req,header_width,indent)); Print(MqlTradeRequestTakeProfit(req,header_width,indent)); Print(MqlTradeRequestPosition(req,header_width,indent)); } //--- Торговый приказ на установку отложенного ордера if(req.action==TRADE_ACTION_PENDING) { Print(MqlTradeRequestSymbol(req,header_width,indent)); Print(MqlTradeRequestVolume(req,header_width,indent)); Print(MqlTradeRequestPrice(req,header_width,indent)); if(req.type==ORDER_TYPE_BUY_STOP_LIMIT || req.type==ORDER_TYPE_SELL_STOP_LIMIT) Print(MqlTradeRequestStopLimit(req,header_width,indent)); Print(MqlTradeRequestStopLoss(req,header_width,indent)); Print(MqlTradeRequestTakeProfit(req,header_width,indent)); Print(MqlTradeRequestType(req,header_width,indent,ext_descr)); Print(MqlTradeRequestTypeFilling(req,header_width,indent,ext_descr)); Print(MqlTradeRequestTypeTime(req,header_width,indent,ext_descr)); Print(MqlTradeRequestExpiration(req,header_width,indent)); Print(MqlTradeRequestMagic(req,header_width,indent)); Print(MqlTradeRequestComment(req,header_width,indent)); } //--- Торговый приказ на модификацию уровней цен отложенного ордера if(req.action==TRADE_ACTION_MODIFY) { Print(MqlTradeRequestOrder(req,header_width,indent)); Print(MqlTradeRequestPrice(req,header_width,indent)); if(req.stoplimit!=0) Print(MqlTradeRequestStopLimit(req,header_width,indent)); Print(MqlTradeRequestStopLoss(req,header_width,indent)); Print(MqlTradeRequestTakeProfit(req,header_width,indent)); Print(MqlTradeRequestTypeTime(req,header_width,indent,ext_descr)); Print(MqlTradeRequestExpiration(req,header_width,indent)); } //--- Торговый приказ на удаление отложенного ордера if(req.action==TRADE_ACTION_REMOVE) { Print(MqlTradeRequestOrder(req,header_width,indent)); } /* Пример вывода: Request Pending (Place a trade order for the execution under specified conditions (pending order)): Symbol: EURUSD Volume: 0.10 Price: 1.09586 SL: 0.0 TP: 0.0 Type: Buy Limit (Buy Limit pending order) Type filling: Return (In case of partial filling, an order with remaining volume is not canceled but processed further) Type time: Time GTC (Good till cancel order) Expiration: 0 Magic: 1024 Comment: TestMqlTradeTransaction */ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Функции для работы со структурой | //| результата проверки торгового запроса MqlTradeCheckResult | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Возвращает в виде строки код ответа | //+------------------------------------------------------------------+ string MqlTradeCheckResultRetcode(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Retcode:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,RetcodeDescription(result.retcode,ext_descr)); /* Пример вывода: Retcode: OK (0) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки баланс после совершения сделки | //+------------------------------------------------------------------+ string MqlTradeCheckResultBalance(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Balance:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем валюту счёта string currency=AccountInfoString(ACCOUNT_CURRENCY); //--- Получаем количество знаков после запятой int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.balance,currency); /* Пример вывода: Balance: 10016.80 USD */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки эквити после совершения сделки | //+------------------------------------------------------------------+ string MqlTradeCheckResultEquity(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Equity:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем валюту счёта string currency=AccountInfoString(ACCOUNT_CURRENCY); //--- Получаем количество знаков после запятой int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.equity,currency); /* Пример вывода: Equity: 10016.80 USD */ } //+------------------------------------------------------------------+ //|Возвращает в виде строки плавающую прибыль после совершения сделки| //+------------------------------------------------------------------+ string MqlTradeCheckResultProfit(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Profit:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем валюту счёта string currency=AccountInfoString(ACCOUNT_CURRENCY); //--- Получаем количество знаков после запятой int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.profit,currency); /* Пример вывода: Profit: 0.00 USD */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки размер маржи, | //| необходимый для требуемой торговой операции | //+------------------------------------------------------------------+ string MqlTradeCheckResultMargin(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Margin:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем валюту счёта string currency=AccountInfoString(ACCOUNT_CURRENCY); //--- Получаем количество знаков после запятой int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.margin,currency); /* Пример вывода: Margin: 128.66 USD */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки размер свободных собственных средств, | //| которые останутся после выполнения требуемой торговой операции | //+------------------------------------------------------------------+ string MqlTradeCheckResultMarginFree(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Margin free:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем валюту счёта string currency=AccountInfoString(ACCOUNT_CURRENCY); //--- Получаем количество знаков после запятой int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.margin_free,currency); /* Пример вывода: Margin free: 9888.14 USD */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки уровень маржи, который установится | //| после выполнения требуемой торговой операции | //+------------------------------------------------------------------+ string MqlTradeCheckResultMarginLevel(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Margin level:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.2f %%",indent,"",w,header,result.margin_level); /* Пример вывода: Margin level: 7785.48 % */ } //+------------------------------------------------------------------+ //| Возвращает комментарий к коду ответа, описание ошибки | //+------------------------------------------------------------------+ string MqlTradeCheckResultComment(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Comment:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,result.comment); /* Пример вывода: Comment: Done */ } //+------------------------------------------------------------------+ //| Выводит в журнал поля структуры MqlTradeCheckResult | //| в результате OrderCheck | //+------------------------------------------------------------------+ void OrderCheckResultPrint(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0,bool ext_descr=false) { Print("OrderCheck result:"); Print(MqlTradeCheckResultRetcode(result,header_width,indent,ext_descr)); Print(MqlTradeCheckResultBalance(result,header_width,indent)); Print(MqlTradeCheckResultEquity(result,header_width,indent)); Print(MqlTradeCheckResultProfit(result,header_width,indent)); Print(MqlTradeCheckResultMargin(result,header_width,indent)); Print(MqlTradeCheckResultMarginFree(result,header_width,indent)); Print(MqlTradeCheckResultMarginLevel(result,header_width,indent)); Print(MqlTradeCheckResultComment(result,header_width,indent)); /* Пример вывода: OrderCheck result: Retcode: Undefined (0) Balance: 10016.80 USD Equity: 10016.80 USD Profit: 0.00 USD Margin: 128.66 USD Margin free: 9888.14 USD Margin level: 7785.48 % Comment: Done */ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Функции для работы со структурой | //| результата торгового запроса MqlTradeResult | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Возвращает в виде строки код результата операции | //+------------------------------------------------------------------+ string MqlTradeResultRetcode(const MqlTradeResult &result,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Retcode:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,RetcodeDescription(result.retcode,ext_descr)); /* Пример вывода: Retcode: 10009 DONE (Request completed) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет сделки, если она совершена | //+------------------------------------------------------------------+ string MqlTradeResultDeal(const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Deal:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,result.deal); /* Пример вывода: Deal: 0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет ордера, если он выставлен | //+------------------------------------------------------------------+ string MqlTradeResultOrder(const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Order:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,result.order); /* Пример вывода: Order: 1821552382 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки объем сделки, подтверждённый брокером | //+------------------------------------------------------------------+ string MqlTradeResultVolume(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Volume:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой в значении лота int dg=(int)ceil(fabs(log10(SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP)))); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.volume); /* Пример вывода: Volume: 0.10 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки цену в сделке, подтверждённую брокером | //+------------------------------------------------------------------+ string MqlTradeResultPrice(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Price:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой int dg=(result.price!=0 ? (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.price); /* Пример вывода: Price: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки текущую рыночную цену предложения (Bid) | //+------------------------------------------------------------------+ string MqlTradeResultBid(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Bid:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой int dg=(result.bid!=0 ? (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.bid); /* Пример вывода: Bid: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки текущую рыночную цену спроса (Ask) | //+------------------------------------------------------------------+ string MqlTradeResultAsk(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Ask:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой int dg=(result.ask!=0 ? (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.ask); /* Пример вывода: Ask: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает комментарий брокера к операции | //+------------------------------------------------------------------+ string MqlTradeResultComment(const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Comment:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,result.comment); /* Пример вывода: Comment: Request executed */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки идентификатор запроса | //+------------------------------------------------------------------+ string MqlTradeResultRequestID(const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Request ID:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-lu",indent,"",w,header,result.request_id); /* Пример вывода: Request ID: 3768213261 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки код ответа внешней торговой системы | //+------------------------------------------------------------------+ string MqlTradeResultRetcodeExternal(const MqlTradeResult &result,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Retcode External:"; uint w=(header_width==0 ? header.Length()+1 : header_width-1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%- ld",indent,"",w,header,result.retcode_external); /* Пример вывода: Retcode External: 0 */ } //+------------------------------------------------------------------+ //| Выводит в журнал поля структуры MqlTradeResult | //| в результате торгового запроса | //+------------------------------------------------------------------+ void TradeResultPrint(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0,bool ext_descr=false) { string symbol_name=(symbol==NULL ? Symbol() : symbol); Print("OrderSend result:"); Print(MqlTradeResultRetcode(result,header_width,indent,ext_descr)); Print(MqlTradeResultDeal(result,header_width,indent)); Print(MqlTradeResultOrder(result,header_width,indent)); Print(MqlTradeResultVolume(symbol_name,result,header_width,indent)); Print(MqlTradeResultPrice(symbol_name,result,header_width,indent)); Print(MqlTradeResultBid(symbol_name,result,header_width,indent)); Print(MqlTradeResultAsk(symbol_name,result,header_width,indent)); Print(MqlTradeResultComment(result,header_width,indent)); Print(MqlTradeResultRequestID(result,header_width,indent)); Print(MqlTradeResultRetcodeExternal(result,header_width,indent)); /* Пример вывода: OrderSend result: Retcode: 10009 DONE (Request completed) Deal: 0 Order: 1821671230 Volume: 0.10 Price: 0.0 Bid: 0.0 Ask: 0.0 Comment: Request executed Request ID: 3768213265 Retcode External: 0 */ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Функции для работы со структурой | //| торговой транзакции MqlTradeTransaction | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет сделки | //+------------------------------------------------------------------+ string MqlTradeTransactionDeal(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Deal:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.deal); /* Пример вывода: Deal: 0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет ордера | //+------------------------------------------------------------------+ string MqlTradeTransactionOrder(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Order:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.order); /* Пример вывода: Order: 1825990224 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки символ ордера | //+------------------------------------------------------------------+ string MqlTradeTransactionSymbol(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Symbol:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,trans.symbol); /* Пример вывода: Symbol: EURUSD */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тип торговой транзакции | //+------------------------------------------------------------------+ string MqlTradeTransactionType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Type:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,TradeTransactionTypeDescription(trans.type,ext_descr)); /* Пример вывода: Type: Order delete (Removing an order from the list of the open ones) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тип ордера | //+------------------------------------------------------------------+ string MqlTradeTransactionOrderType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Объявляем переменные для указания принадлежности транзакции bool trans_req=false; // Запрос bool trans_order=false; // Ордер bool trans_deal=false; // Сделка bool trans_pos=false; // Позиция //--- Устанавливаем принадлежность транзакции SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos); //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Order type:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_order ? OrderTypeDescription(trans.order_type,ext_descr) : "0")); /* Пример вывода: Order type: Sell Limit (Sell Limit pending order) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки состояние ордера | //+------------------------------------------------------------------+ string MqlTradeTransactionOrderState(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Объявляем переменные для указания принадлежности транзакции bool trans_req=false; // Запрос bool trans_order=false; // Ордер bool trans_deal=false; // Сделка bool trans_pos=false; // Позиция //--- Устанавливаем принадлежность транзакции SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos); //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Order state:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_order ? OrderStateDescription(trans.order_state,ext_descr) : "0")); /* Пример вывода: Order state: Started (Order checked, but not yet accepted by broker) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тип сделки | //+------------------------------------------------------------------+ string MqlTradeTransactionDealType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Объявляем переменные для указания принадлежности транзакции bool trans_req=false; // Запрос bool trans_order=false; // Ордер bool trans_deal=false; // Сделка bool trans_pos=false; // Позиция //--- Устанавливаем принадлежность транзакции SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos); //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Deal type:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_deal || trans_pos ? DealTypeDescription(trans.deal_type,ext_descr) : "0")); /* Пример вывода: Deal type: Buy */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тип ордера по времени действия | //+------------------------------------------------------------------+ string MqlTradeTransactionTimeType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Объявляем переменные для указания принадлежности транзакции bool trans_req=false; // Запрос bool trans_order=false; // Ордер bool trans_deal=false; // Сделка bool trans_pos=false; // Позиция //--- Устанавливаем принадлежность транзакции SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos); //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Time type:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_order ? OrderTypeTimeDescription(trans.time_type,ext_descr) : "0")); /* Пример вывода: Order type time: Time GTC (Good till cancel order) */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки срок истечения ордера | //+------------------------------------------------------------------+ string MqlTradeTransactionTimeExpiration(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Time expiration:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Запишем время экспирации в виде строки. Если 0, то впишем 0 string tm=(trans.time_expiration==0 ? "0" : (string)trans.time_expiration); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-s",indent,"",w,header,tm); /* Пример вывода: Time expiration: 0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки цену ордера/сделки/позиции | //+------------------------------------------------------------------+ string MqlTradeTransactionPrice(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Price:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получим Digits символа. Если символ не указан, используем 1 int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price); /* Пример вывода: Price: 1.10331 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки цену срабатывания стоп-лимитного ордера | //+------------------------------------------------------------------+ string MqlTradeTransactionPriceTrigger(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Price trigger:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получим Digits символа. Если символ не указан или стоп-цена отсутствует, используем 1 int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1); if(trans.price_trigger==0) dg=1; //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price_trigger); /* Пример вывода: Price trigger: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки цену Stop Loss | //+------------------------------------------------------------------+ string MqlTradeTransactionPriceSL(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Price SL:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получим Digits символа. Если символ не указан или цена Stop Loss отсутствует, используем 1 int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1); if(trans.price_sl==0) dg=1; //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price_sl); /* Пример вывода: Price SL: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки цену Take Profit | //+------------------------------------------------------------------+ string MqlTradeTransactionPriceTP(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Price TP:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получим Digits символа. Если символ не указан или цена Take Profit отсутствует, используем 1 int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1); if(trans.price_tp==0) dg=1; //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price_tp); /* Пример вывода: Price TP: 0.0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки объём в лотах | //+------------------------------------------------------------------+ string MqlTradeTransactionVolume(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Volume:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Получаем количество знаков после запятой в значении лота. Если символ не указан, используем 1 int dg=(trans.symbol!="" ? (int)ceil(fabs(log10(SymbolInfoDouble(trans.symbol,SYMBOL_VOLUME_STEP)))) : 1); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.volume); /* Пример вывода: Volume: 0.10 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет позиции | //+------------------------------------------------------------------+ string MqlTradeTransactionPosition(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Position:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.position); /* Пример вывода: Position: 0 */ } //+------------------------------------------------------------------+ //| Возвращает в виде строки тикет встречной позиции | //+------------------------------------------------------------------+ string MqlTradeTransactionPositionBy(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0) { //--- Определяем текст заголовка и ширину поля заголовка //--- Если ширина заголовка передана в функцию равной нулю, то шириной будет размер строки заголовка + 1 string header="Position by:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Возвращаем значение свойства с заголовком с нужной шириной и отступом return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.position_by); /* Пример вывода: Position by: 0 */ } //+------------------------------------------------------------------+ //| Выводит в журнал поля структуры MqlTradeTransaction | //+------------------------------------------------------------------+ void MqlTradeTransactionPrint(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false) { Print(MqlTradeTransactionDeal(trans,header_width,indent)); Print(MqlTradeTransactionOrder(trans,header_width,indent)); Print(MqlTradeTransactionSymbol(trans,header_width,indent)); Print(MqlTradeTransactionType(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionOrderType(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionOrderState(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionDealType(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionTimeType(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionTimeExpiration(trans,header_width,indent)); Print(MqlTradeTransactionPrice(trans,header_width,indent)); Print(MqlTradeTransactionPriceTrigger(trans,header_width,indent)); Print(MqlTradeTransactionPriceSL(trans,header_width,indent)); Print(MqlTradeTransactionPriceTP(trans,header_width,indent)); Print(MqlTradeTransactionVolume(trans,header_width,indent)); Print(MqlTradeTransactionPosition(trans,header_width,indent)); Print(MqlTradeTransactionPositionBy(trans,header_width,indent)); /* Пример вывода: Deal: 0 Order: 1829189788 Symbol: EURUSD Type: Order add Order type: Buy Limit Order state: Started Deal type: 0 Time type: Time GTC Time expiration: 0 Price: 1.09861 Price trigger: 0.0 Price SL: 0.0 Price TP: 0.0 Volume: 0.10 Position: 0 Position by: 0 */ } //+------------------------------------------------------------------+ //| Информер торговых транзакций | //+------------------------------------------------------------------+ void TradeTransactionInformer(const MqlTradeTransaction &trans,const MqlTradeRequest& request,const MqlTradeResult& result, const uint header_width=0,const uint indent=0,const bool ext_descr=false) { //--- Объявляем переменные для указания принадлежности транзакции bool trans_req=false; // Запрос bool trans_order=false; // Ордер bool trans_deal=false; // Сделка bool trans_pos=false; // Позиция //--- Устанавливаем принадлежность транзакции SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos); //--- В зависимости от принадлежности транзакции выводим описания соответствующих полей структуры //--- Торговый запрос if(trans_req) { //--- Сообщаем тип транзакции "торговый запрос" и указываем, что нужно анализировать поля структуры торгового запроса и ответа сервера PrintFormat("Transaction %s\n%*sThe second and third parameters of OnTradeTransaction function (request and result) must be analyzed for additional data:", MqlTradeTransactionType(trans,0,0,true),indent,""); //--- Выводим в журнал описание торгового запроса и результата этого запроса, полученного от сервера TradeRequestPrint(request,header_width,indent,ext_descr); TradeResultPrint(trans.symbol,result,header_width,indent,ext_descr); } //--- Иначе, если ордер/сделка/позиция else { //--- Выводим в журнал тип транзакции PrintFormat("Transaction %s",MqlTradeTransactionType(trans,0,0,true)); //--- Ордер if(trans_order) { Print(MqlTradeTransactionOrder(trans,header_width,indent)); Print(MqlTradeTransactionSymbol(trans,header_width,indent)); Print(MqlTradeTransactionOrderType(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionOrderState(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionTimeType(trans,header_width,indent,ext_descr)); if(trans.time_type==ORDER_TIME_SPECIFIED || trans.time_type==ORDER_TIME_SPECIFIED_DAY) Print(MqlTradeTransactionTimeExpiration(trans,header_width,indent)); Print(MqlTradeTransactionPrice(trans,header_width,indent)); if(trans.order_type==ORDER_TYPE_BUY_STOP_LIMIT || trans.order_type==ORDER_TYPE_SELL_STOP_LIMIT) Print(MqlTradeTransactionPriceTrigger(trans,header_width,indent)); Print(MqlTradeTransactionPriceSL(trans,header_width,indent)); Print(MqlTradeTransactionPriceTP(trans,header_width,indent)); Print(MqlTradeTransactionVolume(trans,header_width,indent)); if(trans.type!=TRADE_TRANSACTION_ORDER_ADD && (trans.order_type==ORDER_TYPE_BUY || trans.order_type==ORDER_TYPE_SELL)) Print(MqlTradeTransactionPosition(trans,header_width,indent)); if(trans.order_type==ORDER_TYPE_CLOSE_BY) Print(MqlTradeTransactionPositionBy(trans,header_width,indent)); } //--- Сделка if(trans_deal) { Print(MqlTradeTransactionDeal(trans,header_width,indent)); Print(MqlTradeTransactionOrder(trans,header_width,indent)); Print(MqlTradeTransactionSymbol(trans,header_width,indent)); Print(MqlTradeTransactionDealType(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionPrice(trans,header_width,indent)); Print(MqlTradeTransactionPriceSL(trans,header_width,indent)); Print(MqlTradeTransactionPriceTP(trans,header_width,indent)); Print(MqlTradeTransactionVolume(trans,header_width,indent)); Print(MqlTradeTransactionPosition(trans,header_width,indent)); } //--- Позиция if(trans_pos) { Print(MqlTradeTransactionSymbol(trans,header_width,indent)); Print(MqlTradeTransactionDealType(trans,header_width,indent,ext_descr)); Print(MqlTradeTransactionPrice(trans,header_width,indent)); Print(MqlTradeTransactionPriceSL(trans,header_width,indent)); Print(MqlTradeTransactionPriceTP(trans,header_width,indent)); Print(MqlTradeTransactionVolume(trans,header_width,indent)); Print(MqlTradeTransactionPosition(trans,header_width,indent)); } } /* Пример вывода при установке ордера Sell Limit: Transaction Type: Order add (Adding a new open order) Order: 1833072954 Symbol: EURUSD Order type: Sell Limit (Sell Limit pending order) Order state: Started (Order checked, but not yet accepted by broker) Time type: Time GTC (Good till cancel order) Price: 1.10516 Price SL: 0.0 Price TP: 0.0 Volume: 0.10 Transaction Type: Order update (Updating an open order) Order: 1833072954 Symbol: EURUSD Order type: Sell Limit (Sell Limit pending order) Order state: Placed (Order accepted) Time type: Time GTC (Good till cancel order) Price: 1.10516 Price SL: 0.0 Price TP: 0.0 Volume: 0.10 Transaction Type: Request (The trade request has been processed by a server and processing result has been received) The second and third parameters of OnTradeTransaction function (request and result) must be analyzed for additional data: Request Pending (Place a trade order for the execution under specified conditions (pending order)): Symbol: EURUSD Volume: 0.10 Price: 1.10516 SL: 0.0 TP: 0.0 Type: Sell Limit (Sell Limit pending order) Type filling: Return (In case of partial filling, an order with remaining volume is not canceled but processed further) Type time: Time GTC (Good till cancel order) Expiration: 0 Magic: 1024 Comment: TestMqlTradeTransaction OrderSend result: Retcode: 10009 DONE (Request completed) Deal: 0 Order: 1833072954 Volume: 0.10 Price: 0.0 Bid: 0.0 Ask: 0.0 Comment: Request ID: 3768213464 Retcode External: 0 //--- Здесь при установке отложенного ордера Buy Limit мы порлучили три транзакции: 1. Запрос - запрос на установку отложенного ордера был принят сервером и был получен ответ. Для уточнения информации необходимо анализировать поля структуры торгового запроса MqlTradeRequest и ответа сервера MqlTradeResult – request и result соответственно. 2. Добавление нового отложенного ордера с тикетом #1829788294. Его состояние - Started. 3. Изменение открытого ордера с тикетом #1829788294. Его состояние сменилось со Started на Placed. Очерёдность транзакций не соблюдена, но об этом явно указано в справке по обработчику OnTradeTransaction: https://www.mql5.com/ru/docs/event_handlers/ontradetransaction. */ } //+------------------------------------------------------------------+