Approche probabiliste du Machine Learning pour le trading + compréhension commerciale MACD
Je veux vous donner un aperçu de cela avec un exemple. L’idée principale est de comprendre les informations fournies par nos experts: TRADERS! S’ils passent toute la journée à faire cela, nous devons être humbles et entendre ce qu’ils ont à nous dire. C’est un processus clé dans ce problème, mais aussi dans tout problème que vous êtes prêt à résoudre. Nous avons besoin de ce contexte commercial.
Notre objectif est de faire la meilleure ingénierie de fonctionnalités possible!. Et le processus de création de nos variables Besoins être basé sur des concepts commerciaux. Et seulement APRÈS cela, nous pouvons appliquer toutes les transformations habituelles, comme la normalisation ou la normalisation (la dernière partie UNIQUEMENT si cela fait sens!).
Le but de cette section sera de comparer les performances d’une première approche naïve, puis l’approximation du trading-bot, et, dans le dernier souffle, d’essayer de rassembler toutes les parties. Nous supposerons que nous ne pouvons positions longues, et à cause de cela, nous ne sommes intéressés que par les prédictions de résultats positifs.
PS: je vais vous laisser tout ce code de section sur mon github. Malgré quelques exceptions, le code sera générique pour gagner en fluidité. En outre, certains résultats peuvent changer (pas de façon spectaculaire, je les ai testés) en raison du caractère aléatoire de l’échantillonnage.
Nous allons récupérer nos données auprès de Binance, vous pouvez lire cette blog pour créer votre clé API. Ici est la documentation de python-binance. Nous utiliserons des intervalles de données de 5 minutes. Vous trouverez ci-dessous le code pour collecter les données (3 lignes pour les données, que je convertis en Flash?).
J’ai fait une méthode qui détermine ce qui se passe en premier: une augmentation de 0,5% ou une diminution de 0,5%. La logique est la suivante: la méthode recherche les 100 prochaines périodes (pour des données de 5 minutes, plus de 8 heures) et vérifie si le prix dépasse notre seuil défini, seule la première valeur atteinte est prise en compte.
Je viens d’utiliser le prix de clôture, car les valeurs élevées et basses pourraient être à la fois supérieures ou inférieures à nos objectifs, ce qui nous pose des problèmes. Comme prévu, pas dans tous les cas, il y a eu un résultat, mais le pourcentage n’est pas si élevé, et nous pouvons simplement nous débarrasser de ces données.
Note technique: Les données collectées couvrent les 500 jours précédents à la date ‘22 –04–2020 ’. J’ai marqué + 0,5% de résultats avec 1s et -0,5% avec 0s. Comme vous pouvez le voir, les données ne sont pas clairement déséquilibrées. Sur un total de 143 542 (120 245 pour s’entraîner et 23 297 pour tester les résultats), les points de données sont 49,85% négatifs, 49,82% positifs et 1,26% sans résultat.
Forfait TA a une méthode pour construire un grand nombre d’indicateurs utiles. La grande chose à ce sujet est que tous les paramètres que nous devons choisir ont leur propre valeur par défaut. Néanmoins, nous pouvons les changer si nous le voulons.
import pandas as pd
import numpy as np
import ta
df=pd.read_csv('Binance-ETHUSDT-22-04-2020')
df['timestamp']=pd.to_datetime(df['timestamp'],format='%Y-%m-%d %H:%M:%S')
df.set_index('timestamp',inplace=True)
df=df.astype(float)
df1 = ta.add_all_ta_features(
df, open="open", high="high", low="low", close="close", volume="volume")
Les commerçants sont la compréhension de l’entreprise, et si nous basons notre modèle uniquement sur l’analyse technique – cela pourrait refléter des nouvelles – nous devons connaître les indicateurs!. Mais comme je vous l’ai déjà dit, ces gens ont tellement de mal à les contextualiser pour définir des stratégies, qu’ils finissent par acquérir l’intuition des combinaisons. Notre travail consiste à transformer cette intuition en mathématiques!.
À titre d’exemple, je veux vous parler de la divergence de convergence moyenne mobile (MACD) indicateur. C’est l’un des plus communs et largement répandu entre les commerçants. MACD est calculé en soustrayant une moyenne mobile exponentielle à long terme (EMA) à partir d’une EMA à court terme. Après cela, vous créez une «ligne de signal», qui est un EMA du MACD. Les paramètres les plus utilisés sont 26, 12 et 9, respectivement.
En utilisant mplfinance vous pouvez réaliser des visualisations comme celles utilisées par les commerçants. Ci-dessus, vous pouvez voir un OHLC habituel chandelier sur le panneau principal. Dans le panneau inférieur, nous avons deux choses en cours, le volume sur l’histogramme et les indicateurs représentés par une ligne pointillée (MACD sur gris et MACD_signal sur cyan).
Vous pourriez être confus car la représentation habituelle consiste à utiliser la différence entre les deux MACD pour créer l’histogramme. Mais ne vous sentez pas perdu! L’histogramme est le le volume. Je maximise simplement la quantité d’informations dans le graphique (nous n’avons pas besoin d’un histogramme avec les informations contenues sur les lignes, n’est-ce pas?).
Ok, des indicateurs sympas, des visualisations sympas, mais comment les utiliser? C’est la partie où nous devons essayer certaines stratégies. Avec notre science des données, la connaissance serait-elle suffisante? Voyons ça! La section ci-dessous est pour vous donner un certain contexte des variables. J’ai séparé les indicateurs dans certains bacs. Nous pouvons vérifier si les valeurs à elles seules nous donnent un indice d’un résultat positif ou négatif dans ces fourchettes.
Il semble y avoir une probabilité plus élevée de résultat positif sur les bacs du côté gauche et négatif sur la droite. Mais rien ne semble être un système pare-balles.
Il est temps de former notre premier modèle! Disons que nous pensons que le résultat ne dépend que des trois mesures que nous venons de voir (évidemment pas), mais nous pouvons toujours entraîner notre modèle et voir comment cela se passe. Premièrement, nous équilibrerons les résultats positifs et négatifs et transformerons nos variables en utilisant notre bien-aimé StandardScaler. Les données d’entraînement seront utilisées jusqu’au 1er février 2020. Le reste sera utilisé pour tester les résultats.
Note technique: «Initial» sera la trame de données avec les indicateurs avant février, et «indicateur» est la trame de données entière, mais avec la [120245:] ce ne sont que les données de test.
Initial = Initial.sample(frac=1)
X_train = Initial[["trend_macd", "trend_macd_signal", "trend_macd_diff"]]
y_train = np.where(Initial["Outcome"] == "+0.5%", 1, 0)
X_test = indicator[120245:][["trend_macd", "trend_macd_signal", "trend_macd_diff"]]
y_test = np.where(indicator[120245:]["Outcome"] == "+0.5%", 1, 0)
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)Classifier1 = RandomForestClassifier(
max_depth=2,
min_samples_leaf=400,
max_features=2,
min_samples_split=4,
n_estimators=1000,
random_state=28,
)
Classifier1 = Classifier1.fit(X_train, y_train)
y_pred1 = Classifier1.predict(X_test)confusion_matrix(y_test, y_pred1)
Les nombres verticaux représentent le résultat réel et les horizontaux, la prédiction. Par exemple, dans ce cas, nous avons prédit 9 505 résultats positifs, et 53,8% d’entre eux ont été prédits correctement. Il y a quelques petits problèmes pour attribuer correctement les mauvais résultats, mais nous pouvons oublier cela pendant un certain temps.
Vous souvenez-vous de tout le prélude dans lequel nous avons parlé du retour attendu? Il est maintenant temps de l’utiliser!. Nous pouvons utiliser Predict_Proba pour prendre la probabilité d’un résultat positif. Le graphique ci-dessous montre la probabilité de succès pour un certain P (p), dans ce cas, nous savons que P (p)> 0,5 = 0,538. La théorie dit que plus la prédiction_proba est élevée, plus nos chances de gagner seront élevées.
Au-dessus de chaque rectangle, vous pouvez voir le nombre de cas où cette condition a été remplie. Une probabilité plus élevée implique moins de cas. Mais dans l’ensemble, nous avons trouvé ce que nous attendions! Plus le P (p) est grand, plus le taux de réussite est élevé. Si nous utilisons la stratégie pour aller à chaque fois que P (p)> 0,6, nous nous retrouverons avec 131 entrées correctes de 235 !.
Il existe différentes façons d’utiliser chaque indicateur, en fonction de l’opérateur avec lequel vous parlez. Mais, il y a un sujet où il y a un certain consensus. L’accord est qu’un signal pour entrer est lorsque le MACD passe au-dessus de la ligne de signal et, le dernier, est en dessous de zéro. Si vous allez plus loin, ils vous diront également que ce n’est qu’un signal d’entrée, si le marché évolue dans le même sens que le signal.
Il existe également plusieurs façons de vérifier si un marché a une tendance, nous nous y accrocherons. Comparaison d’un EMA de 200 périodes avec le prix de clôture. Si le prix est supérieur à l’EMA, nous considérerons qu’il s’agit d’une tendance haussière. Pour les mêmes données de test, il s’agit d’un simple filtre sur le nombre de cas où ces trois conditions sont remplies.
Pour rendre cela un peu difficile, je vais vous montrer les 4 premiers jours (pas plus pour la taille GIF) de nos données de test. Ci-dessous, vous pouvez voir deux nouvelles choses. La première est la ligne rouge en pointillés EMA de 200 périodes. L’autre nouveauté est que je marquerai les points d’entrée, uniquement s’ils remplissent toutes les conditions (en rouge si le trade a un résultat négatif, et en vert si c’est positif).
Ce – pas si bon – 4 jours reflète ce qui finit par se produire dans toute la période. 204 fois les conditions ont été remplies, 97 avec des résultats positifs. Ce n’est pas ce que nous attendions, mais nous ne devons pas oublier que ce ne sont que des règles rigides. Dans la section suivante, nous approfondirons l’esprit de cette stratégie.
D’accord, notre approximation a donné des résultats décents, et le bot commercial n’est pas si bon. Mais si nous voulons investir avec des frais réels, ces résultats ne suffisent pas. Pouvons-nous améliorer cela? Voilà pourquoi nous sommes ici! Notre travail consiste à comprendre ce qui se passe, peut-être que si nous prenons une pause pour réfléchir, nos résultats augmenteront.
Quelle était l’intuition derrière les règles? Certains commerçants m’ont dit que la raison de s’attendre à ce que le signal MACD soit derrière la ligne zéro était parce qu’ils s’attendaient à un croisement avec une pente plus élevée. Donc, peut-être que si nous incorporons une variable qui reflète la force de la MACD, nous pourrions avoir de meilleurs résultats.
Ceci peut être réalisé en ajoutant comme variable la différence entre l’indicateur et les périodes les plus récentes. Pour refléter cela, nous utiliserons une méthode de décalage pour soustraire la valeur réelle par rapport à 1, 3 et 5 périodes précédentes. Mais ces concepts pourraient s’appliquer aux 2 autres composants. Nous allons donc le faire pour chaque variable. Cela nous donnera 9 variables supplémentaires, leur tâche sera de refléter d’où viennent ces indicateurs.
En outre, nous pouvons comprendre que la tendance est également importante, mais il n’est peut-être pas nécessaire de l’utiliser comme variable binaire. Au lieu de cela, nous pouvons le calculer en soustrayant le 200-EMA au prix de clôture, puis le diviser par le prix de clôture pour avoir une différence en pourcentage entre eux. Voyons ce qui se passe!
indicator['trend_macd_diff1']=indicator['trend_macd_diff']-indicator['trend_macd_diff'].shift(1)
indicator['trend_macd_diff3']=indicator['trend_macd_diff']-indicator['trend_macd_diff'].shift(3)
indicator['trend_macd_diff5']=indicator['trend_macd_diff']-indicator['trend_macd_diff'].shift(5)
indicator['trend_macd_signal1']=indicator['trend_macd_signal']-indicator['trend_macd_signal'].shift(1)
indicator['trend_macd_signal3']=indicator['trend_macd_signal']-indicator['trend_macd_signal'].shift(3)
indicator['trend_macd_signal5']=indicator['trend_macd_signal']-indicator['trend_macd_signal'].shift(5)
indicator['trend_macd1']=indicator['trend_macd']-indicator['trend_macd'].shift(1)
indicator['trend_macd3']=indicator['trend_macd']-indicator['trend_macd'].shift(3)
indicator['trend_macd5']=indicator['trend_macd']-indicator['trend_macd'].shift(5)
indicator['trend']=(indicator['200MA']-indicator['Close'])/indicator['Close']
Initial = Initial.sample(frac=1)
X_train = Initial[
[
"trend_macd",
"trend_macd_signal",
"trend_macd_diff",
"trend_macd_diff1",
"trend_macd_diff3",
"trend_macd_diff5",
"trend_macd_signal1",
"trend_macd_signal3",
"trend_macd_signal5",
"trend_macd1",
"trend_macd3",
"trend_macd5",
"trend",
]
]
y_train = np.where(Initial["Outcome"] == "+0.5%", 1, 0)
X_test = indicator[120245:][
[
"trend_macd",
"trend_macd_signal",
"trend_macd_diff",
"trend_macd_diff1",
"trend_macd_diff3",
"trend_macd_diff5",
"trend_macd_signal1",
"trend_macd_signal3",
"trend_macd_signal5",
"trend_macd1",
"trend_macd3",
"trend_macd5",
"trend",
]
]
y_test = np.where(indicator[120245:]["Outcome"] == "+0.5%", 1, 0)
from sklearn.preprocessing import StandardScalersc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
from sklearn.ensemble import RandomForestClassifierClassifier = RandomForestClassifier(
max_depth=11,
min_samples_leaf=400,
max_features=11,
min_samples_split=4,
n_estimators=500,
random_state=28,
)
Classifier.fit(X_train, y_train)
y_pred = Classifier.predict(X_test)from sklearn.metrics import confusion_matrixconfusion_matrix(y_test, y_pred, normalize="true")
Ouais, il semble faire mieux sur les résultats négatifs, mais pour les positifs, nous avons juste eu une performance légèrement meilleure (53,98% de vrais positifs). Mmhh… ça pourrait être décourageant, mais bon! N’abandonnez pas avant même de regarder le graphique P (p). Peut-être nous apporte de bonnes nouvelles, qui sait?
Je le savais!! Ce barplot arrive pour sauver la journée!. Comme prévu, le taux de réussite a augmenté sur chaque barre! On peut lire que ce modèle est une nette amélioration par rapport au premier que nous avons fait. Pourquoi? Parce qu’il permet de mieux séparer les cas sur lesquels la probabilité de prendre l’entrée, a un meilleur taux de réussite.
Disons que nous choisissons notre stratégie: acheter chaque fois que le P (p)> 0,62. Notre plan aurait été une bombe! Nous avons reçu 188 signaux, dont 124 ont réussi (65,95% d’efficacité). La chose importante à ce sujet est que nous parvenons à nous retrouver avec une bonne stratégie, en utilisant tout ce que nous avons appris!. Ok, je vais me détendre, trop d’excitation pour aujourd’hui.
Nous y parvenons, en utilisant un seul indicateur! C’est prometteur si nous pensons que les modèles peuvent intégrer d’autres indicateurs essentiels avec différents concepts, comme le volume ou la volatilité. Mais ce gars, c’est une histoire entièrement différente.