Zero Divide (Trouver le problème - mais pourquoi ?) - page 2

 
RaptorUK:

Si vous voulez passer des jours à résoudre ce simple problème, alors n'hésitez pas.... Je ne le ferais pas.

Si vous savez quand cela se produit au cours de votre back test, alors il est facile de le trouver... commencez le back test un jour avant la date à laquelle cela se produit... trouvez exactement, à la minute près, quand cela va se produire... pour toutes les divisions de votre code... oui, toutes, ajoutez un Print(() avant la ligne contenant la division qui imprime la valeur de la division. . oui, toutes, ajoutez un Print() avant la ligne contenant la division qui imprime le diviseur et une référence à la ligne de code en question . . .

Par exemple :

Quand votre code se termine avec l'erreur de division par zéro, vérifiez le fichier journal et dans les dernières impressions, vous trouverez l'impression montrant la ligne de code qui a produit l'erreur et quelle variable a été mise à zéro...

... apprenez à travailler plus intelligemment et à traquer vos problèmes de manière logique et efficace.


J'apprécie que vous m'aidiez et que vous m'indiquiez la bonne direction à suivre pour résoudre ce problème ! J'ai trouvé le problème (après avoir passé un long moment à coller des empreintes partout !)

Il provient en fait du fait que mon courtier (ILQ) utilise un flux notionnel et de l'aide d'un membre de ce forum sur mon fil de discussion à ce sujet. En résumé, voici le code ci-dessous - Avec ILQ, vous pouvez négocier jusqu'à 1 unité. Dans la fenêtre de transaction MT4, vous devez indiquer la taille précise de l'unité que vous souhaitez (par exemple, 0,01 || 874 unités).

Pouvez-vous m'aider à comprendre quelle partie de cette formule ne fonctionne pas à l'endroit où j'ai placé la flèche ? Les calculs semblent corrects d'après ce que je vois ?

//+------------------------------------------------------------------+
//| Order Enter Function                                             |
//+------------------------------------------------------------------+
void OrderEntry(int direction)
{
   //Padding for the stop and padding for the entry too. 
   double ATR_Pad = iATR(NULL,60,14,1)/2;
      if(ATR_Pad == 0.0)Print(" ATR_Pad = ", ATR_Pad); 
   double Buy_Pad = NormalizeDouble(ATR_Pad,Digits);
   double Sell_Pad = NormalizeDouble(ATR_Pad,Digits);
   
   //Get Highest Price in our lookback range and set buy price above it.
   int iTBT = iBarShift(NULL,60, triggerBarTime, true),
   iHH = iHighest(NULL,60, MODE_HIGH, iTBT + CandlesBeforeBiasObtained, 0);
   double Buy_Here = High[iHH] + Buy_Pad;
   double buyPrice= NormalizeDouble(Buy_Here,Digits);

   //Get Lowest Price in our lookback range and set sell price below it.
   int iTBT_1 = iBarShift(NULL, 60, triggerBarTime, true),
   iLL = iLowest(NULL, 60, MODE_LOW, iTBT_1 + CandlesBeforeBiasObtained, 0);
   double Sell_Here =Low[iLL] - Sell_Pad;
   double sellPrice = NormalizeDouble(Sell_Here,Digits);
   
   //Stop calculations.    
   double ATR = iATR(NULL,60,14,1);
   double MA = iMA(NULL,60,MA_Period,0,1,0,1);
   double BuyStopPriceMath = MA - ATR;
   double SellStopPriceMath = MA + ATR;
   double BuyStopPrice = NormalizeDouble(BuyStopPriceMath,Digits);
   double SellStopPrice = NormalizeDouble(SellStopPriceMath,Digits);

   //get our buystop price from below the ma and our takeprofit based on our r:r ratio.
   double pips_to_bsl = buyPrice-BuyStopPrice;
   double buy_tp_price=(pips_to_bsl*RewardRatio)+buyPrice;
   double buy_takeprofit_price= NormalizeDouble(buy_tp_price, Digits);

   //get our sellstop price from below the ma and our takeprofit based on our r:r ratio.
   double pips_to_ssl=SellStopPrice-sellPrice;
   double sell_tp_price=sellPrice-(pips_to_ssl*RewardRatio);
   double sell_takeprofit_price= NormalizeDouble(sell_tp_price, Digits);
   
   //Lot calculation - Facilitates Notional and Lots within MT4 - As well as find the tick value relative to the account denomination.   
   double risk_amount = AccountEquity( )*RiskPercent/100;
      if( risk_amount == 0.0 )Print(" risk_amount = ", risk_amount);
   double Lot_Step = MarketInfo(Symbol(), MODE_LOTSTEP);
   double ts = MarketInfo(Symbol(), MODE_TICKSIZE);
   double tv = MarketInfo(Symbol(), MODE_TICKVALUE);
   double minlot = MarketInfo(Symbol(), MODE_MINLOT);
         
   double loss_for_1_lot = pips_to_bsl/ ts * tv ; //<<<<<<<<<<<<<<<<<<<<<<<<<<< This is giving me a "0" randomly sometimes?
      if( loss_for_1_lot == 0.0 )Print(" loss_for_1_lot = ", loss_for_1_lot);
   //Alert(loss_for_1_lot);
   double LotSize_Buy = MathFloor( risk_amount / loss_for_1_lot/ Lot_Step) * Lot_Step ;
      if( LotSize_Buy == 0.0 )Print(" LotSize_Buy = ", LotSize_Buy);
   //Alert(LotSize_Buy);
      
   double loss_for_1_lot1 = pips_to_ssl/ ts * tv ;  //<<<<<<<<<<<<<<<<<<<<<<<<<<< This is giving me a "0" randomly sometimes?
      if( loss_for_1_lot1 == 0.0 )Print(" loss_for_1_lot1 = ", loss_for_1_lot1);
   //Alert(loss_for_1_lot1);
   double LotSize_Sell = MathFloor( risk_amount / loss_for_1_lot1/ Lot_Step) * Lot_Step ;
      if( LotSize_Sell == 0.0 )Print(" LotSize_Sell = ", LotSize_Sell);
   //Alert(LotSize_Sell);
 
DomGilberto:


J'apprécie que vous m'aidiez et m'indiquiez la bonne direction à suivre pour résoudre ce problème ! J'ai trouvé le problème (après avoir passé un long moment à coller des empreintes partout !)

Il provient en fait du fait que mon courtier (ILQ) utilise un flux notionnel et de l'aide d'un membre de ce forum sur mon fil de discussion à ce sujet. En résumé, voici le code ci-dessous - Avec ILQ, vous pouvez négocier jusqu'à 1 unité. Dans la fenêtre de transaction MT4, vous devez indiquer la taille précise de l'unité que vous souhaitez (par exemple, 0,01 || 874 unités).

Pouvez-vous m'aider à comprendre quelle partie de cette formule ne fonctionne pas à l'endroit où j'ai placé la flèche ? Les calculs semblent corrects d'après ce que je vois ?

OK, j'ai lu brièvement votre autre fil de discussion sur le calcul alternatif de la taille des lots, mais pas de manière assez détaillée, mais en termes généraux, voici ce que je pourrais faire pour résoudre ce problème....

Qu'est-ce qui cause le problème ? ts ? tv ? ou les deux ? si l'un ou l'autre est 0.0, alors le produit de ts et tv sera 0.0... mais si un seul est occasionnellement renvoyé comme 0.0, alors vous n'avez besoin de traiter le problème que sur l'un d'entre eux...


TickSize ne changera pas (pour autant que je sache) ... vous n'avez pas besoin de continuer à le lire, lisez-le dans init() mais vérifiez que vous n'obtenez pas une valeur de 0.0 en retour, ou continuez à le lire si vous le souhaitez mais n'utilisez que ce qui est retourné si ce n'est pas 0.0.

TickValue peut changer, mais il ne devrait jamais être à 0.0, donc si vous le lisez et qu'il est à 0.0, ne mettez pas à jour sa valeur... ou essayez à nouveau et mettez à jour.

Ce n'est pas sorcier...

 

Je ne comprends pas pourquoi vous devez continuer à poser des questions à ce sujet, le simple bon sens devrait vous dire de faire ce que Raptor vient de dire. Si cela s'avère que ts*tv n'est pas le problème, imprime toutes les autres variables qui sont utilisées comme diviseur.

 

@SDC - Je l'ai déjà fait lol ? J'ai déjà identifié d'où vient le problème, je disais simplement que la formule pour le dimensionnement des lots me semble bonne, et plutôt que de tourner autour du pot, j'ai posté le code pour voir si je n'ai pas manqué quelque chose ?

Vous remarquerez dans le code le "<<<<" indiquant ce qui imprime un "0" ou zéro diviseur....

RaptorUK - merci mon pote, j'apprécie que tu aies décomposé cela. Je pense que je sais comment résoudre le problème à partir de ce que tu dis - je vais jouer avec dans un peu de temps et faire un rapport pour confirmer que le problème est résolu :)

 
Ok, donc c'est "TickValue" qui renvoie un "0".

J'ai essayé d'utiliser "static double tv = 0 ;" et ensuite d'assigner la valeur tick dans "int init", puis de mettre à jour ce double statique à chaque nouvelle bougie H1 si "tv==0" mais cela ne produit toujours rien de plus que "0" ? La paire de devises en question est GBPJPY (tout ceci dans Strategy Tester).

Désolé si je suis lent... ?
 
DomGilberto:
Ok, donc c'est "TickValue" qui renvoie un "0".

J'ai essayé d'utiliser "static double tv = 0 ;" et ensuite d'assigner la valeur tick dans "int init", puis de mettre à jour ce double statique à chaque nouvelle bougie H1 si "tv==0" mais cela ne produit toujours rien de plus que "0" ? La paire de devises en question est GBPJPY (tout ceci dans Strategy Tester).

Désolé si je suis lent... ?
Pourquoi mettre à jour la valeur de tv si TICKVALUE renvoie une valeur incorrecte de 0,0 ? Vous ne devriez mettre à jour tv que si TICKVALUE renvoie une valeur non nulle...
 

Désolé, je voulais dire que j'ai essayé les deux méthodes. J'ai essayé de faire simplement "tv = MarketInfo(Symbol(), MODE_TICKVALUE) ;" dans la section "int init"... (et "static double tv = 0 ;")

En fait, la valeur du tick est toujours "0" ? (Je l'ai fait imprimer pour moi bien sûr !)

De même, lorsque je passe au backtest sur l'EURUSD, la valeur du tick me dit également "0", mais il parvient à exécuter avec succès l'ensemble du backtest sans erreur de division par zéro de 2001 à 2013 ?

MISE À JOUR : J'ai donc effectué un test sur un courtier normal sur les marchés en direct qui a une alimentation basée sur le lot, et la valeur de tic renvoie un chiffre > 0. Cependant, lorsque j'ai déposé ce même script sur le même courtier du marché en direct qui a une alimentation notionnelle, la valeur de tic renvoie comme "0" ? Avez-vous une idée de la façon dont je peux contourner cette erreur de taille de lot lorsque j'utilise l'option d'alimentation notionnelle (transaction d'une unité seulement) ?

 
DomGilberto:

Désolé, je voulais dire que j'ai essayé les deux méthodes. J'ai essayé de faire simplement "tv = MarketInfo(Symbol(), MODE_TICKVALUE) ;" dans la section "int init"... (et "static double tv = 0 ;")

En fait, la valeur du tick est toujours "0" ? (Je l'ai fait imprimer pour moi bien sûr !)

De même, lorsque je passe au backtest sur l'EURUSD, la valeur du tick me dit également "0", mais il parvient à exécuter avec succès l'ensemble du backtest sans erreur de division par zéro de 2001 à 2013 ?

D'après le code que vous avez montré... cela n'est pas possible, à moins que vous n'appeliez pas la fonction que vous avez montrée...

   double ts = MarketInfo(Symbol(), MODE_TICKSIZE);
   double tv = MarketInfo(Symbol(), MODE_TICKVALUE);
   double minlot = MarketInfo(Symbol(), MODE_MINLOT);
         
   double loss_for_1_lot = pips_to_bsl/ ts * tv ;

Si TICKVALUE est toujours 0.0 alors tv est 0.0 donc ts * tv = 0.0 donc vous aurez toujours une erreur de division par zéro...

Est-ce que votre terminal est connecté à votre Broker ? ou est-ce que vous travaillez avec un terminal déconnecté ?

 

J'espère que cette vidéo que j'ai réalisée (40 secondes environ) illustre ce dont je parle (car je ne suis pas sûr d'être clair ou non).

Vidéo : http://screencast.com/t/uMHY5DpM

Vous verrez que dans la première partie, lorsque je dépose le script sur le graphique en direct (compte réel), la valeur du tick et la taille du tick renvoient "0" sur ce "compte notionnel", que j'illustre dans la fenêtre des lots (unités).

La deuxième partie est avec le même courtier mais sur une alimentation basée sur les lots et cette fois-ci, il retourne une valeur de tick et une taille de tick. Encore une fois, j'illustre que vous tradez en utilisant des lots.....

En ce qui concerne le testeur de stratégie, je ne sais pas pourquoi il fonctionne et parfois ne fonctionne pas. Le compte a été connecté pendant que j'effectuais les back-tests également (sur un compte démo notionnel alimenté (unités)).

Ma prochaine question est la suivante : si c'est la réponse typique que j'obtiendrai du compte notionnel, pouvez-vous me suggérer comment corriger le calcul de la taille de ma position dans cette circonstance ? Il fonctionne parfaitement pour une alimentation basée sur les lots... J'espère que c'est un peu mieux expliqué ?

 
DomGilberto:
Ok, donc c'est "TickValue" qui renvoie un "0".

J'ai essayé d'utiliser "static double tv = 0 ;" et ensuite d'assigner la valeur tick dans "int init", et ensuite de mettre à jour ce double statique à chaque nouvelle bougie H1 si "tv==0" mais cela ne produit toujours rien de plus que "0" ? La paire de devises en question est GBPJPY (tout ceci dans Strategy Tester).

Désolé si je suis lent... ?


Comment imprimez-vous TickValue ?

Comme les chiffres de GBPJPY sont généralement 3, il est tout à fait possible que TickValue imprime zéro parce qu'il n'y a pas assez de décimales.

Pour être absolument certain, il peut être une idée d'étendre les décimales imprimées

DoubleToStr(MarketInfo(Symbol(),MODE_TICKVALUE),8)

Notez que

double loss_for_1_lot = pips_to_bsl/ ts * tv ; //<<<<<<<<<<<<<<<<<<<<<<<<<<< This is giving me a "0" randomly sometimes?

donnera également zéro si pips_to_bsl est zéro. Est-ce possible ?