Zero Divide (Нашли проблему - но почему?) - страница 2

 
RaptorUK:

Если вы хотите потратить несколько дней на решение этого простого вопроса, то, конечно, не стесняйтесь.... Я бы не стал.

Если вы знаете, когда это произойдет во время обратного тестирования, то это легко найти ... начните обратное тестирование за день до даты, когда это произойдет ... узнайте точно, с точностью до минуты, когда это произойдет ... для всех делений в вашем коде ... ... да, для всех, добавьте Print() перед строкой, содержащей деление, которая печатает делитель и ссылку на соответствующую строку кода....

Например:

Когда ваш код завершится с ошибкой деления на ноль, проверьте файл журнала, и в последних нескольких отпечатках будет выведена строка кода, которая привела к ошибке, и какая переменная была установлена в ноль....

... учитесь работать умнее и искать проблемы логично и эффективно.


Спасибо, что помогли и направили меня в нужное русло! Я нашел проблему (после того, как потратил много времени, шлепая отпечатки повсюду!).

На самом деле это связано с тем, что мой брокер (ILQ) использует условный фид и помощь от члена этого форума в моей теме по этому поводу. В двух словах вот код ниже - С ILQ вы можете торговать до 1 единицы. В окне транзакций MT4 вы должны установить точный размер единицы, который вы хотите (т.е. 0.01 || 874 единицы).

Можете ли вы помочь мне понять, какая часть этой формулы идет не так, где я поставил стрелку? С моей точки зрения, математика выглядит правильно?

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


Спасибо, что помогли и указали мне правильное направление, как с этим справиться! Я нашел проблему (после того, как потратил много времени, шлепая отпечатки повсюду!).

На самом деле это связано с тем, что мой брокер (ILQ) использует условный фид и помощь от члена этого форума в моей теме по этому поводу. В двух словах вот код ниже - С ILQ вы можете торговать до 1 единицы. В окне транзакции MT4 вы должны установить точный размер единицы, который вы хотите (т.е. 0.01 || 874 единицы).

Можете ли вы помочь мне понять, какая часть этой формулы идет не так, где я поставил стрелку? С моей точки зрения, математика выглядит правильно?

Хорошо, я кратко прочитал вашу другую тему об альтернативном расчете размера лота, но не достаточно подробно, но в общих чертах для решения этой проблемы вот что я мог бы сделать...

Что вызывает проблему? ts? tv? или оба? если оба равны 0.0, тогда произведение ts и tv будет 0.0 ... bt если только один из них иногда возвращается как 0.0, тогда вам нужно решить проблему только с одним из них ....


TickSize не изменится (насколько я знаю) ... вам не нужно продолжать читать его, прочитайте его в init(), но проверьте, что вы не получаете возвращаемое значение 0.0, или продолжайте читать его, если хотите, но используйте только то, что возвращается, если это не 0.0.

TickValue может меняться, но оно никогда не должно быть 0.0, поэтому если вы прочитали его и оно равно 0.0, не обновляйте его значение ... или попробуйте еще раз, а затем обновите.

Это не ракетостроение...

 

Я не понимаю, почему вам нужно продолжать спрашивать об этом, простой здравый смысл должен подсказать вам сделать то, что только что сказал Raptor. Если окажется, что ts*tv не является проблемой, распечатайте все остальные переменные, которые используются в качестве делителя.

 

@SDC - Я уже сделал это, лол? Я уже определил, откуда он берется, я просто сказал, что формула для определения размера лота выглядит хорошо для меня, и вместо того, чтобы биться вокруг да около, я опубликовал код, чтобы посмотреть, не упускаю ли я чего-то?

Вы заметите в коде "<<<<", указывающий на то, что распечатывается "0" или нулевое деление.....

@ RaptorUK - спасибо, приятель, ценю, что вы разобрали это. Я думаю, что знаю, как это сделать, исходя из ваших слов - я поиграю с этим немного и сообщу, чтобы подтвердить, что проблема решена :)

 
Итак, его "TickValue" возвращает "0".

Я пробовал использовать "static double tv = 0;" и затем присваивать значение тика в "int init", а затем обновлять этот static double на каждой новой свече H1, если "tv==0", но он все равно не выдает ничего выше "0"? Рассматриваемая валютная пара - GBPJPY (все это в Strategy Tester).

Извините, если я медленно работаю...?
 
DomGilberto:
Итак, его "TickValue" возвращает "0".

Я пробовал использовать "static double tv = 0;" и затем присваивать значение тика в "int init", а затем обновлять этот static double на каждой новой свече H1, если "tv==0", но он все равно не выдает ничего выше "0"? Рассматриваемая валютная пара - GBPJPY (все это в Strategy Tester).

Извините, если я медленно говорю...?
Зачем вам обновлять значение tv, если TICKVALUE вернул неверное значение 0.0? Вы должны обновлять tv, только если TICKVALUE вернул ненулевое значение....
 

Извините, я хотел сказать, что в основном я пробовал оба способа. То есть я пытался просто сделать "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" в секции "int init"... (и "static double tv = 0;").

В принципе, значение тика всегда равно "0"? (У меня это печатается для меня, конечно!).

Аналогично, когда я перехожу к бэктесту на EURUSD, значение тика также говорит мне "0", однако ему удается успешно выполнить весь бэктест без ошибки нулевого деления с 2001-2013?

UPDATE: Итак, я провел тест на обычном брокере на живых рынках, у которого есть лот, и тиковое значение возвращало цифру > 0. Однако, когда я перекинул этот же скрипт на того же брокера на живом рынке, у которого есть условный фид, тиковое значение вернулось как "0"? Есть идеи, как мне обойти эту ошибку с размером лота при использовании условного фида (торговля до 1 единицы)?

 
DomGilberto:

Извините, я хотел сказать, что в основном я пробовал оба способа. То есть я пытался просто сделать "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" в секции "int init"... (и "static double tv = 0;").

В принципе, значение тика всегда равно "0"? (У меня это печатается для меня, конечно!).

Аналогично, когда я перехожу к бэктесту на EURUSD, значение тика также говорит мне "0", однако ему удается успешно выполнить весь бэктест без ошибки нулевого деления с 2001-2013 ?

Из кода, который вы показали ... это невозможно, если только вы не вызываете функцию, которую вы показали ....

   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 ;

Если TICKVALUE всегда 0.0, то tv = 0.0, поэтому ts * tv = 0.0, поэтому вы всегда будете получать ошибку деления на ноль ....

Ваш терминал подключен к Broker? Или вы работаете с отключенным терминалом?

 

Я надеюсь, что это видео, которое я сделал (40 секунд или около того), иллюстрирует то, о чем я говорю (так как я не уверен, что говорю ясно или нет).

Видео: http://screencast.com/t/uMHY5DpM

Вы увидите, что в первой части, когда я бросаю скрипт на живой график (реальный счет), значение тика и размер тика возвращают "0" на этом "условном счете", который я иллюстрирую в окне лотов (единиц).

Вторая часть - с тем же брокером, но на основе лота, и на этот раз он возвращает значение тика и размер тика. Опять же, я иллюстрирую, что вы торгуете, используя лоты.....

Что касается тестера стратегий, я понятия не имею, почему он работает, а иногда нет. Счет был подключен, пока я запускал обратные тесты (на демо условном счете (единицы)).

Мой следующий вопрос: если это типичный ответ, который я получаю от условного счета, можете ли вы предложить, как мне исправить расчет размера позиции в таких обстоятельствах? Он прекрасно работает для лотового фида... Надеюсь, это объясняет немного лучше?

 
DomGilberto:
Итак, его "TickValue" возвращает "0".

Я пробовал использовать "static double tv = 0;" и затем присваивать значение тика в "int init", а затем обновлять этот static double на каждой новой свече H1, если "tv==0", но он все равно не выдает ничего выше "0"? Рассматриваемая валютная пара - GBPJPY (все это в Strategy Tester).

Извините, если я медленно...?


Как вы печатаете TickValue?

Поскольку цифры в GBPJPY обычно равны 3, вполне возможно, что TickValue печатает ноль из-за недостаточного количества знаков после запятой.

Чтобы быть абсолютно уверенным, возможно, стоит увеличить количество выводимых десятичных знаков.

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

Обратите внимание, что

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

также выводит ноль, если pips_to_bsl равен нулю. Возможно ли это?