Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les 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);
      }   

Renvoie parfois l'erreur 4108 - mauvais ticket pour OrderClose. Est-il possible que OrderTicket() ne corresponde pas au ticket dans OrderSelect? La variable ticket peut être égale à zéro.

Il me faut beaucoup de temps pour reproduire l'erreur, il est plus facile de demander.
 
Dmitri Custurov:

Renvoie parfois l'erreur 4108 - mauvais ticket pour OrderClose. Est-il possible que OrderTicket() ne corresponde pas au ticket dans OrderSelect ? La variable ticket peut être égale à zéro.

Il me faut beaucoup de temps pour reproduire l'erreur, il est plus facile de demander.

Vous sélectionnez une commande par ticket. Êtes-vous sûr que la commande sélectionnée n'est pas déjà fermée ? Mais vous essayez de le refermer... Vérifiez l'heure de fermeture après avoir sélectionné avec succès le billet.

 
Artyom Trishkin:

Vous sélectionnez l'ordre sur le billet. Et vous êtes sûr que l'ordre sélectionné n'est pas déjà fermé ? Mais vous essayez de la refermer. Vérifiez l'heure de fermeture après une sélection réussie sur le billet.

Je vérifierai quand je reproduirai l'erreur. Tous les tickets sont stockés dans des variables globales. Lorsque la commande est clôturée, ils sont supprimés. Avant que le ticket OrderSelect() ne soit pris dans les variables globales. Si le ticket n'est pas dans les variables - cette variable sera 0, et donc la commande ne doit pas être sélectionnée et OrderSelect() retournera false. Mais en général, oui, cela vaut la peine de vérifier. Merci.

 
Dmitri Custurov:

Je vérifierai quand je reproduirai l'erreur. Tous les billets sont stockés dans des variables globales. Lorsque la commande est clôturée, ils sont supprimés. Avant que le ticket OrderSelect() ne soit pris dans les variables globales. Si le ticket n'est pas dans les variables - cette variable sera 0, et donc la commande ne doit pas être sélectionnée et OrderSelect() retournera false. Mais en général, oui, cela vaut la peine de vérifier. Merci.

Il est standard de vérifier le cours de clôture lorsqu'un ordre est sélectionné par ticket. Vous ne sauriez pas autrement si l'ordre est fermé et sélectionné dans la liste des ordres fermés, ou s'il est encore ouvert et sélectionné dans la liste des ordres au marché.

La façon la plus irréfléchie est de stocker les billets dans des variables globales. Ils doivent être tirés de l'environnement commercial - les informations actuelles sont là.

 
Artyom Trishkin:

Il est standard de vérifier le cours de clôture lorsqu'un ordre est sélectionné par ticket. Vous ne saurez d'aucune autre manière si l'ordre est fermé et s'il est sélectionné dans la liste des ordres fermés, ou s'il est encore ouvert et s'il est sélectionné dans la liste des ordres au marché.

C'est faire preuve de la plus grande myopie que de stocker les billets dans des variables globales. Ils doivent être tirés de l'environnement commercial - les informations actuelles sont là.

Si je sélectionne comme ceci : OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), est-ce que cela est censé résoudre partiellement le problème ? Je stocke les billets dans des variables globales pour d'autres raisons, eh bien, je l'ai utilisé dans ce cas aussi.

 
Dmitri Custurov:

Si je sélectionne comme ceci : OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES), est-ce que cela est censé résoudre partiellement le problème ? Je stocke les billets dans des variables globales pour d'autres raisons, et je les ai utilisées dans ce cas également.

Non, il ne le fera pas - le pool (MODE_TRADES) est ignoré lors de la sélection par ticket.

 
Dmitri Custurov:

Renvoie parfois l'erreur 4108 - mauvais ticket pour OrderClose. Est-il possible que la fonction OrderTicket() ne corresponde pas au ticket dans OrderSelect ? La variable ticket peut être égale à zéro.

Il me faut beaucoup de temps pour reproduire l'erreur, il est beaucoup plus facile de demander.

Il suffit généralement de vérifier la présence d'ordres au marché :

OrderCloseTime() == 0 //la commande est ouverte

OrderCloseTime() > 0 //l'ordre est fermé

pour les ordres limités, vous devez également vérifier le prix de clôture; s'il est égal à 0, l'ordre limité a été annulé.

 
Merci à tous pour vos réponses, j'ai compris ;))
 

Bonjour !

Partagez le code en utilisant la méthode PositionClosePartial, si vous le pouvez.

En théorie, je comprends comment cela fonctionne, mais j'aimerais voir un code fonctionnel.

Ou me conseiller où chercher.

Merci d'avance.

 
odyn:

Bonjour !

Partagez le code en utilisant la méthode PositionClosePartial, si vous le pouvez.

En théorie, je comprends comment cela fonctionne, mais j'aimerais voir un code fonctionnel.

Ou me conseiller où chercher.

Je vous en suis reconnaissant à l'avance.

En fait, il s'agit d'une seule ligne de code. Mais vous devez obtenir le ticket de position pour cela. Voici l'Expert Advisor de OnInit qui ouvre une position avec 0.2 lot et ferme la moitié de la position 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);
   }
 }
//+------------------------------------------------------------------+

Ou bien voici le code complet de la classe 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));
  }
Dossiers :
00.mq5  5 kb
Raison: