Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 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);
      }   

Devuelve el error 4108 a veces - ticket equivocado para OrderClose. ¿Es posible que OrderTicket() no coincida con el ticket en OrderSelect? La variable del ticket puede ser igual a cero.

Me lleva mucho tiempo reproducir el error, es más fácil preguntar.
 
Dmitri Custurov:

Devuelve el error 4108 a veces - ticket equivocado para OrderClose. ¿Es posible que OrderTicket() no coincida con el ticket en OrderSelect? La variable del ticket puede ser igual a cero.

Me lleva mucho tiempo reproducir el error, es más fácil preguntar.

Se selecciona un pedido por billete. ¿Está seguro de que el pedido seleccionado no está ya cerrado? Pero intentas cerrarlo de nuevo... Compruebe la hora de cierre después de seleccionar correctamente el billete.

 
Artyom Trishkin:

Está seleccionando el orden en el billete. ¿Y está seguro de que el pedido seleccionado no está ya cerrado? Pero usted está tratando de cerrarlo de nuevo. Compruebe la hora de cierre después de una selección exitosa en el billete.

Lo comprobaré cuando reproduzca el error. Tengo todos los tickets almacenados en variables globales. Cuando se cierra el pedido, se eliminan. Antes de la entrada de OrderSelect() se toma de las variables globales. Si el ticket no está en variables - esta variable será 0, y por lo tanto el pedido no debe ser seleccionado y OrderSelect() devolverá false. Pero en general, sí, merece la pena comprobarlo. Gracias.

 
Dmitri Custurov:

Lo comprobaré cuando reproduzca el error. Tengo todos los tickets almacenados en variables globales. Cuando se cierra el pedido, se eliminan. Antes de la entrada de OrderSelect() se toma de las variables globales. Si el ticket no está en variables - esta variable será 0, y por lo tanto el pedido no debe ser seleccionado y OrderSelect() devolverá false. Pero en general, sí, merece la pena comprobarlo. Gracias.

Es habitual comprobar el precio de cierre cuando se selecciona una orden por ticket. No se sabría de otra manera si la orden está cerrada y seleccionada de la lista de órdenes cerradas, o si sigue abierta y seleccionada de la lista de órdenes de mercado.

La forma más miope es almacenar las entradas en variables globales. Deben tomarse del entorno comercial: la información actual está ahí.

 
Artyom Trishkin:

Es habitual comprobar el precio de cierre cuando se selecciona una orden por ticket. No sabrá de ninguna otra manera si la orden está cerrada y seleccionada de la lista de cerradas, o si sigue abierta y seleccionada de la lista de las de mercado.

Es lo más corto de miras almacenar las entradas en variables globales. Deben tomarse del entorno comercial: la información actual está ahí.

Si selecciono así: OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), ¿se supone que resuelve parcialmente el problema? Yo almaceno las entradas en variables globales por otras razones, pues bien, lo he utilizado en este caso también.

 
Dmitri Custurov:

Si selecciono así: OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), ¿se supone que resuelve parcialmente el problema? Almaceno las entradas en variables globales por otras razones, y las he utilizado también en este caso.

No, no lo hará - el pool (MODE_TRADES) se ignora durante la selección por ticket.

 
Dmitri Custurov:

Devuelve el error 4108 a veces - ticket equivocado para OrderClose. ¿Es posible que OrderTicket() no coincida con el ticket en OrderSelect? La variable del ticket puede ser igual a cero.

Me lleva mucho tiempo reproducir el error, es mucho más fácil preguntar.

Por lo general, basta con comprobar si hay órdenes de mercado:

OrderCloseTime() == 0 /el pedido está abierto

OrderCloseTime() > 0 //la orden está cerrada

en el caso de las órdenes limitadas, también debe comprobar el precio de cierre; si es igual a 0, la orden limitada ha sido cancelada

 
Gracias a todos por vuestras respuestas, lo entiendo ))
 

¡Hola!

Comparta el código utilizando el método PositionClosePartial, si puede.

Teóricamente entiendo cómo funciona, pero me gustaría ver algún código que funcione.

O aconséjame dónde buscar.

Gracias de antemano.

 
odyn:

¡Hola!

Comparta el código utilizando el método PositionClosePartial, si puede.

Teóricamente entiendo cómo funciona, pero me gustaría ver algún código que funcione.

O aconséjame dónde buscar.

Gracias de antemano.

En realidad se trata de una sola línea de código. Pero tienes que conseguir el billete de posición para ello. Aquí está el Asesor Experto de OnInit que abre la posición con 0.2 lotes y cierra la mitad de la posición en 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);
   }
 }
//+------------------------------------------------------------------+

O aquí está el código completo de la clase 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));
  }
Archivos adjuntos:
00.mq5  5 kb
Razón de la queja: