Es ist ein Traum, den jeder hat. (Vielleicht nur ich)
** Dieses Mal haben wir ein Klassifizierungsmodell erstellt, das vorhersagt, ob der Dollar-Yen-Kurs in einem zufälligen Wald steigen, fallen oder gleich bleiben wird. ** **.
Warum haben Sie zunächst das Klassifizierungsmodell (dh die ternäre Klassifizierung, ob die Rate steigt, fällt oder gleich bleibt) anstelle des Regressionsmodells (dh des Modells, das die Rate mit Don Pisha schätzt) gewählt? Es gibt verschiedene Gründe.
・ Die Bewertung des Klassifizierungsmodells ist intuitiver als das Regressionsmodell (diesmal wurde die Verwirrungsmatrix berechnet). ・ Es gibt nur drei Aktionen, die Menschen tatsächlich in fx ausführen (kaufen, verkaufen, nichts tun). Ist das nicht gut für die Klassifizierung? ・ Zufälliger Wald Ich wollte ihn nur implementieren.
Deshalb habe ich mich für die Klassifizierungsvorhersage entschieden.
(Wenn Sie später darüber nachdenken, ist das Transaktionsvolumen auch im Transithandel wichtig. Da die spezifische Rate bei der Bestimmung des Transaktionsvolumens wichtig ist, frage ich mich, ob ein Regressionsmodell, das die Rate genau vorhersagen kann, besser war Ich frage mich. Ich werde es beim nächsten Mal erneut versuchen.)
Was soll ich mit dem Funktionsbetrag tun, wenn ich ein Ratenvorhersagemodell für fx einrichte? Wenn Sie dann darüber nachdenken, was Menschen tatsächlich verwenden, um Dollar und Yen zu kaufen und zu verkaufen, kann Ihnen die Menge an Funktionen in den Sinn kommen.
Die Analyse, die Menschen beim Handel mit FX durchführen, ist grob in technische Analyse und Fundamentalanalyse unterteilt. Die technische Analyse dient dazu, Preisbewegungen anhand sogenannter Charts vorherzusagen. Andererseits besteht die Fundamentalanalyse darin, Preisbewegungen aus Nachrichten und Weltgeschehen vorherzusagen.
Dieses Mal werden wir technische Analysen verwenden, die als Merkmal des maschinellen Lernens leicht zu integrieren sind. Der Grund für den einfachen Import liegt darin, dass sich die technische Analyse nur mit Zahlen befasst und einfach zu programmieren ist.
Auf der anderen Seite ist es schwierig, Grundlagen (wie z. B. Text Mining) zu integrieren, und Grundlagen werden häufig für den Kauf und Verkauf aus einer langfristigen Perspektive verwendet, sodass wir sie nicht verwenden.
Nachdem die Richtlinie festgelegt wurde, suchen wir nach einem Datensatz. Dieses Mal haben wir die täglichen Daten der letzten 20 Jahre unter investieren.com verwendet. Es können ca. 250 Tage (FX-Transaktionen nur an Wochentagen) x 20 Jahre bis 5000 Daten erfasst werden.
import pandas as pd
df = pd.read_csv("USD_JPY.csv")
Wie oben erwähnt, verwenden wir diesmal den numerischen Wert der technischen Analyse als Merkmalsgröße. Insbesondere habe ich fünf der SMA5-, SMA20-, RSI14-, MACD- und Bollinger-Bänder (2σ) verwendet. Bitte googeln Sie für die detaillierten Funktionen der einzelnen technischen Indikatoren. ** Bei der Auswahl eines technischen Index, der als Merkmalsgröße verwendet werden soll, ist es jedoch wichtig, nicht statistisch zu analysieren, sondern Multico (multiple Co-Linearität) so weit wie möglich zu vermeiden, so technisch, dass nicht so viel wie möglich miteinander korreliert wird. Bitte wählen Sie einen Index. ** **.
Verwenden Sie für die Berechnung technischer Indikatoren eine Bibliothek namens talib, was äußerst praktisch ist. Der technische Index wird auf einmal berechnet.
Hier werden die technischen Werte wie für RSI und MACD verwendet, die Werte für SMA und Bollinger-Band jedoch nicht. (Selbst wenn der SMA-Wert 105 ist, ist er beispielsweise nicht als Merkmalsgröße geeignet, da nicht bekannt ist, ob der Wert von 105 so hoch oder niedrig ist.) Daher werden wir die Werte von SMA und Bollinger-Band durch den Wert von close dividieren, um sie in relative und vergleichbare Werte umzuwandeln, bevor wir sie als Merkmalsgrößen verwenden.
Ich denke, es gibt viele andere Möglichkeiten, dies zu tun. Probieren Sie also die aus, die Ihnen am besten gefallen!
import talib as ta
import numpy as np
#Verwenden Sie die Schlussrate für alle nachfolgenden Berechnungen
close = np.array(df["Schlusskurs"])
#Erstellen Sie einen leeren Datenrahmen, um die Features zu platzieren
df_feature = pd.DataFrame(index=range(len(df)),columns=["SMA5/current", "SMA20/current","RSI","MACD","BBANDS+2σ","BBANDS-2σ"])
#Im Folgenden wird der technische Index (in diesem Lernprogramm verwendete Merkmalsmenge) mit talib und df berechnet_Feature Feature
#Der einfache gleitende Durchschnitt verwendet das Verhältnis des einfachen gleitenden Durchschnittswerts zum Schlusskurs des Tages als Merkmalsgröße.
df_feature["SMA5/current"]= ta.SMA(close, timeperiod=5) / close
df_feature["SMA20/current"]= ta.SMA(close, timeperiod=20) / close
#RSI
df_feature["RSI"] = ta.RSI(close, timeperiod=14)
#MACD
df_feature["MACD"], _ , _= ta.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
#Bollinger Band
upper, middle, lower = ta.BBANDS(close, timeperiod=20, nbdevup=3, nbdevdn=3)
df_feature["BBANDS+2σ"] = upper / close
df_feature["BBANDS-2σ"] = lower / close
Wie oben erwähnt, sind die Lehrerdaten für dieses Modell die drei Werte [hoch, runter und (fast) unverändert]. Daher werden Lehrerdaten unter Verwendung des oben angegebenen Verhältnisses in den von [investing.com] heruntergeladenen Daten (https://jp.investing.com/currencies/usd-jpy-historical-data) erstellt.
Die spezifischen Funktionen, die zum Erstellen verwendet werden, sind wie folgt.
def classify(x):
#Im Vergleich zum Vortag-0.2%Gruppe 0 wenn
if x <= -0.2:
return 0
#Im Vergleich zum Vortag ist 0.2%<x<0.2%Dann Gruppe 1
elif -0.2 < x < 0.2:
return 1
#Im Vergleich zum Vortag ist 0.2%Gruppe 2 oben
elif 0.2 <= x:
return 2
Warum haben Sie den Vortag durch -0,2% und 0,2% geteilt?
・ 100 (Yen / Dollar) x 0,002 = 0,2 (Yen / Dollar) = 20 Pips, und ich dachte, dass dieser Wert als Wert geeignet ist, um zu beurteilen, ob sich der Kurs bewegt. ** ・ Durch Aufteilung des Vortages in drei Gruppen von -0,2% und 0,2% werden die Daten fast vorerst vorliegen. (Abbildung unten) **
Von links ist dies die Anzahl der Daten in Gruppe 0, Gruppe 1 und Gruppe 2. Es ist fast gleichmäßig aufgeteilt. Es ist sehr wichtig, eine zufällige Gesamtstruktur zu verwenden, damit die Klassen der Lehrerdaten gleichmäßig aufgeteilt werden. (Natürlich können Sie dies auch tun, wenn die Klassen nicht gleichmäßig verteilt sind, aber Sie müssen sie gewichten. Weitere Informationen finden Sie unter Dieser Artikel. .)
Beachten Sie die obigen Punkte und erstellen Sie Lehrerdaten.
df["Der Tag vor Verhältnis_float"] = df["Der Tag vor Verhältnis%"].apply(lambda x: float(x.replace("%", "")))
#Der Tag vor Verhältnis%Wie zu klassifizieren. Teilen Sie die Stichproben jeder Klasse so gleich wie möglich
def classify(x):
if x <= -0.2:
return 0
elif -0.2 < x < 0.2:
return 1
elif 0.2 <= x:
return 2
df["Der Tag vor Verhältnis_classified"] = df["Der Tag vor Verhältnis_float"].apply(lambda x: classify(x))
#Verschieben Sie die Daten, die Sie Lehrer werden möchten, um einen Tag (ich denke, Sie können es verstehen, wenn Sie über die Bedeutung nachdenken).
df_y = df["Der Tag vor Verhältnis_classified"].shift()
Mach ein wenig Verarbeitung. Wenn Sie beispielsweise SMA5 zur Berechnung des Funktionsbetrags verwenden, lautet der Wert für die ersten 4 Tage NaN. (Da für die Berechnung des 5-Tage-Durchschnitts Daten im Wert von mindestens 5 Tagen erforderlich sind) Wie Sie sehen können, ist NaN am Anfang der Feature-Daten enthalten, daher werden wir es entfernen.
df_xy = pd.concat([df_feature, df_y], axis=1)
df_xy = df_xy.dropna(how="any")
Damit ist die Vorverarbeitung abgeschlossen. Da diesmal eine zufällige Gesamtstruktur verwendet wird, ist keine Normalisierung / Standardisierung erforderlich.
Alles was Sie tun müssen, ist zu lernen. Es könnte interessant sein, zu experimentieren, indem Sie die Parameter des zufälligen Waldes ändern ... Die Hyperparameter der zufälligen Gesamtstruktur sind in diesem Artikel leicht zu verstehen.
Auch die Hyperparameter wurden mit optuna optimiert. Beachten Sie bei der Verwendung von optuna, dass die Zielfunktion so eingestellt ist, dass sie das zurückgibt, was Sie minimieren möchten.
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import optuna
X_train, X_test, Y_train, Y_test = train_test_split(df_xy[["SMA5/current", "SMA20/current","RSI","MACD","BBANDS+2σ","BBANDS-2σ"]],df_xy["Der Tag vor Verhältnis_classified"], train_size=0.8)
def objective(trial):
min_samples_split = trial.suggest_int("min_samples_split", 2,16)
max_leaf_nodes = int(trial.suggest_discrete_uniform("max_leaf_nodes", 4,64,4))
criterion = trial.suggest_categorical("criterion", ["gini", "entropy"])
n_estimators = int(trial.suggest_discrete_uniform("n_estimators", 50,500,50))
max_depth = trial.suggest_int("max_depth", 3,10)
clf = RandomForestClassifier(random_state=1, n_estimators = n_estimators, max_leaf_nodes = max_leaf_nodes, max_depth=max_depth, max_features=None,criterion=criterion,min_samples_split=min_samples_split)
clf.fit(X_train, Y_train)
return 1 - accuracy_score(Y_test, clf.predict(X_test))
study = optuna.create_study()
study.optimize(objective, n_trials=100)
print(1-study.best_value)
print(study.best_params)
Die Genauigkeit bei der Optimierung der Hyperparameter beträgt
0.6335025380710659 Da es sich um eine Drei-Werte-Klassifizierung handelt, halte ich es für ein recht gutes Ergebnis. Es ist ungefähr doppelt so gut wie wenn Sie es zufällig auswählen.
Wenn die Preisbewegung mit einer Wahrscheinlichkeit von 60% vorhergesagt wird, ist der erwartete Wert positiv, selbst wenn Sie den Spread berücksichtigen!
Betrachten Sie eine Verwirrungsmatrix für die Klassifizierung mehrerer Klassen!
Um mit Fx einen Gewinn zu erzielen, ist es wünschenswert, dass das Verhältnis von ① und ⑨ hoch ist. Betrachtet man die Verwirrungsmatrix, so ist 1 + 9 = 48,9%, was fast der Hälfte entspricht. Was Sie am meisten vermeiden möchten, sind die Muster ③ und ⑦ (das Muster, von dem Sie vorhergesagt haben, dass es steigt, aber tatsächlich sinkt, und das Muster, von dem Sie vorhergesagt haben, dass es sinkt, aber tatsächlich steigt). Diese beiden sind ziemlich niedrige Werte von ③ + ⑦ = 7,3%.
** Aus den obigen Überlegungen können wir ersehen, dass das diesmal erlernte Modell rentabel sein kann. ** **.
Auch der Hyperparameter bei maximaler Genauigkeit ist
{'min_samples_split': 8,
'max_leaf_nodes': 40.0,
'criterion': 'entropy',
'n_estimators': 310.0,
'max_depth': 7}
war. Die Beziehung zwischen Hyperparametern und Genauigkeit ist wie folgt.
(* Beachten Sie, dass subjektiver_Wert = 1 - Genauigkeit! (Optuna-Spezifikationen))
Die hellere Farbe in der obigen Abbildung ist die höhere Genauigkeit. Sicherlich kann gelesen werden, dass max_depth ungefähr 7 ist, max_leaf_nodes ungefähr 30-40 ist und n_estimators ungefähr 300 ist.
Bisher haben wir drei Werte klassifiziert, aber lassen Sie uns sie in zwei Werte klassifizieren: Ratenerhöhung oder -abnahme.
Ändern Sie nur die 3. Klassifizierungsfunktion für die Erstellung von Lehrerdaten.
def classify(x):
if x <= 0:
return 0
else:
return 1
Wenn Sie ein Modell auf die gleiche Weise erstellen und die Hyperparameter mit optuna optimieren ...
accuracy=0.7766497461928934
** Ich bin auch sehr reich damit (weiße Augen)! ** **.
Auf diese Weise kann es interessant sein, nicht nur die Datenaufteilungsmethode zu ändern, sondern auch mit den verwendeten technischen Indikatoren zu spielen!