Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 854

 
Я тут вожусь с CTrade::PositionClose(const ulong ticket,const ulong deviation=ULONG_MAX) и понимаю, что внутри оно организовано не совсем. Все дело в 2-х кодах возврата - bool и ResultRetcode(). RetCode не всегда зануляется внутри перед возвратом false, так что если PositionClose выдает false, то RetCode может вполне вернуть TRADE_RETCODE_DONE. Как-бы эти 2 возвращаемых значения разработчикам синхронизировать.
 
. ... Rick D. ... .:
Я тут вожусь с CTrade::PositionClose(const ulong ticket,const ulong deviation=ULONG_MAX) и понимаю, что внутри оно организовано не совсем. Все дело в 2-х кодах возврата - bool и ResultRetcode(). RetCode не всегда зануляется внутри перед возвратом false, так что если PositionClose выдает false, то RetCode может вполне вернуть TRADE_RETCODE_DONE. Как-бы эти 2 возвращаемых значения разработчикам синхронизировать.

Код + пример + логи.

 
Нашелся один странный баг. Может только у меня.

COrderInfo::OrderType() всегда возвращает 0.

Для проверки можно выставить вручную любой отложенный ордер (BuyStop, SellStop, ...),
затем вписать его ticket в скрипте.
#include <Trade\Trade.mqh>

COrderInfo m_order;

void OnStart()
{
  ulong ticket = 250262937; //здесь ваш тикет
  
  if (!m_order.Select(ticket))
  {
    PrintFormat("COrderInfo::Select(#%I64u) failed", ticket);
    return;
  }
  
  PrintFormat("OrderType= %d", m_order.Type());
}

Может что-то с таблицей виртуальных функций? В отладке я попадаю только в virtual int CObject::Type()

PS. Сам уже разобрался. У COrderInfo есть 2 похожих метода: Type() и OrderType().

 
Vladimir Karputov:

Код + пример + логи.

Смотрите, какую ситуация я имею ввиду.

#include <Trade\Trade.mqh>

CTrade m_trade;

void OnStart()
{ 
  int LErr;
  bool bRC;
  double price;

  ResetLastError();
  
  price = 0.0;
  bRC = m_trade.Buy(0.1, "EURUSD", price, 0.0, 0.0);

  LErr = GetLastError();

  PrintFormat("! Buy:  (bRC= %s)(RetCode= %u: %s)(LErr= %d)",
    ticket,
    (string)bRC, 
    m_trade.ResultRetcode(), 
    m_trade.ResultComment(), 
    LErr
  );
  
  //В m_trade.ResultRetcode() теперь TRADE_RETCODE_DONE
  
  //---

  ulong ticket = 1; //Позиции с таким тикетом нет
  
  ResetLastError();

  bRC = m_trade.PositionClose(ticket);  

  LErr = GetLastError();
  
  PrintFormat("! Close #%I64u:  (bRC= %s)(RetCode= %u: %s)(LErr= %d)",
    ticket,
    (string)bRC, 
    m_trade.ResultRetcode(), 
    m_trade.ResultComment(), 
    LErr
  );
  
  //В m_trade.ResultRetcode() все еще TRADE_RETCODE_DONE
}

У CTrade я не вижу методов SetResultRetcode и SetResultComment, чтобы перед каждой новой операцией сбрасывать их.

Приходится наследовать свой класс, где добавляется один единственный метод


class CTradeEx : public CTrade
{
public:
  void SetResult(MqlTradeResult& result)
  {
    m_result = result;
  }  
};
 
. ... Rick D. ... .:

Смотрите, какую ситуация я имею ввиду.

У CTrade я не вижу методов SetResultRetcode и SetResultComment, чтобы перед каждой новой операцией сбрасывать их.

А зачем? Абсолютно не нужные функции.

Первое: Вы стреляете в воздух - отсылаете торговый приказ без первой проверки - без проверки что вернула операция. Смотрим справку: PositionClose имеет тип bool.

Второе: смотрим цепочку закрытия позиции: когда позиция не найдена (её невозможно выбрать по указанному тикету) возвращается "false". 

//+------------------------------------------------------------------+
//| Close specified opened position                                  |
//+------------------------------------------------------------------+
bool CTrade::PositionClose(const ulong ticket,const ulong deviation)
  {
//--- check stopped
   if(IsStopped(__FUNCTION__))
      return(false);
//--- check position existence
   if(!PositionSelectByTicket(ticket))
      return(false);
   string symbol=PositionGetString(POSITION_SYMBOL);
//--- clean

При этом нигде структуры не очищаются - так как это бессмысленно - ведь перед этим не удалось выбрать позицию, следовательно в структурах нет никакой информации.

 
Vladimir Karputov:

А зачем? Абсолютно не нужные функции.

Первое: Вы стреляете в воздух - отсылаете торговый приказ без первой проверки - без проверки что вернула операция. Смотрим справку: PositionClose имеет тип bool.

Второе: смотрим цепочку закрытия позиции: когда позиция не найдена (её невозможно выбрать по указанному тикету) возвращается "false". 

При этом нигде структуры не очищаются - так как это бессмысленно - ведь перед этим не удалось выбрать позицию, следовательно в структурах нет никакой информации.

1) С таким-же успехом можно сказать, что ResetLastError() абсолютно ненужная функция.

2) Проверка возвращаемого результата есть. Представьте, по аналогии вы вызываете какую-то функцию WinAPI, она возвращает ошибку, а GetLastError() (аналог ResultRetcode) возвращает любой последний код.

Если я добавлю какую-то проверку перед вызовом PositionClose (а я ее добавлю), это не отменяет любых других проверок перед любыми другими вызовами, когда RetCode не изменится.

Мой эксперт пишет в лог информацию. Все, что мне нужно - это написать в лог вменяемые ResultRetcode и ResultComment, если какой-то вызов вернул false.

 
. ... Rick D. ... .:

1) С таким-же успехом можно сказать, что ResetLastError() абсолютно ненужная функция.

2) Проверка возвращаемого результата есть. Представьте, по аналогии вы вызываете какую-то функцию WinAPI, она возвращает ошибку, а GetLastError() (аналог ResultRetcode) возвращает любой последний код.

Если я добавлю какую-то проверку перед вызовом PositionClose (а я ее добавлю), это не отменяет любых других проверок перед любыми другими вызовами, когда RetCode не изменится.

Мой эксперт пишет в лог информацию. Все, что мне нужно - это написать в лог вменяемые ResultRetcode и ResultComment, если какой-то вызов вернул false.

Прочтите в справке по торговым операциям класса CTrade когда нужно  проверять результат выполнения торгового запроса (код возврата торгового сервера) вызовом метода ResultRetcode().

 
Vladimir Karputov:

Прочтите в справке по торговым операциям класса CTrade когда нужно  проверять результат выполнения торгового запроса (код возврата торгового сервера) вызовом метода ResultRetcode().

Вы можете утверждать, что

1) Если PositionClose возвращает false, то Retcode никогда не заполняется?

2) Если PositionClose возвращает true, то Retcode заполняется всегда?

 
Vladimir Karputov:

Ордер -> сделка -> позиция. Берите с позиции цену открытия.

Можете показать картинку как это Ордер -> сделка -> позиция, это снизу где сделки пишет так оно там не даёт копировать


 
Seric29:

Можете показать картинку как это Ордер -> сделка -> позиция, это снизу где сделки пишет так оно там не даёт копировать


Пожалуйста или перепишите свой вопрос или расставьте знаки препинания, а ещё лучше добавьте на картинке что, где и кто. Иначе получается, что я вижу знакомые буквы, а понять смысл и Вашу мысль не могу.

Причина обращения: