Zero Divide (Found the issue - but why?) - page 2

 
RaptorUK:

If you want to spend days sorting this simple issue then by all means feel free . . . . I wouldn't.

If you know when it happens during your back test then it's easy to find . . . start the back test a day before the date when it happens . . . find out exactly, to the minute, when it is going to happen . . . for all the divisions in your code . . . yes, all of them, add a Print() before the line containing the division which prints the divisor and a reference to the line of code in question . . .

For example:

When your code terminates with the divide by zero error check the log file and in the last few prints will be the print showing the line of code that produced the error and which variable was set to zero . . .

. . . learn to work smarter and hunt your issues down logically and efficiently.


Appreciate you helping and pointing me in the right direction of how to handle this! I've found the problem (after spending a long while slapping prints every where!)

It's actually stemming from the fact that my broker (ILQ) uses a notional feed and the help from a member of this forum on my thread regarding this. In a nut shell this is the code below - With ILQ you can trade as low as 1 unit. Within MT4 transaction window you would put the precise unit sizing you want (i.e. 0.01 || 874 units).

Are you able to help me understand what part of this formula is going wrong where I have put the arrow? The math looks good from where I am looking at it?

//+------------------------------------------------------------------+
//| 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:


Appreciate you helping and pointing me in the right direction of how to handle this! I've found the problem (after spending a long while slapping prints every where!)

It's actually stemming from the fact that my broker (ILQ) uses a notional feed and the help from a member of this forum on my thread regarding this. In a nut shell this is the code below - With ILQ you can trade as low as 1 unit. Within MT4 transaction window you would put the precise unit sizing you want (i.e. 0.01 || 874 units).

Are you able to help me understand what part of this formula is going wrong where I have put the arrow? The math looks good from where I am looking at it?

OK, I've briefly read your other thread about the alternative lot size calculation but not in enough detail, but in general terms to address this issue this is what I might do . . .

What is causing the issue ? ts ? tv ? or both ? if either are 0.0 then the product of ts and tv will be 0.0 . . . bt if only one is occasionally being returned as 0.0 then you only need to address the issue with one of them . . .


TickSize won't change ( as far a I am aware ) . . . you don't need to keep reading it, read it in init() but check that you are not getting a returned value of 0.0, or keep reading it if you like but only use what is returned if it isn't 0.0

TickValue can change, but it should never be 0.0, so if you read it and it's 0.0 don't update it's value . . . or try again and then update.

It's not rocket science . . .

 

I dont understand why you need to keep asking about this, simple common sense should tell you to do what Raptor just said. If that turns out ts*tv is not the problem print out all other variables that are used as a divider.

 

@SDC - I have done that already lol? I've already identified where it is coming from, all I was simply saying is that the formula for lot sizing looks good to me, and rather than beat round the bush I posted the code to see if I am missing something?

You will notice in the code the "<<<<" indicating what is printing out a "0" or zero divide....

@ RaptorUK - thanks mate, appreciate you breaking that down. I think I know how to work it out from what you're saying - I'll have a play with it in a bit and report back to confirm the issue is resolved :)

 
Ok so its "TickValue" that is returning a "0".

I have tried using "static double tv = 0;" and then assigning the tick value within "int init", and then update that static double on every new H1 candle if "tv==0" but it still will not produce anything higher than "0"? The currency pair in question is GBPJPY (This is all within Strategy Tester)

Sorry if I am being slow...?
 
DomGilberto:
Ok so its "TickValue" that is returning a "0".

I have tried using "static double tv = 0;" and then assigning the tick value within "int init", and then update that static double on every new H1 candle if "tv==0" but it still will not produce anything higher than "0"? The currency pair in question is GBPJPY (This is all within Strategy Tester)

Sorry if I am being slow...?
Why would you update the value of tv if TICKVALUE has returned an incorrect value of 0.0 ? you should only update tv if TICKVALUE returns a non-zero value . . .
 

Sorry, I meant to say that I have basically tried both ways. So I have tried to just do "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" within "int init" section... (and "static double tv = 0;")

Basically tick value is always "0"? (I have it printing for me of course!)

Likewise, when I flip over to backtest on EURUSD the tick value is also telling me "0", however it manages to successfully run the entire back-test without zero divide error from 2001-2013?

UPDATE: So I ran a test on a normal broker on the live markets that has a lot based feed, and the tick value was returning a figure > 0. However, when I dropped this same script onto the same live market broker that has a notional feed, the tick value returned as "0"? Any idea's how I get around this lot sizing error when using the notional feed option (trade as low as 1 unit)?

 
DomGilberto:

Sorry, I meant to say that I have basically tried both ways. So I have tried to just do "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" within "int init" section... (and "static double tv = 0;")

Basically tick value is always "0"? (I have it printing for me of course!)

Likewise, when I flip over to backtest on EURUSD the tick value is also telling me "0", however it manages to successfully run the entire back-test without zero divide error from 2001-2013?

From the code you have shown . . . that is not possible, unless you aren't calling the function you have shown . . .

   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 ;

if TICKVALUE is always 0.0 then tv is 0.0 so ts * tv = 0.0 so you will always get a divide by zero error . . .

Is your terminal connected to your Broker ? or are you running with it diisconnected ?

 

I'm hoping this video I've made (40 seconds or so) illustrates what I am talking about ( as I am not sure if I am making it clear or not ).

Video: http://screencast.com/t/uMHY5DpM

You will see that the first part when I drop the script onto the live chart (real account) that the tick value and tick size return "0" on that "notional account", which I illustrate in the lots window (units).

The second part is with the same broker but on a lot based feed and this time it returns a tick value and tick size. Again, I illustrate that you trade using lots....

So with regards to the strategy tester, I have no idea why it has been working and sometimes it doesn't. The account has been connected whilst I run the back-tests too (on a demo notional fed account (units)).

My next question would be, if this is the typical response I will get from the notional fed account, are you able to suggest how I correct my position sizing calculation in this circumstance? It works perfectly for a lot based feed... Hope that explains it a little better?

 
DomGilberto:
Ok so its "TickValue" that is returning a "0".

I have tried using "static double tv = 0;" and then assigning the tick value within "int init", and then update that static double on every new H1 candle if "tv==0" but it still will not produce anything higher than "0"? The currency pair in question is GBPJPY (This is all within Strategy Tester)

Sorry if I am being slow...?


How are you printing TickValue?

As Digits from GBPJPY are usually 3, it's quite possible that TickValue is printing zero because there are not enough decimal places.

To be absolutely certain, it may be an idea to extend the decimals printed

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

Note that

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

will also result in zero if pips_to_bsl is zero. Is this possible?