(Résolu) PositionModify met à jour le PositionType

mcorgnet  

Bonjour à tous, 

Je crois (mais j'espère me tromper) avoir identifié une anomalie dans MQL5. 

Lorsqu'une position est ouverte (short), le PositionType = 1. 

J'applique ensuite la fonction suivante, sur la position ouverte : 

m_trade.PositionModify(_Symbol, sl, 0.0);

Voici ce que me renvoie le position type

Print("OrderType : ", m_trade.RequestType(), " SL : ", sl, " TSL : ", tsl, " Tick : ", Tick.last);
2023.09.14 11:25:02.995 2011.12.16 11:02:02   OrderType : 0 SL : 1.38065 TSL : 1.3839000000000001 Tick : 1.30331

Il est passé à 0, alors qu'à l'ouverture de la position il était à 1. 

Est-ce normal ? 

Merci d'avance de votre réponse et à votre disposition pour toute question ;)

J M  
mcorgnet:

Bonjour à tous, 

Je crois (mais j'espère me tromper) avoir identifié une anomalie dans MQL5. 

Lorsqu'une position est ouverte (short), le PositionType = 1. 

J'applique ensuite la fonction suivante, sur la position ouverte : 

Voici ce que me renvoie le position type

Il est passé à 0, alors qu'à l'ouverture de la position il était à 1. 

Est-ce normal ? 

Merci d'avance de votre réponse et à votre disposition pour toute question ;)

Je pense que le problème devrait clairement se trouver de ton côté. Car, pour ce qui est du type de position, 1 correspond exactement à Buy (ou Long), et 0, à Sell (ou Short). Donc, c'est vraiment à toi de revoir un peu de ton côté... Merci

mcorgnet  

Bonjour J M, et merci beaucoup de ta réponse. 


Je viens de faire une EA dédiée à ce test. Le but est de voir 3 messages dans le cadre d'une position courte. 

1. Type d'une position lors de l'ouverture

2. Type d'une position avant utilisation de la fonction PositionModify

3. Type d'une position après utilisation de la fonction PositionModify


Conclusion

Pour l'instant cela confirme ce que j'ai écrit précédemment. On voit bien que le troisème message renvoie "0" en type de position. Donc à priori, d'une manière ou l'autre, PositionModify modifie également le type de position.

D'autre part, autre anomalie rencontrée, PositionModify ne fonctionnera pas si TP == 0.0 et renverra une erreur (autre sujet à traiter :d)

Messages renvoyés

2023.09.14 14:55:05.379 2011.10.12 00:00:00   OUVERTURE DE POSITION ! Type : 1 Bid : 1.36391 SL : 1.4321055
2023.09.14 14:55:06.181 2011.10.12 00:00:01   LA POSITION VA ETRE MODIFIEE ! Type : 1 SL : 1.4321055 TSL : 1.41779 TickValue : 1.36392
2023.09.14 14:55:06.183 2011.10.12 00:00:01   LA POSITION A ETE MODIFIEE ! Type : 0 SL : 1.41779

Le code intégral de l'EA

//+------------------------------------------------------------------+
//|                                                 testmodifySL.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright ""
#property link      "https://www.mql5.com"
#property version   "1.00"

//--- ExpertTrade
#include <Expert\ExpertTrade.mqh>
#include <Trade\HistoryOrderInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Indicators\Trend.mqh>
#include <Expert\Money\MoneyFixedRisk.mqh>

//+------------------------------------------------------------------+
//| Tick & Rates                                                     |
//+------------------------------------------------------------------+
MqlTick              Tick;
MqlRates             rates[];
//+------------------------------------------------------------------+
//| RiskManagement                                                   |
//+------------------------------------------------------------------+
double               dbRisk = 3;
int                  openTrades = 1;
//+------------------------------------------------------------------+
//| Initialization functions                                         |
//+------------------------------------------------------------------+
CTrade               m_trade;
CSymbolInfo          m_symbol;
CPositionInfo        m_position;
CMoneyFixedRisk      m_money;
//+------------------------------------------------------------------+
//| Define timeframes for analyze                                  |
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES MiddleTF = PERIOD_D1;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Refresh Symbol rates
   m_symbol.Name(_Symbol);
   m_symbol.Refresh();
//--- Define moneySymbol & risk %
   m_money.Init(&m_symbol, MiddleTF, _Point);
   m_money.Percent(dbRisk);
   m_money.Magic(75891);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   ResetLastError();
//---  Symbol refresh values
   m_symbol.Refresh();
   m_symbol.RefreshRates();
// define tick
   SymbolInfoTick(_Symbol, Tick);
//--- Positions management
   if(PositionsTotal() > 0 && m_trade.RequestSymbol() == _Symbol)
     {
      //--- Update Stop loss
      // If LONG Position
      double sl = NormalizeDouble(m_trade.RequestSL(), m_symbol.Digits());
      double tsl = NormalizeDouble(sl * 0.99, m_symbol.Digits());
      
      Print("LA POSITION VA ETRE MODIFIEE ! Type : ", m_trade.RequestType(), " SL : ", m_trade.RequestSL(), " TSL : ", tsl, " TickValue : ", Tick.last);
      // If SHORT position
      if(
         m_trade.RequestType() == ORDER_TYPE_SELL
         )
        {
         m_trade.PositionModify(_Symbol, sl, Tick.last * 0.99);
         Print("LA POSITION A ETE MODIFIEE ! Type : ", m_trade.RequestType(), " SL : ", m_trade.RequestSL());
        }
     }

// Opening short position
   if(
      PositionsTotal() < openTrades
   )
     {
      double sl = Tick.last * 1.05;
      double lots = m_money.CheckOpenShort(m_symbol.Bid(), sl);
      m_trade.SetTypeFilling(ORDER_FILLING_IOC);
      m_trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, lots, m_symbol.Bid(), sl, 0.0, "sell");
      
      Print("OUVERTURE DE POSITION ! Type : ", m_trade.RequestType(), " Bid : " , m_symbol.Bid(), " SL : ", sl);
     }
// Print last error
   if(GetLastError() > 0)
     {
      Print("error : ", GetLastError());
     }
  }
