Zero Divide (Encontrou a questão - mas por quê?) - página 2

 
RaptorUK:

Se você quiser passar dias ordenando esta simples questão, sinta-se à vontade . . . . Eu não o faria.

Se você sabe quando isso acontece durante seu teste de costas então é fácil de encontrar . . iniciar o teste de costas um dia antes da data em que ele acontece . . descobrir exatamente, ao minuto, quando ele vai acontecer . . para todas as divisões em seu código . . sim, todas elas, acrescente uma impressão () antes da linha contendo a divisão que imprime o divisor e uma referência à linha de código em questão . .

Por exemplo:

Quando seu código terminar com a divisão por erro zero, verifique o arquivo de log e nas últimas impressões será a impressão mostrando a linha de código que produziu o erro e qual variável foi definida como zero . .

. . aprenda a trabalhar de forma mais inteligente e a caçar seus problemas de forma lógica e eficiente.


Agradeço a sua ajuda e me indique a direção certa de como lidar com isso! Eu encontrei o problema (depois de passar um longo tempo batendo as impressões em todos os lugares!)

Na verdade, é decorrente do fato de que meu corretor (ILQ) usa uma alimentação nocional e a ajuda de um membro deste fórum no meu tópico a respeito disso. Em uma casca de noz, este é o código abaixo - Com o ILQ você pode negociar até 1 unidade. Dentro da janela de transação MT4 você colocaria o tamanho exato da unidade desejada (ou seja, 0,01 || 874 unidades).

Você é capaz de me ajudar a entender que parte desta fórmula está dando errado onde eu coloquei a seta? A matemática parece boa de onde estou olhando para ela?

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


Agradeço a sua ajuda e me indique a direção certa de como lidar com isso! Eu encontrei o problema (depois de passar um longo tempo batendo as impressões em todos os lugares!)

Na verdade, ele é decorrente do fato de que meu corretor (ILQ) usa uma alimentação nocional e a ajuda de um membro deste fórum no meu tópico a respeito disso. Em uma casca de noz, este é o código abaixo - Com o ILQ você pode negociar até 1 unidade. Dentro da janela de transação MT4 você colocaria o tamanho exato da unidade desejada (ou seja, 0,01 || 874 unidades).

Você é capaz de me ajudar a entender que parte desta fórmula está dando errado onde eu coloquei a seta? A matemática parece boa de onde estou olhando para ela?

OK, li brevemente seu outro tópico sobre o cálculo do tamanho do lote alternativo, mas não em detalhes suficientes, mas em termos gerais para abordar esta questão, isto é o que eu poderia fazer ...

O que está causando o problema ? ts ? tv ? ou ambos ? se um deles for 0.0 então o produto de ts e tv será 0.0 . . bt se apenas um estiver ocasionalmente sendo devolvido como 0.0 então você só precisa endereçar o problema com um deles . .


TickSize não vai mudar ( até onde eu sei ) . . você não precisa continuar lendo, leia no init() mas verifique se você não está recebendo um valor retornado de 0,0, ou continue lendo se você quiser mas só use o que é retornado se não for 0,0

TickValue pode mudar, mas nunca deve ser 0,0, então se você lê-lo e for 0,0 não atualize seu valor . . . ou tente novamente e depois atualize.

Não é ciência de foguetes . .

 

Eu não entendo porque você precisa continuar perguntando sobre isso, o simples bom senso deve lhe dizer para fazer o que o Raptor acabou de dizer. Se isso não for o problema, imprima todas as outras variáveis que são usadas como divisor.

 

@SDC - Eu já fiz isso rs? Eu já identifiquei de onde vem, tudo o que eu estava simplesmente dizendo é que a fórmula para o dimensionamento de lotes me parece boa, e em vez de andar com rodeios eu coloquei o código para ver se estou perdendo alguma coisa?

Você vai notar no código o "<<<<" indicando o que está imprimindo um "0" ou zero divide....

@ RaptorUK - obrigado amigo, agradeço a você por ter quebrado isso. Acho que sei como resolver a questão a partir do que você está dizendo - vou fazer uma brincadeira daqui a pouco e voltarei a informar para confirmar que a questão está resolvida :)

 
Ok, então seu "TickValue" que está retornando um "0".

Eu tentei usar "tv estática dupla = 0;" e então atribuir o valor do tick dentro de "int init", e então atualizar esse duplo estático em cada nova vela H1 se "tv==0", mas ainda assim não produzirá nada superior a "0"? O par de moedas em questão é GBPJPY (Tudo isso está dentro do Strategy Tester)

