Series conserve un historique associé aux bougies. Parfois, vous souhaitez décider vous-même quelles valeurs collecter, dans quel ordre et quand les supprimer. Vous pouvez utiliser un tableau.

Que contient un tableau ?

Un tableau est une suite d’éléments. Chaque élément possède un indice ; le premier est zéro.

Un tableau contient des éléments de même type. Il peut stocker des nombres ou des textes, mais nous ne mettons pas de texte dans un tableau numérique. Même type ne signifie pas même valeur : 100, 103 et 101 sont des nombres différents dans un même tableau.

Si vous ajoutez 100, 103 et 101 dans cet ordre, l’élément d’indice 0 vaut 100, celui d’indice 1 vaut 103 et celui d’indice 2 vaut 101. L’indice désigne ici un emplacement, pas automatiquement un nombre de bougies dans le passé.

close[1] est la clôture précédente. array.get(prices, 1) est le deuxième élément du tableau prices. L’âge de cet élément dépend de la manière dont vous remplissez le tableau.

L’espace de noms array

array.new_float(0) crée un tableau numérique initialement vide. Zéro indique le nombre initial d’éléments, pas un prix initial.

OpérationRôle
array.push(prices, close)Ajoute un élément à la fin
array.size(prices)Renvoie le nombre d’éléments
array.shift(prices)Retire et renvoie le premier élément
array.get(prices, 0)Lit le premier élément
array.avg(prices)Calcule la moyenne des nombres conservés

L’indice de array.get doit correspondre à un élément existant. Pour trois éléments, 0, 1 et 2 sont valides, mais pas 3.

Conserver cinq prix récents

Créez recent_prices.py :

"""
@pyne edge
"""
from pynecore import Persistent
from pynecore.lib import array, close, color, plot, script, ta


@script.indicator("Recent Prices", overlay=True)
def main():
    prices: Persistent[list[float]] = array.new_float(0)
    array.push(prices, close)
    if array.size(prices) > 5:
        array.shift(prices)
    stored_average = array.avg(prices)
    full_average = ta.sma(close, 5)
    plot(stored_average, "Stored average", color=color.blue, linewidth=2)
    plot(full_average, "SMA 5", color=color.orange)

list[float] est le type d’un tableau numérique. Persistent conserve le tableau pour la bougie suivante. Sa création n’est pas répétée à chaque bougie.

Nous manipulons le tableau avec l’espace de noms array. Il n’est pas nécessaire d’importer une bibliothèque Python généraliste ni d’écrire un littéral de liste.

Exécutez-le sur les données de démonstration. La ligne bleue trace la moyenne des prix déjà collectés. Elle utilise un prix à la première bougie, deux à la deuxième, puis trois et quatre. À partir de la cinquième, cinq éléments sont conservés.

Le graphique de recent_prices.py affiche en bleu la moyenne des prix conservés et en orange la SMA sur cinq bougies.
Nous comparons la moyenne de notre tableau à une SMA calculée sur une fenêtre complète de cinq valeurs.

L’ordre d’ajout et de retrait

À la sixième bougie, nous ajoutons d’abord la sixième clôture. Le tableau contient alors six éléments. La condition if est vraie : nous retirons donc le premier, le plus ancien. Au moment de calculer la moyenne, il ne reste que les cinq clôtures des bougies deux à six.

Dans ce programme, le début du tableau contient le plus ancien prix conservé et la fin le plus récent. À partir de cinq éléments, array.get(prices, 0) donne donc le prix de quatre bougies auparavant, pas le prix actuel.

Pour lire le plus récent, utilisez le dernier indice : array.size(prices) - 1. Le nombre d’éléments et le dernier indice diffèrent d’un, car la numérotation commence à zéro.

Une fenêtre partielle ou complète

Les deux moyennes se comportent différemment au début. Celle du tableau se calcule aussi avec les un à quatre prix déjà collectés. ta.sma(close, 5) ne fournit une valeur qu’avec une fenêtre complète de cinq.

À partir de la cinquième bougie, elles utilisent les mêmes cinq clôtures. Les deux lignes doivent alors coïncider à la précision de représentation des nombres près.

Une moyenne sur tableau ne remplace donc pas automatiquement la moyenne mobile existante. Vous devez définir la règle pour la fenêtre initiale.

Pourquoi limiter la taille ?

Si vous ajoutez un élément à chaque bougie sans en retirer, le tableau grandit avec les données. À la fin, il contiendrait toutes les clôtures traitées.

Ici, seuls les cinq derniers prix nous intéressent, donc nous retirons les plus anciens. Au moment du calcul, la taille reste limitée à cinq. Dans une véritable collecte, définissez aussi quelles données conserver et pendant combien de temps.

À vous de jouer

Modifiez le programme pour conserver trois prix. Réglez aussi la SMA sur trois. Tracez ensuite le plus ancien élément conservé comme troisième ligne.

Solution de l’exercice

La condition de retrait :

if array.size(prices) > 3:
    array.shift(prices)

La moyenne existante et la nouvelle ligne :

full_average = ta.sma(close, 3)
oldest_price = array.get(prices, 0)
plot(oldest_price, "Oldest stored price", color=color.gray)

array.push précède la lecture à chaque bougie ; le tableau a donc au moins un élément. Une fois sa taille de trois atteinte, son plus ancien prix date de deux bougies auparavant.

Noter le contenu du tableau

Avec trois éléments conservés plutôt que cinq et la suite de prix 100, 103, 101, 105, notez le contenu après chacune des quatre bougies. Après la quatrième, il doit contenir 103, 101 et 105, dans cet ordre.