Zero Divide (Trovato il problema - ma perché?) - pagina 2

 
RaptorUK:

Se volete passare giorni a risolvere questo semplice problema, allora sentitevi liberi di farlo... Io non lo farei.

Se sapete quando succede durante il vostro back test allora è facile da trovare . . . iniziate il back test un giorno prima della data in cui succede . . . scoprite esattamente, al minuto, quando succederà . . . per tutte le divisioni nel vostro codice . . . sì, tutte, aggiungete una Print() prima della linea che contiene la divisione che stampa il divisore e un riferimento alla linea di codice in questione . . .

Per esempio:

Quando il vostro codice termina con l'errore di divisione per zero controllate il file di log e nelle ultime stampe ci sarà la stampa che mostra la linea di codice che ha prodotto l'errore e quale variabile è stata impostata a zero . . .

. . . imparate a lavorare in modo più intelligente e a dare la caccia ai vostri problemi in modo logico ed efficiente.


Ti ringrazio per l'aiuto e per avermi indicato la giusta direzione su come gestire questo problema! Ho trovato il problema (dopo aver passato molto tempo a schiaffeggiare stampe ovunque!)

In realtà deriva dal fatto che il mio broker (ILQ) utilizza un feed nozionale e dall'aiuto di un membro di questo forum sul mio thread riguardante questo. In poche parole questo è il codice qui sotto - Con ILQ puoi scambiare fino a 1 unità. All'interno della finestra delle transazioni MT4 si dovrebbe mettere il preciso dimensionamento dell'unità che si desidera (cioè 0,01 || 874 unità).

Sei in grado di aiutarmi a capire quale parte di questa formula sta andando male dove ho messo la freccia? La matematica sembra buona da dove la sto guardando?

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


Ti ringrazio per l'aiuto e per avermi indicato la giusta direzione su come gestire la cosa! Ho trovato il problema (dopo aver passato molto tempo a schiaffeggiare stampe ovunque!)

In realtà deriva dal fatto che il mio broker (ILQ) utilizza un feed nozionale e dall'aiuto di un membro di questo forum sul mio thread riguardante questo. In poche parole questo è il codice qui sotto - Con ILQ puoi scambiare fino a 1 unità. All'interno della finestra delle transazioni MT4 si dovrebbe mettere il preciso dimensionamento dell'unità che si desidera (cioè 0,01 || 874 unità).

Sei in grado di aiutarmi a capire quale parte di questa formula sta andando male dove ho messo la freccia? La matematica sembra buona da dove la sto guardando?

OK, ho letto brevemente il tuo altro thread sul calcolo alternativo della dimensione del lotto, ma non abbastanza in dettaglio, ma in termini generali per affrontare questo problema questo è quello che potrei fare.

Cosa sta causando il problema? ts? tv? o entrambi? se entrambi sono 0.0 allora il prodotto di ts e tv sarà 0.0 . . . bt se solo uno viene occasionalmente restituito come 0.0 allora è necessario affrontare il problema solo con uno di loro . . .


TickSize non cambierà (per quanto ne so) . . . non c'è bisogno di continuare a leggerlo, leggilo in init() ma controlla che non ti venga restituito un valore di 0.0, o continua a leggerlo se vuoi ma usa solo ciò che viene restituito se non è 0.0

TickValue può cambiare, ma non dovrebbe mai essere 0,0, quindi se lo leggete ed è 0,0 non aggiornate il suo valore... o riprovate e poi aggiornate.

Non è scienza missilistica . . .

 

Non capisco perché devi continuare a chiedere di questo, il semplice buon senso dovrebbe dirti di fare quello che Raptor ha appena detto. Se si scopre che ts*tv non è il problema, stampa tutte le altre variabili che sono usate come divisore.

 

@SDC - L'ho già fatto lol? Ho già identificato da dove viene, tutto quello che stavo dicendo è che la formula per il dimensionamento dei lotti mi sembra buona, e piuttosto che battere intorno al cespuglio ho postato il codice per vedere se mi manca qualcosa?

Noterai nel codice il "<<<<" che indica cosa sta stampando uno "0" o zero divide....

@ RaptorUK - grazie amico, apprezzo la tua rottura. Penso di sapere come risolverlo da quello che stai dicendo - ci giocherò un po' e riferirò per confermare che il problema è risolto :)

 
Ok, quindi il suo "TickValue" sta restituendo uno "0".

Ho provato a usare "static double tv = 0;" e poi assegnare il valore di tick all'interno di "int init", e poi aggiornare quel doppio statico su ogni nuova candela H1 se "tv==0" ma ancora non produrrà nulla di più alto di "0"? La coppia di valute in questione è GBPJPY (tutto questo è all'interno di Strategy Tester)

Scusate se sono lento...?
 
DomGilberto:
Ok, quindi il suo "TickValue" sta restituendo uno "0".

Ho provato a usare "static double tv = 0;" e poi assegnare il valore di tick all'interno di "int init", e poi aggiornare quel doppio statico su ogni nuova candela H1 se "tv==0" ma ancora non produrrà nulla di più alto di "0"? La coppia di valute in questione è GBPJPY (tutto questo è all'interno di Strategy Tester)

Scusa se sono un po' lento...?
Perché dovresti aggiornare il valore di tv se TICKVALUE ha restituito un valore errato di 0.0? dovresti aggiornare tv solo se TICKVALUE restituisce un valore non nullo.
 

Scusa, volevo dire che ho praticamente provato in entrambi i modi. Quindi ho provato a fare solo "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" nella sezione "int init"... (e "static double tv = 0;")

In pratica il valore di tick è sempre "0"? (Lo faccio stampare per me, naturalmente!)

Allo stesso modo, quando passo al backtest su EURUSD il valore di tick mi dice anche "0", tuttavia riesce a eseguire con successo l'intero backtest senza errore di divisione dello zero dal 2001-2013?

AGGIORNAMENTO: Quindi ho eseguito un test su un broker normale sui mercati live che ha un feed basato sul lotto, e il valore di tick stava restituendo una cifra > 0. Tuttavia, quando ho lasciato questo stesso script sullo stesso broker dei mercati live che ha un feed nozionale, il valore di tick restituito come "0"? Qualche idea su come aggirare questo errore di dimensionamento dei lotti quando si usa l'opzione di alimentazione nozionale (commercio fino a 1 unità)?

 
DomGilberto:

Scusa, volevo dire che ho praticamente provato in entrambi i modi. Quindi ho provato a fare solo "tv = MarketInfo(Symbol(), MODE_TICKVALUE);" nella sezione "int init"... (e "static double tv = 0;")

In pratica il valore di tick è sempre "0"? (Lo faccio stampare per me, naturalmente!)

Allo stesso modo, quando passo al backtest su EURUSD anche il valore di tick mi dice "0", tuttavia riesce ad eseguire con successo l'intero backtest senza errore di divisione dello zero dal 2001-2013 ?

Dal codice che hai mostrato . . . non è possibile, a meno che tu non stia chiamando la funzione che hai mostrato . . .

   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 allora tv è 0.0 quindi ts * tv = 0.0 quindi avrai sempre un errore di divisione per zero . . .

Il tuo terminale è collegato al tuo Broker? O lo stai usando con il diisconnesso?

 

Spero che questo video che ho fatto (40 secondi circa) illustri ciò di cui sto parlando (dato che non sono sicuro di renderlo chiaro o meno).

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

Vedrete che nella prima parte, quando faccio cadere lo script sul grafico live (conto reale), il valore di tick e la dimensione di tick restituiscono "0" su quel "conto nozionale", che illustro nella finestra dei lotti (unità).

La seconda parte è con lo stesso broker ma su un feed basato sui lotti e questa volta restituisce un valore di tick e una dimensione di tick. Di nuovo, illustro che si fa trading usando lotti....

Quindi, per quanto riguarda il tester della strategia, non ho idea del perché abbia funzionato e a volte no. Il conto è stato collegato mentre eseguo i back-test (su un conto demo fittizio alimentato (unità)).

La mia prossima domanda sarebbe, se questa è la risposta tipica che otterrò dal conto alimentato nozionale, siete in grado di suggerirmi come correggere il mio calcolo di dimensionamento della posizione in questa circostanza? Funziona perfettamente per un'alimentazione basata sul lotto... Spero che questo spieghi un po' meglio?

 
DomGilberto:
Ok, quindi il suo "TickValue" sta restituendo uno "0".

Ho provato a usare "static double tv = 0;" e poi assegnare il valore di tick all'interno di "int init", e poi aggiornare quel doppio statico su ogni nuova candela H1 se "tv==0" ma ancora non produrrà nulla di più alto di "0"? La coppia di valute in questione è GBPJPY (tutto questo è all'interno di Strategy Tester)

Scusa se sono un po' lento...?


Come stai stampando TickValue?

Dato che le cifre di GBPJPY sono di solito 3, è abbastanza possibile che TickValue stia stampando zero perché non ci sono abbastanza cifre decimali.

Per essere assolutamente certi, potrebbe essere un'idea estendere i decimali stampati

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

Si noti che

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

risulterà anche zero se pips_to_bsl è zero. È possibile?

Motivazione: