Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 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);
      }   

Returns error 4108 sometimes - wrong ticket for OrderClose. Is it possible that OrderTicket() does not match the ticket in OrderSelect? The ticket variable can be equal to zero.

It takes me a long time to reproduce the error, it's easier to ask.
 
Dmitri Custurov:

Returns error 4108 sometimes - wrong ticket for OrderClose. Is it possible that OrderTicket() does not match the ticket in OrderSelect ? The ticket variable can be equal to zero.

It takes me a long time to reproduce the error, it's easier to ask.

You select an order by ticket. Are you sure that the selected order is not already closed? But you try to close it again ... Check the closing time after successfully selecting the ticket.

 
Artyom Trishkin:

You are selecting the order on the ticket. And you are sure that the selected order is not already closed? But you are trying to close it again. Check the closing time after a successful selection on the ticket.

I'll check when I reproduce the error. I have all tickets stored in global variables. When the order is closed, they are deleted. Before OrderSelect() ticket is taken from global variables. If the ticket is not in variables - this variable will be 0, and thus the order should not be selected and OrderSelect() will return false. But in general, yes, it's worth checking. Thank you.

 
Dmitri Custurov:

I'll check when I reproduce the error. I have all tickets stored in global variables. When the order is closed, they are deleted. Before OrderSelect() ticket is taken from global variables. If the ticket is not in variables - this variable will be 0, and thus the order should not be selected and OrderSelect() will return false. But in general, yes, it's worth checking. Thank you.

It is standard to check the closing price when an order is selected by ticket. You wouldn't know in any other way if the order is closed and selected from the list of closed orders, or if it is still open and selected from the list of market orders.

The most shortsighted way is to store tickets in global variables. They should be taken from the trading environment - the current information is there.

 
Artyom Trishkin:

It is standard to check the closing price when an order is selected by ticket. You will not know in any other way if the order is closed and selected from the list of closed, or if it is still open and selected from the list of market ones.

It is the most short-sighted to store tickets in global variables. They should be taken from the trading environment - the current information is there.

If I select like this: OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), is it supposed to partially solve the problem? I store tickets in global variables for other reasons, well, I used it in this case too.

 
Dmitri Custurov:

If I select like this: OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), is it supposed to partially solve the problem? I store tickets in global variables for other reasons, and I used them in this case as well.

No, it won't - pool (MODE_TRADES) is ignored during selection by ticket.

 
Dmitri Custurov:

Returns error 4108 sometimes - wrong ticket for OrderClose. Is it possible that OrderTicket() does not match the ticket in OrderSelect ? The ticket variable might be equal to zero.

It takes me a long time to reproduce the error, it's much easier to ask.

It is usually sufficient to check for market orders:

OrderCloseTime() == 0 //order is open

OrderCloseTime() > 0 //the order is closed

for limit orders, you should also check the close price; if it is equal to 0, the limit order has been cancelled

 
Thank you all for your answers, I get it ))
 

Hello!

Share the code using the PositionClosePartial method, if you can.

Theoretically I understand how it works, but I'd like to see some working code.

Or advise me where to look.

Thank you in advance.

 
odyn:

Hello!

Share the code using the PositionClosePartial method, if you can.

Theoretically I understand how it works, but I'd like to see some working code.

Or advise me where to look.

I am grateful in advance.

Actually it is just one line of code. But you have to get the position ticket for it. Here is the Expert Advisor from OnInit that opens position with 0.2 lot and closes half of position in 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);
   }
 }
//+------------------------------------------------------------------+

Or here is the full code from the CTrade class

//+------------------------------------------------------------------+
//| 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));
  }
Files:
00.mq5  5 kb
Reason: