Dans le chapitre sur les croisements, l’indicateur traçait un repère au croisement des moyennes. Vous utiliserez maintenant le même événement pour déclencher un ordre simulé. Le programme ouvre une position acheteuse au croisement haussier et la ferme au croisement baissier.

Que fait une stratégie ?

Un indicateur calcule et affiche. Une stratégie transmet aussi des ordres au simulateur de backtest. Celui-ci suit les ordres, les positions et leurs résultats à partir des bougies historiques et des règles définies.

Cette simulation sur le passé s’appelle un backtest. Tous les ordres de ce chapitre sont simulés ; lancer Run Pyne code ne les transmet pas à un compte de trading réel.

Une position est la quantité détenue après l’exécution d’une entrée. Un ordre est une instruction ; son exécution est l’événement qui crée ou modifie la position. Nous ne confondrons pas ces trois termes.

Décrire les règles avant le code

Les règles de notre stratégie :

  • Calculer une SMA de cinq et une de vingt à chaque bougie.
  • Au croisement haussier, passer un ordre d’entrée pour une position longue d’une unité.
  • Au croisement baissier, fermer la position associée à l’entrée identifiée par Long.
  • Effectuer les calculs avec les données de bougies historiques clôturées.

La valeur d’une position longue augmente lorsque le prix monte et diminue lorsqu’il baisse. Cet exemple n’ouvre aucune position courte.

La règle n’affirme pas que chaque croisement haussier sera rentable. Le backtest sert justement à examiner ce que ces opérations auraient produit sur les données choisies.

Le programme complet

Créez crossover_strategy.py :

"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, strategy, ta


@script.strategy(
    "Average Crossing Strategy",
    overlay=True,
    initial_capital=10000,
    default_qty_type=strategy.fixed,
    default_qty_value=1,
    pyramiding=1,
)
def main(
    fast_length: int = input.int(5, title="Fast length", minval=1, maxval=200),
    slow_length: int = input.int(20, title="Slow length", minval=1, maxval=200),
):
    fast_average = ta.sma(close, fast_length)
    slow_average = ta.sma(close, slow_length)
    crosses_up = ta.crossover(fast_average, slow_average)
    crosses_down = ta.crossunder(fast_average, slow_average)
    if crosses_up:
        strategy.entry("Long", strategy.long)
    if crosses_down:
        strategy.close("Long")
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)

@script.strategy indique que main() est une stratégie. Les calculs et les deux lignes restent utilisables. Le nouvel espace de noms importé, strategy, contient les opérations sur les ordres et les données de stratégie.

Le décorateur est un appel sur plusieurs lignes. Ses réglages contrôlent l’exécution de la stratégie ; les paramètres de main() sont les entrées de nos calculs.

Capital initial et quantité

initial_capital=10000 définit le solde initial de la simulation. Les métadonnées de marché propres à la démonstration définissent les unités et niveaux de prix de l’exécution.

default_qty_type=strategy.fixed indique une quantité fixe. default_qty_value=1 demande un ordre d’une unité. Ce n’est ni un pourcentage du capital ni nécessairement une unité monétaire.

pyramiding=1 autorise au plus une entrée dans la même direction. L’exemple n’augmente pas une position existante par de nouvelles entrées longues.

Pour apprendre, nous suivons les opérations avec une petite quantité fixe. Cela réduit le nombre de facteurs de dimensionnement à examiner lorsque le résultat change.

Les identifiants d’entrée et de fermeture

Le premier argument de strategy.entry("Long", strategy.long) est un identifiant d’ordre. Le programme choisit le texte Long ; le second argument définit la direction.

strategy.close("Long") référence le même identifiant. Les noms doivent correspondre. Une fermeture de "Long" ne cible pas une entrée nommée "Buy".

Le croisement baissier déclenche ici une fermeture, pas une entrée courte. Si aucune position associée à cet identifiant n’est ouverte, il n’y a rien à fermer.

Exécuter dans PyneIDE

  1. Enregistrez le programme complet.
  2. Choisissez Run Pyne code et les données demo.
  3. Vérifiez les deux SMA et les repères de transactions sur le graphique.
  4. Ouvrez le panneau sous le graphique et sélectionnez Trades.
À côté de crossover_strategy.py, deux SMA et les repères des entrées et sorties de la stratégie sont visibles.
Les croisements des SMA déclenchent des ordres ; les transactions exécutées apparaissent aussi sur le graphique.

Si aucune transaction n’apparaît, vérifiez que vous avez lancé le fichier de stratégie et conservé @script.strategy. Vérifiez aussi les valeurs effectives des deux inputs. Deux SMA de même longueur et de même source ne se croisent pas.

L’instant du signal et celui de l’exécution

Avec les réglages utilisés ici, le programme passe un ordre au marché à partir des données de clôture d’une bougie. Cet ordre s’exécute généralement à l’ouverture de la suivante. La bougie du signal peut donc différer de celle de l’entrée.

Il en va de même pour une fermeture au marché. L’ordre créé au croisement baissier peut fermer la position à l’ouverture suivante.

Un ordre produit à la dernière bougie n’a pas de bougie suivante dans le fichier. Il ne sera donc pas forcément exécuté. Une position ouverte auparavant peut aussi rester ouverte à la fin des données.

Le mode d’exécution fait partie des réglages. Le chapitre suivant le présente aussi dans Properties. Interprétez toujours un résultat avec le mode d’exécution qui l’a produit.

À vous de jouer

Ouvrez les inputs de la stratégie et réglez les deux longueurs sur 20. Prévoyez la position relative des deux lignes et le nombre de croisements susceptibles de déclencher une transaction.

Solution de l’exercice

Les deux SMA utilisent les mêmes prix avec la même fenêtre ; elles sont identiques. Aucune bougie ne fait passer l’une au-dessus ou au-dessous de l’autre. La stratégie n’ouvre aucune transaction selon cette règle.

Le graphique n’affiche ce résultat qu’après l’enregistrement des inputs modifiés et la fin du recalcul. Rétablissez ensuite les valeurs 5 et 20.

Examiner une entrée

Choisissez une entrée exécutée et examinez les deux moyennes sur la bougie précédente. Le croisement haussier doit avoir lieu à la bougie du signal. Comparez le prix de la transaction à l’ouverture de la bougie d’entrée, sans l’assimiler automatiquement à la clôture du signal.