Comment écrire une stratégie de suivi de tendance avancée pour algotrade Bitcoin
Il n’est plus nécessaire de suivre les tendances
Le suivi des tendances est souvent le plus simple à la fois pour démarrer avec le trading d’algo et pour être rentable. Dans l’article précédent, j’ai écrit une stratégie de suivi de tendance et même augmenté ses performances en utilisant un délai plus long pour déterminer la tendance. Mais c’était une simple stratégie d’entrée et de sortie.
Le but de ce didacticiel est de vous familiariser avec quelques-unes des fonctionnalités de Jesse qui vous aident à écrire la plupart des stratégies de suivi de tendance que vous trouverez. Peu de ces fonctionnalités sont:
- Sortie du commerce en deux points, l’un à prix fixe, l’autre à prix dynamique.
- Mise à jour du stop-loss au seuil de rentabilité après avoir quitté la moitié de la position.
- Filtrer les transactions qui ont un mauvais rapport gain / perte.
- Utiliser les événements pour s’intégrer aux cycles de vie d’un métier.
Je crée d’abord une nouvelle stratégie avec le make-strategy
commander:
jesse make-strategy TrendFollowingStrategy
Et je modifie mon routes.py
fichier pour utiliser cette stratégie, et j’ai défini le délai à 4h
:
Ensuite, j’ouvre le fichier de stratégie nouvellement créé et il ressemble à ceci:
Je veux aller longtemps quand:
- Nous sommes dans une tendance haussière (et vice versa pour les trades courts)
- La bougie de fermeture (actuelle) touche la ligne 50 EMA
Ils disent qu’une image vaut 1 000 mots, alors voici une image montrant ce que je compte comme une tendance haussière dans ce cas:
Et voici ce que je veux dire par la bougie actuelle touchant le 50 EMA (la ligne orange est le 50 EMA):
Écrivons maintenant le code de current_candle_touches_long_ema
et trend
:
J’ai utilisé trois lignes EMA pour déterminer la direction de la tendance. je reviens 1
pour une tendance haussière, et -1
pour une tendance baissière. current_candle_touches_long_ema
est assez simple, je dois juste m’assurer que le prix élevé de la bougie actuelle est plus grand que le long_ema
(qui est une EMA avec une période de 50) et que le prix bas de la bougie actuelle est inférieur au long_ema
ligne.
Le prix d’entrée va être le plus haut de la bougie actuelle pour les transactions longues. Le prix stop-loss sera 3 fois l’ATR actuel loin de mon prix d’entrée.
Dans cette stratégie, je veux entrer des métiers en même temps, mais sortir à deux points. Je quitterai la première moitié de ma position au sommet précédent de la tendance. Voici ce que je veux dire par le haut de la tendance haussière (la ligne bleue est ma cible):
Pour coder cela, je sélectionne d’abord les prix élevés des 20 dernières bougies. Et puis renvoyez simplement le maximum d’entre eux.
Pour le dimensionnement de la position, je veux risquer 5% de mon capital total pour chaque transaction. Pour calculer le qty
Je utilise l risk_to_qty
utilitaire.
Et bien sûr, c’est l’inverse pour les métiers à découvert. Voici le code:
Comme vous pouvez le voir, je ne quitte que la moitié de la taille de ma position au prix de prise en charge. En d’autres termes, une fois ma position réduite, je souhaite faire passer mon prix stop au seuil de rentabilité. Pour écrire le code pour cela dans Jesse, je vais utiliser le pré-intégré on_reduced_position méthode.
Mise à jour du self.stop_loss
est tout ce que je devais faire pour dire à jesse de mettre à jour ma commande stop-loss. Jesse le récupère automatiquement, annule l’ordre d’arrêt précédent et en soumet un nouveau. Rien de plus simple!
Pour en savoir plus sur les événements et voir une liste de toutes les méthodes d’événement disponibles dans Jesse, assurez-vous de lire son Documentation.
Pour cette stratégie, j’ai l’intention de sortir de la seconde moitié de mon poste dans une situation dynamique. L’idée derrière cette situation est de sortir lorsque le prix est fortement suracheté et sur le point de prendre une sérieuse correction. Pour le dire dans la langue de quant, je veux quitter lorsque l’indicateur RSI atteint au-dessus de 80.
Je vais d’abord utiliser la fonction intégrée update_position()
pour écrire ma logique. Cette méthode n’est exécutée après chaque nouvelle bougie que si nous avons une position ouverte. Par conséquent, il est utilisé pour mettre à jour une position. Ce qui signifie que nous n’avons pas besoin de vérifier si la position est ouverte ou non.
La prochaine chose à considérer ici est que je ne souhaite quitter que la seconde moitié de mon poste. En d’autres termes, je veux liquider la position ouverte si elle a été réduite. La façon la plus simple de vérifier si ma position a été réduite consiste à utiliser la fonction intégrée est réduite propriété et liquider() méthode.
Ma stratégie semble bonne jusqu’à présent, exécutons un backtest et voyons comment ça se passe:
jesse backtest 2019-01-01 2020-05-01
Après environ 4% pour cent du backtest, j’obtiens une erreur:
Uncaught Exception: InvalidStrategy: take-profit(3601.6) must be below entry-price(3601.6) in a short position
L’erreur essaie de nous dire à un moment donné que les prix d’entrée et de profit de notre stratégie sont égaux (3601,6 $), ce qui n’est pas acceptable. Il s’agit d’un problème délicat à déboguer, mais vous serez capable de déboguer avec Jesse après avoir écrit vos premières stratégies.
Pour expliquer pourquoi ce problème se produit, nous devons revoir la prise en compte et l’entrée:
L’erreur nous a dit que l’entrée et le take-profit sont les mêmes à certains moments. Cela signifie qu’à ce stade, le sommet actuel de la bougie est le plus élevé des 20 dernières mesures. Ce n’est pas le type de commerce que nous avions en tête pour cette stratégie.
Nous pourrions empêcher que cela ne se produise avec quelques déclarations sales if-else dans notre should_long
ou en utilisant un filtre conçu spécifiquement pour ces types de cas.
Un filtre est juste une fonction qui renvoie une valeur booléenne. Un filtre est passé en renvoyant un True
et vice versa. Je définis un filtre et je le nomme reward_to_risk_filter
. Le nom peut être n’importe quoi, mais c’est généralement une bonne pratique de commencer ou de terminer le nom d’une méthode de filtrage par le mot filter
. Le travail de ce filtre est de s’assurer que le métier dans lequel nous essayons d’entrer en vaut la peine.
À ce stade, Jesse ne sait toujours pas que reward_to_risk_filter()
est un filtre. Pour lui faire reconnaître mon filtre, je dois l’ajouter au filters()
méthode qui est une méthode pré-intégrée qui retourne une liste Python:
Je vais maintenant ajouter reward_to_risk_filter
à l’intérieur de la liste de retour en tant que variable. Cela signifie qu’aucune parenthèse ne doit être présente à la fin:
Maintenant, exécutons le backtest une fois de plus:
jesse backtest 2019-01-01 2020-05-01
Cette fois, tout se passe bien.
Plus vous pouvez garder vos stratégies simples, plus il sera facile de les déboguer et même de s’améliorer avec le temps.
Écrire des stratégies avec Jesse est aussi simple que d’échanger vos stratégies manuellement. Donc, la prochaine fois que vous trouverez une stratégie introduite dans un livre de trading ou par un gourou du trading, écrivez simplement le code et testez-le.