mcorgnet  

J'en ai profité pour apporter un correctif. 

Ca semble fonctionner mais je pense que des personnes plus expérimentées devraient le relire / valider. 


Classe : CTrade

Fichier : Include\Trade\Trade.mqh


Correction : 

m_request.type    =(ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE);


Appliquée ici : 

//+------------------------------------------------------------------+
//| Modify specified opened position                                 |
//+------------------------------------------------------------------+
bool CTrade::PositionModify(const string symbol,const double sl,const double tp)
  {
//--- check stopped
   if(IsStopped(__FUNCTION__))
      return(false);
//--- check position existence
   if(!SelectPosition(symbol))
      return(false);
//--- clean
   ClearStructures();
//--- setting request
   m_request.action  =TRADE_ACTION_SLTP;
   m_request.type    =(ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE);
   m_request.symbol  =symbol;
   m_request.magic   =m_magic;
   m_request.sl      =sl;
   m_request.tp      =tp;
   m_request.position=PositionGetInteger(POSITION_TICKET);
//--- action and return the result
   return(OrderSend(m_request,m_result));
  }
//+------------------------------------------------------------------+
//| Modify specified opened position                                 |
//+------------------------------------------------------------------+
bool CTrade::PositionModify(const ulong ticket,const double sl,const double tp)
  {
//--- check stopped
   if(IsStopped(__FUNCTION__))
      return(false);
//--- check position existence
   if(!PositionSelectByTicket(ticket))
      return(false);
//--- clean
   ClearStructures();
//--- setting request
   m_request.action  =TRADE_ACTION_SLTP;
   m_request.type    = (ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE);
   m_request.position=ticket;
   m_request.symbol  =PositionGetString(POSITION_SYMBOL);
   m_request.magic   =m_magic;
   m_request.sl      =sl;
   m_request.tp      =tp;
//--- action and return the result
   return(OrderSend(m_request,m_result));
  }
J M  
mcorgnet #:

J'en ai profité pour apporter un correctif. 

Ca semble fonctionner mais je pense que des personnes plus expérimentées devraient le relire / valider. 


Classe : CTrade

Fichier : Include\Trade\Trade.mqh


Correction : 


Appliquée ici : 

Bon, comme tu l'as si bien dit, il faudrait peut-être que des personnes plus expérimentées analysent un peu ce code pour voir d'où est entrain de venir ce petit bémol là... Car personnellement, j'ai essayé de l'analyser, mais je n'arrive pas à repérer l'erreur dans ton code...

mcorgnet  
Tu as tenté de copier / coller mon EA pour reproduire ? (normalement ça devrait fonctionner direct)
mcorgnet  

Hello, pensez vous qu'il faut clôturer le sujet ? 

Fernando Carreiro  
mcorgnet # : Hello, pensez vous qu'il faut clôturer le sujet ? 

Sur ce forum, les sujets ne sont jamais fermés. Ils restent ouverts pour toujours, au cas où de futurs lecteurs souhaiteraient ajouter d'autres questions et commentaires.

mcorgnet  
Oui mais en l'état, faudrait vraiment être sûrs du bug et du contournement non ?
Alain Verleyen  
mcorgnet #:
Oui mais en l'état, faudrait vraiment être sûrs du bug et du contournement non ?

Il n'y a pas de bug MQL5. Vous confondez le type d'une position et le type d'un ordre, ainsi que le type d'une requête.

Vous obteniez 0 pour "la position a été modifiée" parce que l'appel à PositionModify() remet la structure MqlTradeRequest à 0.

Votre "correction" introduit un bug.

Raison: