Besoin d'aide avec l'erreur #130 "invalid stoploss". - page 2

 

La meilleure façon d'obtenir un stoploss correct est de penser correctement à l'écart. Le spread est la distance entre le Ask et le Bid. Ainsi, lorsque vous ajoutez un stoploss à un ordre d'achat en utilisant Bid - SL, le spread est automatiquement inclus et vous n'avez pas besoin de le coder, ce qui vous permet d'ignorer totalement le spread. Pour une transaction de vente, l'utilisation de Ask + SL a le même effet. Cependant, ATTENTION --- en période de faible volume de transactions, le spread s'élargit et vous pouvez vous retrouver avec un SL bien loin de l'endroit où vous l'attendez --- vous pouvez donc ajouter un code pour empêcher l'ajout du SL au-dessus d'une taille de spread définie.

Maintenant que la question de l'écart est réglée, la prochaine cause principale d'erreur 130 est que les prix ont changé alors que votre EA est toujours en cours d'exécution. Cela peut être dû à un EA qui prend beaucoup de temps à s'exécuter ou au fait que le serveur est très occupé à traiter les transactions, ce qui retarde l'exécution de votre EA. Le résultat est qu'un tick a provoqué le début de l'exécution de votre EA mais qu'un autre tick est arrivé avant la fin de l'exécution et que les prix sont maintenant invalides.

Dans tous les cas, vous devez rafraîchir les prix en utilisant RefreshRates : while (RefrshRates() == 1) Sleep(5) ; ------ ou ce que vous voulez comme temps d'attente.

 
BigAl:


Dans les deux cas, vous devez rafraîchir les prix en utilisant RefreshRates : while (RefrshRates() == 1) Sleep(5) ; ------ ou ce que vous voulez comme temps d'attente.

Cela n'est correct que si le code utilise des variables prédéfinies https://docs.mql4.com/predefined/variables. Si le code utilise MarketInfo pour l'offre et la demande, alors RefreshRates n'aura aucune influence...
 
qjol:
AFAIK RefreshRates() n'a rien à voir avec l'erreur 130

Point pris RaptorUK et je suis d'accord que l'utilisation de MODE_ASK etc. éliminerait la nécessité de RefreshRates() mais j'ai supposé que comme dans l'exemple de code de shinobi .....

J'envoie un ordre avec par exemple :

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green) ;

la variable prédéfinie ASK est utilisée et donc la valeur ask/bid ainsi que la valeur de l'écart peuvent avoir changé donnant l'erreur 130. Dans un tel cas, RefreshRates() pourrait être utilisé immédiatement avant l'envoi de l'ordre.

 
BigAl:

Point pris RaptorUK et je suis d'accord que l'utilisation de MODE_ASK etc. éliminerait la nécessité de RefreshRates() mais j'ai supposé que comme dans l'exemple de code de shinobi .....

J'envoie une commande avec par exemple

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green) ;

la variable prédéfinie ASK est utilisée et donc la valeur ask/bid ainsi que la valeur de l'écart peuvent avoir changé donnant l'erreur 130. Dans un tel cas, RefreshRates() pourrait être utilisé immédiatement avant l'envoi de l'ordre.

Merci à tous pour vos excellents conseils !
Je suis un peu occupé en ce moment, mais dès que j'en aurai l'occasion, j'essaierai toutes vos suggestions, puis j'écrirai un billet récapitulatif pour tous ceux qui pourraient tomber sur ce fil de discussion avec le même problème.

Merci, et prenez soin de vous !

shinobi
 
BigAl: J'envoie un ordre avec par exemple :

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green) ;

ne dit pas tout. Comment calculez-vous initial_stop - en utilisant Bid ?

Comment calculez-vous le SLIPPAGE - en tenant compte des courtiers à 4/5 chiffres ?

 
Salut les gars !

J'ai dû faire une pause pendant un certain temps (déménagement dans une nouvelle ville, nouveau travail).
Mais maintenant je voudrais reprendre ce fil de discussion, et enfin trouver une solution pour cette maudite erreur #130 stoploss.

Je vous suis reconnaissant pour tous vos conseils et j'ai essayé de les intégrer tous :

1 : Spread.
Pour éliminer l'écart comme cause possible de l'erreur, j'ai défini le stoploss comme suit :
Bid-stoploss (Long)
Ask+stoploss (Short)

2 : Changing Market Rates
Pour éliminer la cause possible du changement des taux du marché avant l'envoi de l'ordre,
j'ai modifié mon code et remplacé toutes les occurrences de Ask et Bid par
MarketInfo(Symbol(), MODE_ASK) et MarketInfo(Symbol(), MODE_BID)

3 : 4-5 Digits-Broker
Pour éliminer la cause possible du nombre invalide de chiffres, j'ai arrondi le stoploss selon le code de WHRoeders :
int     pips2points;    // slippage  3 pips    3=points    30=points
double  pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)

//init digit adjustment
if (Digits % 2 == 1) {      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262
    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
} else {
    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; 
}

OrderSend(Symbol(), OP_BUY, position_size, MarketInfo(Symbol(), MODE_ASK), SLIPPAGE, (MarketInfo(Symbol(), MODE_BID) - stoploss) * pips2dbl, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);
Comme mentionné précédemment, les variables SLIPPAGE et TAKEPROFIT dans mon cas sont toujours 0. Elles ne devraient donc pas poser de problème non plus.


J'ai donc intégré toutes les suggestions, mais l'erreur persiste. Pour autant que je puisse dire, elle se produit aussi souvent qu'avant, il doit donc y avoir une autre cause.
Voici un journal récent :

tickvalue : 12.50000000
pos size : 37.00000000
Ask/Bid 1262.00000000/1261.75000000
stoploss:12.59610000
position_size : 37
Spread 0.25000000

Error could not take long position. L'erreur est : #130 invalid stops

La ligne de code OrderSend ci-dessus a été utilisée avec les valeurs enregistrées pour essayer de prendre une position longue.
Avez-vous d'autres idées, quelle pourrait être la cause ?

Merci !
shinobi
 

Est-ce un courtier ECN ?

WHRoeder 2011.09.15 20:36

Sur les courtiers ECN, vous devez ouvrir et ensuite fixer des stops.

 
shinobi:
pour éliminer la cause possible du nombre invalide de chiffres, j'ai arrondi le stoploss selon le code de WHRoeders :
  1. Il n'y avait pas d'arrondi dans le code que j'ai posté.
  2. Sur les courtiers ECN, vous devez ouvrir et ensuite fixer des stops.
  3. Sur les métaux (où TICKSIZE != Point) le prix d'ouverture pour les ordres en attente doit être arrondi
    double TS=MarketInfo(pair, MODE_TICKSIZE);
    OOP = MathRound(OOP/TS)*TS;
    Je ne sais pas pour les stops.

  4. Arrêtez de nous dire quelles sont les valeurs et ce que vous pensez avoir fait. Affichez le code.
 

Faites simplement

extern double StopLoss = 50 ;

extern double TakeProfit = 50 ;

puis pour les achats :

double SL=Bid - StopLoss*Point;

double TP=Bid + TakeProfit*Point;

int Ticket=OrderSend(Symbol(),0,1,Ask,2,SL,TP,"",12345);

if( Ticket<0) print("error="GetLastError()) ;

pour les ventes :

double SL=Ask + StopLoss*Point;

double TP=Ask - TakeProfit*Point;

int Ticket=OrderSend(Symbol(),1,1,Bid,2,SL,TP,"",12345);

if( Ticket<0) print("error="GetLastError()) ;

puis envoyez le fichier journal si cela ne fonctionne pas.

 
Merci Raptor, WHRoeder et SDC pour vos réponses.

SDC :
J'ai essayé votre code comme ceci :
   int result_ticket = -1;
   double stoploss            = 50;
   double takeprofit          = 50;
   double SL = 0.0;
   double TP = 0.0;
   if(long) {   //take long position
      SL = MarketInfo(Symbol(), MODE_BID) - stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_BID) + takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 0, 1, MarketInfo(Symbol(), MODE_ASK), 2, SL, TP, "", 12345);
   } else {     //take short position
      SL = MarketInfo(Symbol(), MODE_ASK) + stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_ASK) - takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 1, 1, MarketInfo(Symbol(), MODE_BID), 2, SL, TP, "", 12345);
   }

   //check for errors
   if(result_ticket == -1) {
      Log("error="+GetLastError());
      return(-1);
   }
La seule différence est que j'ai remplacé Point, Ask et Bid par MarketInfo pour éviter le problème RefreshRates mentionné par Raptor et BigAI.
Le problème persiste avec ce simple exemple. J'obtiens toujours

#ESZ1,M5 : Position d'ouverture
#ESZ1,M5 : tickvalue : 12.50000000
#ESZ1,M5 : taille de la position : 1.00000000
#ESZ1,M5 : Demande/offre 1244.50000000/1244.25000000
#ESZ1,M5 : Ecart 0.25000000
#ESZ1,M5 : SL : 1244.00000000
#ESZ1,M5 : TP : 1245.00000000
#ESZ1,M5 : error=130

Raptor :
J'utilise actuellement UWC-Trader avec un compte de démonstration pour les tests.
Comme mentionné précédemment, je négocie des Futures. Par exemple, ESZ1 et FDXZ1.

WHRoeder :
Désolé, je n'arrondis pas non plus. Remplacez "arrondir" par "ajuster pour les courtiers à 4/5 chiffres". I.E. Je viens d'appliquer votre code.
J'ai également affiché l'OrderSend tel que je l'utilise dans ma réponse précédente. Et les valeurs de toutes les variables impliquées. Je ne sais pas quelle autre partie du code serait intéressante.
Comme le mini-exemple, suggéré par SDC, l'a montré, l'erreur peut être décomposée à ce simple code. Elle doit donc être plus fondamentale.

Je ne négocie pas de métaux, donc l'arrondi ne devrait pas être important.

Je vais essayer la prochaine fois :
d'ouvrir (sans stoploss) puis de modifier (en fixant le stoploss) plus tard.

Merci encore pour vos réflexions,

shinobi