2051 lines
136 KiB
MQL5
2051 lines
136 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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;i<total;i++)
|
|
{
|
|
int pos=StringFind(res,"_",index);
|
|
//--- Если подчёркивание найдено,
|
|
if(pos>0)
|
|
{
|
|
//--- заменяем его на пробел и следующую букву переводим в верхний регистр
|
|
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.
|
|
*/
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|