ProRealCode - Trading & Coding with ProRealTime™
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
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?
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.
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!
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
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
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
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
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) 🙂
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!
Scusatemi ma perchè mi da questo errore?
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).
Indicatore ZigZag – Prova codice
This topic contains 11 replies,
has 4 voices, and was last updated by
robertogozzi
3 years, 2 months ago.
| Forum: | ProBuilder: Indicatori & Strumenti Personalizzati |
| Language: | Italian |
| Started: | 12/16/2022 |
| Status: | Active |
| Attachments: | 5 files |
The information collected on this form is stored in a computer file by ProRealCode to create and access your ProRealCode profile. This data is kept in a secure database for the duration of the member's membership. They will be kept as long as you use our services and will be automatically deleted after 3 years of inactivity. Your personal data is used to create your private profile on ProRealCode. This data is maintained by SAS ProRealCode, 407 rue Freycinet, 59151 Arleux, France. If you subscribe to our newsletters, your email address is provided to our service provider "MailChimp" located in the United States, with whom we have signed a confidentiality agreement. This company is also compliant with the EU/Swiss Privacy Shield, and the GDPR. For any request for correction or deletion concerning your data, you can directly contact the ProRealCode team by email at privacy@prorealcode.com If you would like to lodge a complaint regarding the use of your personal data, you can contact your data protection supervisory authority.