Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1110

 
if(OrderSelect(ticket, SELECT_BY_TICKET)){
      double lots;
      string symbol = OrderSymbol(); 
      while(true){
         RefreshRates();
         double price;
         parseClosePrice(OrderType(), symbol, price);
         if(OrderClose(OrderTicket(), OrderLots(), price, 500)){
            break;
         }else{
            Print(GetLastError());
         }              
         Sleep(1000);
      }   

Возвращает ошибку 4108 иногда - неправильный тикет для OrderClose. Может ли быть так что OrderTicket() не совпадает с тикетом в OrderSelect ? Переменная ticket может быть равной нулю.

Мне долго воспроизводить ошибку, проще спросить.
 
Dmitri Custurov:

Возвращает ошибку 4108 иногда - неправильный тикет для OrderClose. Может ли быть так что OrderTicket() не совпадает с тикетом в OrderSelect ? Переменная ticket может быть равной нулю.

Мне долго воспроизводить ошибку, проще спросить.

Вы выбираете ордер по тикету. А уверены, что выбранный ордер уже не закрыт? Но при этом пытаетесь его опять закрыть... Время закрытия проверьте после успешного выбора по тикету.

 
Artyom Trishkin:

Вы выбираете ордер по тикету. А уверены, что выбранный ордер уже не закрыт? Но при этом пытаетесь его опять закрыть... Время закрытия проверьте после успешного выбора по тикету.

Я проверю, когда воспроизведу ошибку. У меня все тикеты в глобальных переменных хранятся. При закрытии ордера они удаляются. Перед OrderSelect() ticket берется из глобальных переменных. Если тикета нет в переменных - эта переменная будет 0, а значит ордер не должен выбраться и OrderSelect() вернет false. Но вообще да, стоит проверить. Спасибо.

 
Dmitri Custurov:

Я проверю, когда воспроизведу ошибку. У меня все тикеты в глобальных переменных хранятся. При закрытии ордера они удаляются. Перед OrderSelect() ticket берется из глобальных переменных. Если тикета нет в переменных - эта переменная будет 0, а значит ордер не должен выбраться и OrderSelect() вернет false. Но вообще да, стоит проверить. Спасибо.

Это стандартно - проверить цену закрытия при выборе ордера по тикету. Другим способом вы нормально не узнаете закрыт ли ордер, и выбран из списка закрытых, или ещё открыт, и выбран из списка рыночных.

Самое недальновидное - хранить тикеты в глобальных переменных. Их нужно брать из торгового окружения - там актуальная на текущий момент информация.

 
Artyom Trishkin:

Это стандартно - проверить цену закрытия при выборе ордера по тикету. Другим способом вы нормально не узнаете закрыт ли ордер, и выбран из списка закрытых, или ещё открыт, и выбран из списка рыночных.

Самое недальновидное - хранить тикеты в глобальных переменных. Их нужно брать из торгового окружения - там актуальная на текущий момент информация.

Если я буду выбирать вот так: OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), по идее это частично решит проблему? Тикеты в глобальных переменных храню по другим причинам, ну и заодно воспользовался в этом случае.

 
Dmitri Custurov:

Если я буду выбирать вот так: OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), по идее это частично решит проблему? Тикеты в глобальных переменных храню по другим причинам, ну и заодно воспользовался в этом случае.

Нет, не решит - pool (MODE_TRADES) при выборе по тикету игнорируется.

 
Dmitri Custurov:

Возвращает ошибку 4108 иногда - неправильный тикет для OrderClose. Может ли быть так что OrderTicket() не совпадает с тикетом в OrderSelect ? Переменная ticket может быть равной нулю.

Мне долго воспроизводить ошибку, проще спросить.

обычно достаточно проверить для рыночных ордеров:

OrderCloseTime() == 0 //ордер открыт

OrderCloseTime() > 0 //ордер закрыт

для лимитных ордеров нужно еще смотреть цену закрытия, если она равна 0 - то лимитник был Canceled

 
Всем спасибо за ответы, я понял ))
 

Здравствуйте!

Поделитесь, кто может, кодом с употреблением метода PositionClosePartial . 

Теоретически понимаю, как работает, но мне бы на рабочий код посмотреть.

Или посоветуйте, где посмотреть.

Заранее благодарен.

 
odyn:

Здравствуйте!

Поделитесь, кто может, кодом с употреблением метода PositionClosePartial . 

Теоретически понимаю, как работает, но мне бы на рабочий код посмотреть.

Или посоветуйте, где посмотреть.

Заранее благодарен.

Практически это одна строка кода. Но для неё надо получить тикет позиции. Вот советник из OnInit открывающий позицию лотом 0.2 и в OnTick закрывающий половину позиции.

//+------------------------------------------------------------------+
//|                                                           00.mq5 |
//|                                          © 2020, Alexey Viktorov |
//|                     https://www.mql5.com/ru/users/alexeyvik/news |
//+------------------------------------------------------------------+
#property copyright "© 2020, Alexey Viktorov"
#property link      "https://www.mql5.com/ru/users/alexeyvik/news"
#property version   "1.00"

#include <Trade\Trade.mqh>
CTrade trade;
ulong posTicket;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
 {
  trade.SetExpertMagicNumber(111);
  trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, 0.2, SymbolInfoDouble(_Symbol, SYMBOL_ASK), 0.0, 0.0);
  return(INIT_SUCCEEDED);
 }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
 {
//---
 }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
 {
  if(PositionSelectByTicket(posTicket) && PositionGetDouble(POSITION_VOLUME) > 0.1)
    trade.PositionClosePartial(posTicket, 0.1);
 }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
 {
//---
  if(trans.type == TRADE_TRANSACTION_HISTORY_ADD)
   {
    if(PositionSelectByTicket(trans.position) && PositionGetInteger(POSITION_MAGIC) == 111 && PositionGetString(POSITION_SYMBOL) == _Symbol)
      posTicket = PositionGetInteger(POSITION_TICKET);
   }
 }
//+------------------------------------------------------------------+

Или вот полный код из класса CTrade

//+------------------------------------------------------------------+
//| Partial close specified opened position (for hedging mode only)  |
//+------------------------------------------------------------------+
bool CTrade::PositionClosePartial(const ulong ticket,const double volume,const ulong deviation)
  {
//--- check stopped
   if(IsStopped(__FUNCTION__))
      return(false);
//--- for hedging mode only
   if(!IsHedging())
      return(false);
//--- check position existence
   if(!PositionSelectByTicket(ticket))
      return(false);
   string symbol=PositionGetString(POSITION_SYMBOL);
//--- clean
   ClearStructures();
//--- check filling
   if(!FillingCheck(symbol))
      return(false);
//--- check
   if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
     {
      //--- prepare request for close BUY position
      m_request.type =ORDER_TYPE_SELL;
      m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
     }
   else
     {
      //--- prepare request for close SELL position
      m_request.type =ORDER_TYPE_BUY;
      m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
     }
//--- check volume
   double position_volume=PositionGetDouble(POSITION_VOLUME);
   if(position_volume>volume)
      position_volume=volume;
//--- setting request
   m_request.action   =TRADE_ACTION_DEAL;
   m_request.position =ticket;
   m_request.symbol   =symbol;
   m_request.volume   =position_volume;
   m_request.magic    =m_magic;
   m_request.deviation=(deviation==ULONG_MAX) ? m_deviation : deviation;
//--- close position
   return(OrderSend(m_request,m_result));
  }
Файлы:
00.mq5  5 kb
Причина обращения: