Indicatore ZigZag – Prova codice
Forums › ProRealTime forum Italiano › Supporto ProBuilder › Indicatore ZigZag – Prova codice
- This topic has 11 replies, 4 voices, and was last updated 1 year ago by robertogozzi.
-
-
12/16/2022 at 9:25 PM #205922
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.TF-ZigZagProva_PRC123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104//16/12/2022 - T.F. - Codice ZigZag con Array//Sharing ProRealCodeDEFPARAM 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 onlyPI=max(0,(Segmenti-1)) //punti indietro da memorizzareVarY=CustomClose //close,tpicalprice, etc//inizializzo primo punto come TOPonce LastPoint = 1once $TX[0] = barindexonce $TY[0] = VarY//Tipo ZZ in Punti o PercentualeIf Tipo=0 then //ZZ in puntiDeltaY=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 valoreendif//ZZ in fase 1if LastPoint=1 then //ultimo punto era un massimoif VarY>$TY[0] then // aggiorno il punto di max e rimango in LastPoint=1$TY[0]=VarY$TX[0]=barindexelsif VarY<($TY[0]-DeltaY) then //primo punto definitivo lowfor 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]=barindexLastPoint=-1endifendif//ZZ in fase -1if LastPoint=-1 then //ultimo punto era un minimoif VarY<$LY[0] then // aggiorno il punto di min e rimango in LastPoint=-1$LY[0]=VarY$LX[0]=barindexelsif VarY>($LY[0]+DeltaY) then //primo punto definitivo topfor 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]=barindexLastPoint=1endifendif//---GRAFICA---If LastPoint=1 thendrawsegment (barindex,VarY,$TX[0],$TY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progressfor i=0 to PI do //segmenti definitividrawsegment ($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)nextendifIf LastPoint=-1 thendrawsegment (barindex,VarY,$LX[0],$LY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progressfor i=0 to PI do //segmenti definitividrawsegment ($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)nextendifif grafica>=1 thendrawtext ("#LastPoint#",barindex, HIGH+20)endif//TABELLA PER VISUALIZZARE CONTENUTO ARRAY - SOLO PER DEBUGif grafica>=2 thenfor tt=0 to lastset($TX) do //indicare Array da scansionareKToffsetX = -50 //Offset inizio tabella sull'asse X rispetto all'ultimo LOWKToffsetY = 80*pipsize //Offset inizio tabella sull'asse Y rispetto all'ultimo LOWKTcol = 5 //passo fra le colonneKTrow = 5*pipsize //passo fra le righeIA = tt //indice dell'ArrayV1A = $TX[tt] //variabile 1 in tabellaV2A = $TY[tt] //variabile 2 in tabellaV3A = $LX[tt] //variabile 3 in tabellaV4A = $LY[tt] //variabile 4 in tabelladrawtext("#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)nextendifreturn12/16/2022 at 9:59 PM #20592812/17/2022 at 4:17 PM #205963Grazie per averlo condiviso, sicuramente sarà di aiuto a molti trader.
Puoi ripostare il codice corretto, se vuoi, altrimenti ognuno farà la modifica da solo.
12/17/2022 at 5:48 PM #20596712/17/2022 at 7:14 PM #205977Come 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
2 users thanked author for this post.
12/20/2022 at 5:36 PM #206100Buon 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
ZigZag ver.1123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596//20/12/2022 - T.F. - V1: Codice ZigZag Versione v1: eliminati gli array e gestito con variabili fisse//Sharing on ProRealCodeDEFPARAM DRAWONLASTBARONLY=TRUE//Variabili://Punti=20 //Pips//Percentuale=0.25 //%//Tipo=0 //0=pips; 1=percVarY=CustomClose //close,tpicalprice, etc//inizializzo primo punto come TOPonce LastPoint = 1once TX0 = barindexonce TY0 = VarY//Tipo ZZ in Punti o PercentualeIf Tipo=0 then //ZZ in puntiDeltaY=Punti*pipsizeelsif tipo=1 then //ZZ in %DeltaY=Percentuale/100*Dclose(1)//usato Dclose come rif. per stabilità del valoreendif//ZZ in fase 1if LastPoint=1 then //ultimo punto era un massimoif VarY>=TY0 then // aggiorno il punto di max e rimango in LastPoint=1TY0=VarYTX0=barindexendifif VarY<=TY0-DeltaY then //primo punto definitivo lowrem for i=PI downto 0 do //shift memoria punti precedentiLX4=LX3LY4=LY3LX3=LX2LY3=LY2LX2=LX1LY2=LY1LX1=LX0LY1=LY0LY0=VarY //primo punto definitivo topLX0=barindexLastPoint=-1endifendif//ZZ in fase -1if LastPoint=-1 then //ultimo punto era un minimoif VarY<=LY0 then // aggiorno il punto di min e rimango in LastPoint=-1LY0=VarYLX0=barindexendifif VarY>=LY0+DeltaY then //primo punto definitivo topTX4=TX3TY4=TY3TX3=TX2TY3=TY2TX2=TX1TY2=TY1TX1=TX0TY1=TY0TY0=VarY //primo punto definitivo topTX0=barindexLastPoint=1endifendif//---GRAFICA---If lastpoint=1 thendrawsegment (barindex,close,TX0,TY0) style (dottedline,2) COLOURED (0,0,200) //segmento in progressdrawsegment (TX0,TY0,LX0,LY0) style (line,2) COLOURED (0,0,200) //segmenti definitividrawsegment (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)endifIf lastpoint=-1 thendrawsegment (barindex,close,LX0,LY0) style (dottedline,2) COLOURED (0,200,0) //segmento in progressdrawsegment (LX0,LY0,TX0,TY0) style (line,2) COLOURED (0,0,200) //segmenti definitividrawsegment (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)endifreturn12/29/2022 at 8:05 PM #206474Il 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:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112//16/12/2022 - T.F. - Codice ZigZag con Array//Sharing ProRealCodeDEFPARAM DRAWONLASTBARONLY=TRUE//Variabili:Punti=20 //PipsPercentuale=0.25 //%Tipo=0 //0=pips; 1=percSegmenti=5 //n. segmenti up/dw da visualizzareGrafica=0 //debug onlyPI=max(0,(Segmenti-1)) //punti indietro da memorizzareONCE $myTime[0] = 0ONCE $myTime[1] = -1$myTime[0] = TimeIF Time <> Time[1] AND $myTime[0] <> $myTime[1] THEN$myTime[0] = TimeENDIFIF $myTime[1] <> $myTime[0] THENVarY=CustomClose //close,tpicalprice, etc//inizializzo primo punto come TOPonce LastPoint = 1once $TX[0] = barindexonce $TY[0] = VarY//Tipo ZZ in Punti o PercentualeIf Tipo=0 then //ZZ in puntiDeltaY=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 valoreendif//ZZ in fase 1if LastPoint=1 then //ultimo punto era un massimoif VarY>$TY[0] then // aggiorno il punto di max e rimango in LastPoint=1$TY[0]=VarY$TX[0]=barindexelsif VarY<($TY[0]-DeltaY) then //primo punto definitivo lowfor 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]=barindexLastPoint=-1endifendif//ZZ in fase -1if LastPoint=-1 then //ultimo punto era un minimoif VarY<$LY[0] then // aggiorno il punto di min e rimango in LastPoint=-1$LY[0]=VarY$LX[0]=barindexelsif VarY>($LY[0]+DeltaY) then //primo punto definitivo topfor 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]=barindexLastPoint=1endifendifendif$myTime[1] = $myTime[0]//---GRAFICA---If LastPoint=1 thendrawsegment (barindex,VarY,$TX[0],$TY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progressfor i=0 to PI do //segmenti definitividrawsegment ($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)nextendifIf LastPoint=-1 thendrawsegment (barindex,VarY,$LX[0],$LY[0]) style (dottedline,2) COLOURED (0,0,200) //segmento in progressfor i=0 to PI do //segmenti definitividrawsegment ($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)nextendifif grafica>=1 thendrawtext ("#LastPoint#",barindex, HIGH+20)endif//TABELLA PER VISUALIZZARE CONTENUTO ARRAY - SOLO PER DEBUGif grafica>=2 thenfor tt=0 to lastset($TX) do //indicare Array da scansionareKToffsetX = -50 //Offset inizio tabella sull'asse X rispetto all'ultimo LOWKToffsetY = 80*pipsize //Offset inizio tabella sull'asse Y rispetto all'ultimo LOWKTcol = 5 //passo fra le colonneKTrow = 5*pipsize //passo fra le righeIA = tt //indice dell'ArrayV1A = $TX[tt] //variabile 1 in tabellaV2A = $TY[tt] //variabile 2 in tabellaV3A = $LX[tt] //variabile 3 in tabellaV4A = $LY[tt] //variabile 4 in tabelladrawtext("#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)nextendifreturn1 user thanked author for this post.
12/30/2022 at 5:19 PM #206539Come 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 Roberto1 user thanked author for this post.
12/30/2022 at 5:31 PM #206540Il 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) 🙂
1 user thanked author for this post.
12/30/2022 at 5:58 PM #206542Ci 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!01/05/2023 at 11:02 AM #20681601/05/2023 at 11:11 AM #206818Elimina 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).
-
AuthorPosts
Find exclusive trading pro-tools on