Desculpe se eu estou sendo lento...?
 
DomGilberto:
Ok, então seu "TickValue" que está retornando um "0".

Eu tentei usar "tv estática dupla = 0;" e então atribuir o valor do tick dentro de "int init", e então atualizar esse duplo estático em cada nova vela H1 se "tv==0", mas ainda assim não produzirá nada maior que "0"? O par de moedas em questão é GBPJPY (Tudo isso está dentro do Strategy Tester)

Desculpe se eu estou sendo lento...?
Por que você atualizaria o valor da tv se TICKVALUE retornou um valor incorreto de 0,0 ? você só deve atualizar a tv se TICKVALUE retornar um valor diferente de zero . .
 

Desculpe, eu queria dizer que basicamente tentei de ambas as maneiras. Portanto, tentei apenas fazer "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" dentro da seção "int init"... (e "tv estática dupla = 0;")

Basicamente, o valor do tick é sempre "0"? (tenho-o imprimindo para mim, é claro!)

Da mesma forma, quando eu viro para o backtest no EURUSD o valor do tick também está me dizendo "0", mas ele consegue executar com sucesso todo o backtest sem erro de divisão zero de 2001-2013?

ATUALIZAÇÃO: Então eu fiz um teste em um corretor normal nos mercados ao vivo que tem uma alimentação baseada em lote, e o valor do tick estava retornando um valor > 0. Entretanto, quando eu deixei cair este mesmo script no mesmo corretor do mercado ao vivo que tem uma alimentação nocional, o valor do tick retornou como "0"? Alguma idéia de como contornar este erro de dimensionamento de lote ao usar a opção de alimentação nocional (troca tão baixa quanto 1 unidade)?

 
DomGilberto:

Desculpe, eu queria dizer que basicamente tentei de ambas as maneiras. Portanto, tentei apenas fazer "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" dentro da seção "int init"... (e "tv estática dupla = 0;")

Basicamente, o valor do tick é sempre "0"? (tenho-o imprimindo para mim, é claro!)

Da mesma forma, quando eu viro para o backtest no EURUSD o valor do tick também está me dizendo "0", mas ele consegue executar com sucesso todo o backtest sem erro de divisão zero de 2001-2013 ?

Pelo código que você mostrou . . . isso não é possível, a menos que você não esteja chamando a função que você mostrou . .

   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 ;

se TICKVALUE é sempre 0,0 então tv é 0,0 então tv * tv = 0,0 então você sempre terá um erro de divisão por zero . .

Seu terminal está conectado ao seu Corretor ? ou você está executando com ele diisconectado ?

 

Espero que este vídeo que fiz (cerca de 40 segundos) ilustre o que estou falando (pois não tenho certeza se estou deixando claro ou não).

Vídeo: http://screencast.com/t/uMHY5DpM

Você verá que a primeira parte quando eu solto o script no gráfico ao vivo (conta real) que o valor e o tamanho do tick retornam "0" naquela "conta nocional", que eu ilustro na janela de lotes (unidades).

A segunda parte é com o mesmo corretor, mas em uma alimentação baseada no lote e desta vez ele retorna um valor e tamanho do tick. Mais uma vez, eu ilustro que você negocia usando lotes....

Portanto, com relação ao testador de estratégia, não tenho idéia do porquê ele tem funcionado e às vezes não funciona. A conta foi conectada enquanto eu também realizo os testes de retaguarda (em uma conta nocional de demonstração (unidades)).

Minha próxima pergunta seria: se esta for a resposta típica que receberei da conta nocional federal, você pode sugerir como corrijo meu cálculo de tamanho de posição nesta circunstância? Funciona perfeitamente para uma alimentação baseada em lote... Espero que isso o explique um pouco melhor?

 
DomGilberto:
Ok, então seu "TickValue" que está retornando um "0".

Eu tentei usar "tv estática dupla = 0;" e então atribuir o valor do tick dentro de "int init", e então atualizar esse duplo estático em cada nova vela H1 se "tv==0", mas ainda assim não produzirá nada maior que "0"? O par de moedas em questão é GBPJPY (Tudo isso está dentro do Strategy Tester)

Desculpe se eu estou sendo lento...?


Como você está imprimindo o TickValue?

Como os dígitos do GBPJPY são geralmente 3, é bem possível que o TickValue esteja imprimindo zero porque não há casas decimais suficientes.

Para ter certeza absoluta, pode ser uma idéia estender as casas decimais impressas

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

Note que

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

também resultará em zero se pips_to_bsl for zero. Isto é possível?