Mettre à jour un tableau sur clôture de bougie

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #201637 quote
    Denis Quéva
    Participant
    New

    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
    #201693 quote
    Nicolas
    Keymaster
    Master

    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.

    #202307 quote
    Denis Quéva
    Participant
    New

    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

       

    #202345 quote
    Nicolas
    Keymaster
    Master

    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
    #202351 quote
    Nicolas
    Keymaster
    Master

    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 ?

    #202353 quote
    Denis Quéva
    Participant
    New

    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 😉

    #202359 quote
    Nicolas
    Keymaster
    Master

    Les variables de type tableau prennent une valeur et ne reset pas durant la même barre, contrairement à une variable ordinaire.

    #202366 quote
    Denis Quéva
    Participant
    New

    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
    #202412 quote
    Nicolas
    Keymaster
    Master

    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
    volume-by-price-indicartor.png volume-by-price-indicartor.png
    #202416 quote
    Denis Quéva
    Participant
    New

    Top ! Ca faisait des jours que je me prenais la tête avec ça 🙂

    Merci beaucoup Nicolas !

    #202426 quote
    Nicolas
    Keymaster
    Master

    Super, bonne continuation.

    Denis Quéva thanked this post
Viewing 11 posts - 1 through 11 (of 11 total)
  • You must be logged in to reply to this topic.

Mettre à jour un tableau sur clôture de bougie


ProBuilder : Indicateurs & Outils Personnalisés

New Reply
Author
author-avatar
Denis Quéva @deun-deun Participant
Summary

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

Topic Details
Forum: ProBuilder : Indicateurs & Outils Personnalisés
Language: French
Started: 09/29/2022
Status: Active
Attachments: 1 files
Logo Logo
Loading...