Indicatore ZigZag – Prova codice

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #205922 quote
    effegi
    Participant
    Senior

    Salve a tutti. Non avendo trovato nel sito alcun codice relativo allo zigzag classico, pubblico questa versione scritta da me con l’ausilio degli array. L’ho confrontato con l’indicatore delle piattaforma e i risultati sono pressocchè identici sia nella modalità pips che in percentuale.

    Con la variabile “Tipo” si può commutare il funzionamento fra “Punti” e “Percentuale” (Nota: nel caso di ZZ in %, ho usato come base di calcolo il Day Close del giorno precedente per dare stabilità al riferimento; usando il close con valori % molto bassi, a volte il ricalcolo da origine ad artefatti grafici)
    Con la variabile “Segmenti” si decide quante coppie di segmenti up/down visualizzare sul grafico.

    //16/12/2022 - T.F. - Codice ZigZag con Array
    //Sharing ProRealCode
    
    DEFPARAM DRAWONLASTBARONLY=TRUE
    //Variabili:
    //Punti=20          //Pips
    //Percentuale=0.25  //%
    //Tipo=0            //0=pips; 1=perc
    //Segmenti=5        //n. segmenti up/dw da visualizzare
    //Grafica=0         //debug only
    
    PI=max(0,(Segmenti-1)) //punti indietro da memorizzare
    VarY=CustomClose //close,tpicalprice, etc
    
    //inizializzo primo punto come TOP
    once LastPoint = 1
    once $TX[0]    = barindex
    once $TY[0]    = VarY
    
    //Tipo ZZ in Punti o Percentuale
    If Tipo=0 then //ZZ in punti
    DeltaY=max(2,Punti*pipsize)
    elsif tipo=1 then //ZZ in %
    DeltaY=max(0.05,Percentuale/100*Dclose(1)) //usato Dclose come rif. per stabilità del valore
    endif
    
    //ZZ in fase 1
    if LastPoint=1 then //ultimo punto era un massimo
    if VarY>$TY[0] then // aggiorno il punto di max e rimango in LastPoint=1
    $TY[0]=VarY
    $TX[0]=barindex
    elsif VarY<($TY[0]-DeltaY) then //primo punto definitivo low
    for i=PI downto 0 do //shift memoria punti precedenti
    $LX[i+1]=$LX[i]
    $LY[i+1]=$LY[i]
    next
    $LY[0]=VarY
    $LX[0]=barindex
    LastPoint=-1
    endif
    endif
    
    //ZZ in fase -1
    if LastPoint=-1 then //ultimo punto era un minimo
    if VarY<$LY[0] then // aggiorno il punto di min e rimango in LastPoint=-1
    $LY[0]=VarY
    $LX[0]=barindex
    elsif VarY>($LY[0]+DeltaY) then //primo punto definitivo top
    for i=PI downto 0 do  //shift memoria punti precedenti
    $TX[i+1]=$TX[i]
    $TY[i+1]=$TY[i]
    next
    $TY[0]=VarY
    $TX[0]=barindex
    LastPoint=1
    endif
    endif
    //---GRAFICA---
    If LastPoint=1 then
    drawsegment (barindex,VarY,$TX[0],$TY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progress
    
    for i=0 to PI do //segmenti definitivi
    drawsegment ($TX[i],$TY[i],$LX[i],$LY[i]) style (line,2) COLOURED (0,0,200)
    drawsegment ($LX[i],$LY[i],$TX[i+1],$TY[i+1]) style (line,2) COLOURED (0,0,200)
    next
    
    endif
    If LastPoint=-1 then
    drawsegment (barindex,VarY,$LX[0],$LY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progress
    
    for i=0 to PI do //segmenti definitivi
    drawsegment ($LX[i],$LY[i],$TX[i],$TY[i]) style (line,2) COLOURED (0,0,200)
    drawsegment ($TX[i],$TY[i],$LX[i+1],$LY[i+1]) style (line,2) COLOURED (0,0,200)
    next
    
    endif
    if grafica>=1 then
    drawtext ("#LastPoint#",barindex, HIGH+20)
    endif
    
    //TABELLA PER VISUALIZZARE CONTENUTO ARRAY - SOLO PER DEBUG
    if grafica>=2 then
    for tt=0 to lastset($TX) do //indicare Array da scansionare
    KToffsetX = -50 //Offset inizio tabella sull'asse X rispetto all'ultimo LOW
    KToffsetY = 80*pipsize //Offset inizio tabella sull'asse Y rispetto all'ultimo LOW
    KTcol     = 5 //passo fra le colonne
    KTrow     = 5*pipsize //passo fra le righe
    
    IA        = tt      //indice dell'Array
    V1A       = $TX[tt] //variabile 1 in tabella
    V2A       = $TY[tt] //variabile 2 in tabella
    V3A       = $LX[tt] //variabile 3 in tabella
    V4A       = $LY[tt] //variabile 4 in tabella
    
    drawtext("#IA#" ,barindex+KToffsetX+KTcol*1,low-KToffsetY-KTrow*tt)
    drawtext("#V1A#",barindex+KToffsetX+KTcol*2,low-KToffsetY-KTrow*tt)
    drawtext("#V2A#",barindex+KToffsetX+KTcol*3,low-KToffsetY-KTrow*tt)
    drawtext("#V3A#",barindex+KToffsetX+KTcol*4,low-KToffsetY-KTrow*tt)
    drawtext("#V4A#",barindex+KToffsetX+KTcol*5,low-KToffsetY-KTrow*tt)
    
    next
    endif
    
    return
    
    ZZ-1.jpg ZZ-1.jpg ZZ-2.jpg ZZ-2.jpg TF-ZigZagProva_PRC.itf
    #205928 quote
    effegi
    Participant
    Senior

    Mi sono accorto di un errore quando utilizzato con le valute.

    correggere le righe 22 e 24 con:

    DeltaY=max(2*pipsize,Punti*pipsize)

    DeltaY=max(0.001,Percentuale/100*Dclose(1)*pipsize)

    Ps: non è possibile correggere i post?

    #205963 quote
    robertogozzi
    Moderator
    Master

    Grazie per averlo condiviso, sicuramente sarà di aiuto a molti trader.

    Puoi ripostare il codice corretto, se vuoi, altrimenti ognuno farà la modifica da solo.

    #205967 quote
    luxrun
    Participant
    Master

    Una domanda: usando gli array nel codice dello zigzag si supera il fenomeno del repaint o no? Io ricordo che lo zigzag viene assimilato al dpo per questo problema del repaint. Grazie e complimenti per il bel lavoro!

    #205977 quote
    effegi
    Participant
    Senior

    Come nello ZigZag della piattaforma, l’ultimo punto Top o Low valido (che ha quindi superato il DeltaY in pips o %) rimane “in progress”, nel senso che potrebbe venire aggiornato dalla candela in corso se chiude nella medesima direzione. Tutti i punti precedenti rimangono fissi e confermati.

    Per es, se l’ultimo punto valido era un Top a 11300 punti, e ZZ settato a 50pips, se il prezzo continua a salire, ad ogni chiusura di candela l’ultimo Top verrà aggiornato e rimarrà in progress.

    Se invece da 11300 il prezzo inizia a scendere, fino a 11251 (DeltaY non superato), viene tracciato un segmento tratteggiato e  l’ultimo punto valido sarà sempre il Top a 11300. Se si arriva a 11250, viene memorizzato un nuovo punto Low (che rimane in progress in quanto il prezzo potrebbe scendere ulteriormente), mentre il Top precedente diventa ora definitivo.

    Spero di essermi riuscito e spiegare 🙂

    No l’ho testato moltissimo, ma mi sembra che funzioni correttamente in entrambe le modalità.

    Ps. l’uso degli array è solo per semplificazione del codice quando si cambiano il n. dei segmenti da visualizzare e anche per poter utilizzare il comando DRAWONLASTBARONLY=TRUE, che consente di plottare l’ultimo segmento tratteggiato in fase di aggiornamento, come fa l’indicatore della piattaforma

    robertogozzi and luxrun thanked this post
    #206100 quote
    effegi
    Participant
    Senior

    Buon pomeriggio.

    Purtroppo mi sono accorto che l’indicatore realizzato con gli array, così come compilato, dà dei problemi nella fase di commutazione da lastpoint 1/-1 durante la candela in corso di aggiornamento. Ho provato a capirne il motivo per una giornata intera, ma non sono riuscito a venir a capo di questa problematica che fa riempire gli array di valori sballati durante tutta la candela in progress.

    Al che ho fatto una marcia indietro, e ho rifatto tutto usando variabili fisse e non parametriche, ed ora funziona tutto perfettamente anche se il n. di segmenti visualizzati ora è fisso e modificabile solo nel codice (comunque sufficienti per l’utilizzo con una strategia 1-2-3)

    Peccato, ma non ho proprio idea su come risolvere il problema di cui sopra.

    Ps: Roberto, come si può fare il modo che un codice venga eseguito solo alla chiusura della candela (e non in modo continuo “live”)? Ho provato ad usare il comando “timeframe(<valore del timeframe>, udateonclose)” ma apperentemente non ha effetto sul ricalcolo

    //20/12/2022 - T.F. - V1: Codice ZigZag Versione v1: eliminati gli array e gestito con variabili fisse
    //Sharing on ProRealCode
    
    DEFPARAM DRAWONLASTBARONLY=TRUE
    //Variabili:
    //Punti=20          //Pips
    //Percentuale=0.25  //%
    //Tipo=0            //0=pips; 1=perc
    
    VarY=CustomClose //close,tpicalprice, etc
    
    //inizializzo primo punto come TOP
    once LastPoint = 1
    once TX0    = barindex
    once TY0    = VarY
    
    //Tipo ZZ in Punti o Percentuale
    If Tipo=0 then //ZZ in punti
    DeltaY=Punti*pipsize
    elsif tipo=1 then //ZZ in %
    DeltaY=Percentuale/100*Dclose(1)//usato Dclose come rif. per stabilità del valore
    endif
    
    //ZZ in fase 1
    if LastPoint=1 then //ultimo punto era un massimo
    if VarY>=TY0 then // aggiorno il punto di max e rimango in LastPoint=1
    TY0=VarY
    TX0=barindex
    endif
    if VarY<=TY0-DeltaY then //primo punto definitivo low
    rem for i=PI downto 0 do //shift memoria punti precedenti
    LX4=LX3
    LY4=LY3
    LX3=LX2
    LY3=LY2
    LX2=LX1
    LY2=LY1
    LX1=LX0
    LY1=LY0
    
    LY0=VarY //primo punto definitivo top
    LX0=barindex
    LastPoint=-1
    endif
    endif
    
    //ZZ in fase -1
    if LastPoint=-1 then //ultimo punto era un minimo
    if VarY<=LY0 then // aggiorno il punto di min e rimango in LastPoint=-1
    LY0=VarY
    LX0=barindex
    endif
    if VarY>=LY0+DeltaY then //primo punto definitivo top
    TX4=TX3
    TY4=TY3
    TX3=TX2
    TY3=TY2
    TX2=TX1
    TY2=TY1
    TX1=TX0
    TY1=TY0
    
    TY0=VarY //primo punto definitivo top
    TX0=barindex
    LastPoint=1
    endif
    endif
    
    
    //---GRAFICA---
    If lastpoint=1 then
    drawsegment (barindex,close,TX0,TY0) style (dottedline,2) COLOURED (0,0,200) //segmento in progress
    drawsegment (TX0,TY0,LX0,LY0) style (line,2) COLOURED (0,0,200) //segmenti definitivi
    drawsegment (LX0,LY0,TX1,TY1) style (line,2) COLOURED (0,0,200)
    drawsegment (TX1,TY1,LX1,LY1) style (line,2) COLOURED (0,0,200)
    drawsegment (LX1,LY1,TX2,TY2) style (line,2) COLOURED (0,0,200)
    drawsegment (TX2,TY2,LX2,LY2) style (line,2) COLOURED (0,0,200)
    drawsegment (LX2,LY2,TX3,TY3) style (line,2) COLOURED (0,0,200)
    drawsegment (TX3,TY3,LX3,LY3) style (line,2) COLOURED (0,0,200)
    drawsegment (LX3,LY3,TX4,TY4) style (line,2) COLOURED (0,0,200)
    drawsegment (TX4,TY4,LX4,LY4) style (line,2) COLOURED (0,0,200)
    endif
    If lastpoint=-1 then
    drawsegment (barindex,close,LX0,LY0) style (dottedline,2) COLOURED (0,200,0) //segmento in progress
    drawsegment (LX0,LY0,TX0,TY0) style (line,2) COLOURED (0,0,200) //segmenti definitivi
    drawsegment (TX0,TY0,LX1,LY1) style (line,2) COLOURED (0,0,200)
    drawsegment (LX1,LY1,TX1,TY1) style (line,2) COLOURED (0,0,200)
    drawsegment (TX1,TY1,LX2,LY2) style (line,2) COLOURED (0,0,200)
    drawsegment (LX2,LY2,TX2,TY2) style (line,2) COLOURED (0,0,200)
    drawsegment (TX2,TY2,LX3,LY3) style (line,2) COLOURED (0,0,200)
    drawsegment (LX3,LY3,TX3,TY3) style (line,2) COLOURED (0,0,200)
    drawsegment (TX3,TY3,LX4,LY4) style (line,2) COLOURED (0,0,200)
    drawsegment (LX4,LY4,TX4,TY4) style (line,2) COLOURED (0,0,200)
    endif
    
    return
    
    #206474 quote
    robertogozzi
    Moderator
    Master

    Il problema è che gli ARRAY non sono storicizzati come le normali variabili, ad esempio MiaVariabile[0] è il valore corrente di una variabile, MiaVariabile[1] è il valore che quella variabile aveva nella barra precedente.

    $MioElemento[0], in quanto elemento di un ARRAY, non viene storicizzato e non si può usare $MioElemento[0][1] per fare riferimento al suo valore precedente. Siccome un ARRAY può contenere un numero illimitato di elementi (solo la memoria disponibile è il suo limite fisico), dopo qualche migliaio di barre occorrerebbero centinaia di migliaia, se non milioni, di slot di memoria (ciascuno di vari bytes, forse 8, non so di che tipo numerico siano, penso FLOAT), quindi assolutamente IMPOSSIBLE da fare, per cui ogni elemento mantiene il valore corrente e non viene mai resettato al valore iniziale che ha avuto alla chiusura della barra precedente, ed assume un nuovo valore ad ogni tick.

    Ho provato ad usare due specifici elementi di una ARRAY che, combinati con la verifica dell’orario (che sia diverso dal precedente), sembrano funzionare. Provalo e fammi sapere:

    //16/12/2022 - T.F. - Codice ZigZag con Array
    //Sharing ProRealCode
    
    DEFPARAM DRAWONLASTBARONLY=TRUE
    //Variabili:
    Punti=20          //Pips
    Percentuale=0.25  //%
    Tipo=0            //0=pips; 1=perc
    Segmenti=5        //n. segmenti up/dw da visualizzare
    Grafica=0         //debug only
    
    PI=max(0,(Segmenti-1)) //punti indietro da memorizzare
    
    ONCE $myTime[0] = 0
    ONCE $myTime[1] = -1
    
    $myTime[0] = Time
    IF Time <> Time[1] AND $myTime[0] <> $myTime[1] THEN
    $myTime[0] = Time
    ENDIF
    
    IF $myTime[1] <> $myTime[0] THEN
    VarY=CustomClose //close,tpicalprice, etc
    
    //inizializzo primo punto come TOP
    once LastPoint = 1
    once $TX[0]    = barindex
    once $TY[0]    = VarY
    
    //Tipo ZZ in Punti o Percentuale
    If Tipo=0 then //ZZ in punti
    DeltaY=max(2,Punti*pipsize)
    elsif tipo=1 then //ZZ in %
    DeltaY=max(0.05,Percentuale/100*Dclose(1)) //usato Dclose come rif. per stabilità del valore
    endif
    
    //ZZ in fase 1
    if LastPoint=1 then //ultimo punto era un massimo
    if VarY>$TY[0] then // aggiorno il punto di max e rimango in LastPoint=1
    $TY[0]=VarY
    $TX[0]=barindex
    elsif VarY<($TY[0]-DeltaY) then //primo punto definitivo low
    for i=PI downto 0 do //shift memoria punti precedenti
    $LX[i+1]=$LX[i]
    $LY[i+1]=$LY[i]
    next
    $LY[0]=VarY
    $LX[0]=barindex
    LastPoint=-1
    endif
    endif
    
    //ZZ in fase -1
    if LastPoint=-1 then //ultimo punto era un minimo
    if VarY<$LY[0] then // aggiorno il punto di min e rimango in LastPoint=-1
    $LY[0]=VarY
    $LX[0]=barindex
    elsif VarY>($LY[0]+DeltaY) then //primo punto definitivo top
    for i=PI downto 0 do  //shift memoria punti precedenti
    $TX[i+1]=$TX[i]
    $TY[i+1]=$TY[i]
    next
    $TY[0]=VarY
    $TX[0]=barindex
    LastPoint=1
    endif
    endif
    endif
    $myTime[1] = $myTime[0]
    //---GRAFICA---
    If LastPoint=1 then
    drawsegment (barindex,VarY,$TX[0],$TY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progress
    
    for i=0 to PI do //segmenti definitivi
    drawsegment ($TX[i],$TY[i],$LX[i],$LY[i]) style (line,2) COLOURED (0,0,200)
    drawsegment ($LX[i],$LY[i],$TX[i+1],$TY[i+1]) style (line,2) COLOURED (0,0,200)
    next
    
    endif
    If LastPoint=-1 then
    drawsegment (barindex,VarY,$LX[0],$LY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progress
    
    for i=0 to PI do //segmenti definitivi
    drawsegment ($LX[i],$LY[i],$TX[i],$TY[i]) style (line,2) COLOURED (0,0,200)
    drawsegment ($TX[i],$TY[i],$LX[i+1],$LY[i+1]) style (line,2) COLOURED (0,0,200)
    next
    
    endif
    if grafica>=1 then
    drawtext ("#LastPoint#",barindex, HIGH+20)
    endif
    //TABELLA PER VISUALIZZARE CONTENUTO ARRAY - SOLO PER DEBUG
    if grafica>=2 then
    for tt=0 to lastset($TX) do //indicare Array da scansionare
    KToffsetX = -50 //Offset inizio tabella sull'asse X rispetto all'ultimo LOW
    KToffsetY = 80*pipsize //Offset inizio tabella sull'asse Y rispetto all'ultimo LOW
    KTcol     = 5 //passo fra le colonne
    KTrow     = 5*pipsize //passo fra le righe
    
    IA        = tt      //indice dell'Array
    V1A       = $TX[tt] //variabile 1 in tabella
    V2A       = $TY[tt] //variabile 2 in tabella
    V3A       = $LX[tt] //variabile 3 in tabella
    V4A       = $LY[tt] //variabile 4 in tabella
    drawtext("#IA#" ,barindex+KToffsetX+KTcol*1,low-KToffsetY-KTrow*tt)
    drawtext("#V1A#",barindex+KToffsetX+KTcol*2,low-KToffsetY-KTrow*tt)
    drawtext("#V2A#",barindex+KToffsetX+KTcol*3,low-KToffsetY-KTrow*tt)
    drawtext("#V3A#",barindex+KToffsetX+KTcol*4,low-KToffsetY-KTrow*tt)
    drawtext("#V4A#",barindex+KToffsetX+KTcol*5,low-KToffsetY-KTrow*tt)
    next
    endif
    return
    effegi thanked this post
    #206539 quote
    effegi
    Participant
    Senior

    Come l’hai realizzato tu funziona perfettamente, anche se ancora non mi è completamente chiaro il motivo.
    Ho fatto anche un esperimento per fare eseguire la parte centrale del codice solo quando:
    Time <> Time[1]
    ma non è sufficiente, è proprio necessario anche il confronto fra:
    $myTime[0] <> $myTime[1]
    come hai fatto tu, e la relativa transizione a fine codice $myTime[1] = $myTime[0] anche se il contenuto di $myTime è sempre il valore Time (che teoricamente incrementa con passo >= 1 secondo essendo un valore HHMMSS).
    E’ un po difficile spiegarsi via messaggio 🙂
    Me lo studio ancora un po per riuscire a mettere bene a fuoco la tua modifica risolutiva.
    Per intanto ti ringrazio! Dai tuoi post imparo sempre qualcosa in più 😉
    Buone feste Roberto

    robertogozzi thanked this post
    #206540 quote
    robertogozzi
    Moderator
    Master

    Il problema sta sia nel verificare l’orario diverso dal precedente, ma che anche che i due elementi siano diversi, in quanto quest’ultimi vengono aggiornati (e saranno identici) ad ogni tick successivo. Interessa fare in modo che siano diversi solo per il PRIMO tick.

    Se verifico le date, queste saranno sempre diverse rispetto alla barra precedente, in quanto sono dati storicizzati per ciascuna barra, mentre i due elementi del nuovo ARRAY no, per cui combinando insieme le due cose si riesce a risolvere il problema.

    Come vedi è passato del tempo prima che abbia potuto risponderti, perché trovare una soluzione è stato impegnativo; ho provato diverse soluzioni che non funzionavano ed ogni volta ho abbandonato temporaneamente per staccare la mente da quel problema… alla fine ce l’ho fatta.

    Buone Feste anche a te (e a tutti gli altri) 🙂

    effegi thanked this post
    #206542 quote
    effegi
    Participant
    Senior

    Ci stavo riflettendo… ed effettivamente il problema si capisce meglio facendolo girare su un grafico a 1 tick. Come giustamente dicevi tu, il TIME in HHMMSS rimane uguale anche per diversi tick, mente ovviamente i valori del prezzo continuano a cambiare e quindi anche i relativi calcoli nel ciclo dell’indicatore.
    In alcune condizioni, il valore di LastPoint continua a commutare da 1 a -1 all’interno della stessa barra, facendo quindi aggionare i valori di X e Y di entrambi gli array $T e $L, che ad un certo punto si riempiono dello stesso prezzo e barindex.
    La tua (ottima) soluzione riesce ad ovviare a questo anomalo comportamento.
    Grazie ancora per il tempo speso, per me è stato molto utile!

    #206816 quote
    tundercut
    Participant
    Senior

    Scusatemi ma perchè mi da questo errore?

    Immagine-05-01-23-alle-10.56.jpg Immagine-05-01-23-alle-10.56.jpg
    #206818 quote
    robertogozzi
    Moderator
    Master

    Elimina la linea 3, ma se l’errore si sposta su rughe più in basso allora è un problema del copia e incolla.

    Fai la copia del codice utilizzando il pulsante indicato nella foto e premendo Ctrl+C (poi incollalo al posrto di quello errato).

    x.jpg x.jpg
Viewing 12 posts - 1 through 12 (of 12 total)
  • You must be logged in to reply to this topic.

Indicatore ZigZag – Prova codice


ProBuilder: Indicatori & Strumenti Personalizzati

New Reply
Author
author-avatar
effegi @effegi Participant
Summary

This topic contains 11 replies,
has 4 voices, and was last updated by robertogozzi
3 years, 2 months ago.

Topic Details
Forum: ProBuilder: Indicatori & Strumenti Personalizzati
Language: Italian
Started: 12/16/2022
Status: Active
Attachments: 5 files
Logo Logo
Loading...