Bonjour,
Je souhaite créer un histogramme par volume de prix. Le problème que je rencontre c’est qu’en temps réel, l’incrémentation +1 se réalise à chaque tick.
J’ai tenté d’ajouter une variable LastUpdate qui empêche de mettre à jour le tableau sur la bougie en cours, mais ça ne marche pas…
Voici le code
// Par convention, on définit une tranche de l'histogramme --> prix arrondi à l'unité
// On mémorise chaque cotation dans un tableau donc l'indice est le prix arrondi à l'unité
// Exemple :
// $NbCotation[6500] renvoie le nombre de fois où le prix 6500 a été touché
// $Cotation[6500] renvoie la valeur de cotation : 6500
// Représentation graphique sous forme d'histogramme :
// axe horizontal : $NbCotation[6500]
// axe vertical : $Cotation[6500]
defparam DRAWONLASTBARONLY = true
timeframe(default, UPDATEONCLOSE)
//********************************************************************************************************************
// Mémorisation des cotations
//********************************************************************************************************************
once MaxHighUnitaire = round(high+0.5) // utile pour la représentation graphique
once MinLowUnitaire = round(low-0.5) // utile pour la représentation graphique
once LastUpdate = barindex // initialisation sur le premier barindex égal à 0
if barindex > 0 and barindex <> LastUpdate then //On comptabilise quand la bougie est clôturée
HighUnitaire = round(high[1]+0.5) //bougie précédente clôturée
LowUnitaire = round(low[1]-0.5) //bougie précédente clôturée
for i = LowUnitaire to HighUnitaire
if isset($NbCotation[i]) then //cotation déjà touchée, alors on ajoute 1
$NbCotation[i] = $NbCotation[i]+1
else
$NbCotation[i] = 1 // première fois que la cotation est atteinte, on initialise à 1
$Cotation[i] = i // on mémorise le prix de cotation pour le graphique
endif
MaxHighUnitaire = max(MaxHighUnitaire, HighUnitaire)
MinLowUnitaire = min(MinLowUnitaire, LowUnitaire)
next
LastUpdate = barindex
endif
//********************************************************************************************************************
// Représentation graphique sous forme d'histogramme
//********************************************************************************************************************
if IsLastBarUpdate then
for i = MinLowUnitaire to MaxHighUnitaire
if i >=low and i<=high then //Jeux de couleurs pour visualiser les tranches concernées par la bougie en cours
R=255
G=0
B=0
else
R=0
G=255
B=0
endif
if isset($NbCotation[i]) then
DRAWRECTANGLE(0, $Cotation[i], $NbCotation[i], $Cotation[i]-1) coloured(R,G,B,50) bordercolor(R,G,B,0)
else // Gestion des gaps (ils n'ont pas été mémorisés)
$NbCotation[i] = 0
$Cotation[i] = i
DRAWRECTANGLE(0, $Cotation[i], $NbCotation[i], $Cotation[i]-1) coloured(R,G,B,50) bordercolor(R,G,B,0)
endif
next
DRAWLINE(0, high, barindex, high) style(dottedline,1)
DRAWLINE(0, low, barindex, low) style(dottedline,1)
endif
return
L’instruction IsLastBarUpdate retourne un booléen TRUE à chaque fois que le prix de la barre actuelle change, donc je pense que cela n’est pas approprié pour ta demande.
Je pense toutefois qu’il y a un bug quelque part.
J’ai refait un code plus simple (voir ci-dessous) qui se compose de 3 étapes.
Seule l’étape 1 alimente deux tableaux : X (nombre de fois que le prix est atteint) et Y (valeur arrondie du prix). Cette étape n’a lieu qu’une et seule fois.
Pourtant, en le testant par exemple sur le future CAC en 5 minutes, on voit très bien que :
- le tableau continue d’être alimenté (la somme calculée augmente et l’histogramme idem).
- pourtant le traceur ne bouge pas. Donc l’étape 1 n’a bien lieu qu’une fois.
-
//Etape 0 : on ne fait rien
//Etape 1 : on compte le nombre de fois où le prix est atteint (Etape qui n'a lieu qu'une seule fois)
//Etape 2 : on dessine l'histogramme des prix
defparam DRAWONLASTBARONLY = true
once Etape = 0
if IsLastBarUpdate then
if Etape = 0 then
Etape = 1
endif
endif
once traceur = 0
If Etape = 1 then
traceur = traceur + 1
Y3Rmax = round(highest[barindex](high))
Y3Rmin = round(lowest[barindex](low))
for x = 0 to barindex-1
xi = barindex - x
LowR = round(low[xi])
HighR = round(high[xi])
for i = LowR to HighR
if isset($X2[i]) then //Le prix a déjà été atteint, on ajoute 1
$X2[i] = $X2[i]+1
else //Toute première fois que le prix est atteint, on le crée
$X2[i] = 1
$Y2R[i] = i
endif
next
next
Somme = 0
for i = Y3Rmin to Y3Rmax
Somme = Somme + $X2[i]
next
Etape = 2
endif
if Etape = 2 then
for i = Y3Rmin to Y3Rmax
DRAWSEGMENT(0, $Y2R[i], $X2[i], $Y2R[i]) style(line,5)
next
endif
drawtext("traceur:#traceur# Somme:#Somme#",round(barindex/2),Y3Rmax+1)
return
En effet, je remarque un comportement qui m’échappe.. Je poste ici le code pour référence, je vais reboucler en interne et revenir dés que j’ai une piste, merci pour ta patience.
//Etape 0 : on ne fait rien
//Etape 1 : on compte le nombre de fois où le prix est atteint (Etape qui n'a lieu qu'une seule fois)
//Etape 2 : on dessine l'histogramme des prix
defparam DRAWONLASTBARONLY = true
//once Etape = 0
if IsLastBarUpdate then
if Etape = 0 then
startbar=barindex
Etape = 1
endif
endif
//once traceur = 0
If Etape = 1 then
traceur = traceur + 1
Y3Rmax = round(highest[barindex](high))
Y3Rmin = round(lowest[barindex](low))
for x = 0 to barindex-1
xi = barindex - x
LowR = round(low[xi])
HighR = round(high[xi])
for i = LowR to HighR
if isset($X2[i]) then //Le prix a déjà été atteint, on ajoute 1
$X2[i] = $X2[i]+1
else //Toute première fois que le prix est atteint, on le crée
$X2[i] = 1
$Y2R[i] = i
endif
next
next
Somme = 0
for i = Y3Rmin to Y3Rmax
Somme = Somme + $X2[i]
next
Etape = 2
endif
if islastbarupdate and Etape = 2 then
for i = Y3Rmin to Y3Rmax
DRAWSEGMENT(0, $Y2R[i], $X2[i], $Y2R[i]) style(line,5)
drawtext($Y2R[i],$X2[i],$Y2R[i])
next
endif
drawtext("traceur:#traceur# Somme:#Somme# Etape:#etape#",barindex,Y3Rmax+1)
return startbar,barindex, Y3Rmin,Y3Rmax//LowR,Highr
On me glisse à l’oreille, que en effet, puisqu’une variable “standard” (en l’occurrence Etape) ne prend sa valeur définitive qu’à la fin d’une bougie, à son Close, alors à chaque tick reçu durant la même bougie, elle vaut toujours 0. Donc en utilisant un tableau associé à la condition de cette variable, ton tableau change de valeur jusqu’au Close de la bougie en cours et par conséquent continue à se tracer avec des valeurs différentes à chaque nouveau tick reçu. Est-ce clair ?
Merci Nicolas. Oui c’est très clair. Je comprends mieux maintenant pourquoi sur des unités de temps plus courtes les données se stabilisent à un moment donné.
Par contre je suis preneur de toute astuce 😉
Les variables de type tableau prennent une valeur et ne reset pas durant la même barre, contrairement à une variable ordinaire.
Nicolas,
J’ai changé la variable normale en tableau (voir code).
L’histogramme et le texte apparaissent mais disparaissent au prochain tick.
//Etape 0 : on ne fait rien
//Etape 1 : on compte le nombre de fois où le prix est atteint (Etape qui n'a lieu qu'une seule fois)
//Etape 2 : on dessine l'histogramme des prix
defparam DRAWONLASTBARONLY = true
if not isset($Etape[0]) then
$Etape[0] = 0
endif
if IsLastBarUpdate then
if $Etape[0] = 0 then
$Etape[0] = 1
endif
endif
once traceur = 0
If $Etape[0] = 1 then
traceur = traceur + 1
Y3Rmax = round(highest[barindex](high))
Y3Rmin = round(lowest[barindex](low))
for x = 0 to barindex-1
xi = barindex - x
LowR = round(low[xi])
HighR = round(high[xi])
for i = LowR to HighR
if isset($X2[i]) then //Le prix a déjà été atteint, on ajoute 1
$X2[i] = $X2[i]+1
else //Toute première fois que le prix est atteint, on le crée
$X2[i] = 1
$Y2R[i] = i
endif
next
next
Somme = 0
for i = Y3Rmin to Y3Rmax
Somme = Somme + $X2[i]
next
$Etape[0] = 2
endif
if $Etape[0] = 2 then
for i = Y3Rmin to Y3Rmax
DRAWSEGMENT(0, $Y2R[i], $X2[i], $Y2R[i]) style(line,5)
next
endif
drawtext("traceur:#traceur# Somme:#Somme#",round(barindex/2),Y3Rmax+1)
return
Les mêmes raisons causent les mêmes effets 🙂
Toujours des variables qui reset dés le premier nouveau tick reçu.
Voilà une version qui fonctionne, j’ai supprimé les étapes, ayant bien compris le fonctionnement de ce que tu cherchais à faire.
defparam DRAWONLASTBARONLY = true
if IsLastBarUpdate and not isset($somme[0]) then
Y3Rmax = round(highest[barindex](high))
Y3Rmin = round(lowest[barindex](low))
for x = 0 to barindex-1
xi = barindex - x
LowR = round(low[xi])
HighR = round(high[xi])
for i = LowR to HighR
if isset($X2[i]) then //Le prix a déjà été atteint, on ajoute 1
$X2[i] = $X2[i]+1
else //Toute première fois que le prix est atteint, on le crée
$X2[i] = 1
$Y2R[i] = i
endif
next
next
Somme = 0
for i = Y3Rmin to Y3Rmax
Somme = Somme + $X2[i]
next
$somme[0]=somme
$Y3Rmax[0] = Y3Rmax
$Y3Rmin[0] = Y3Rmin
endif
if isset($somme[0]) then
for i = $Y3Rmin[0] to $Y3Rmax[0]
DRAWSEGMENT(0, $Y2R[i], $X2[i], $Y2R[i]) style(line,5)
next
endif
return
Top ! Ca faisait des jours que je me prenais la tête avec ça 🙂
Merci beaucoup Nicolas !
Super, bonne continuation.