Anwendung von Machine-Learning-Technologien im Handel

Schriftsteller:Gutes, Erstellt: 2019-08-29 09:42:00, Aktualisiert: 2023-10-19 21:02:44

img

Die Inspiration für diesen Artikel kam aus meiner Beobachtung einiger häufiger Warnungen und Fallen, nachdem ich während meiner Datenforschung an der Inventor Quantitative Platform versucht hatte, Maschinenlerntechnik auf Transaktionsprobleme anzuwenden.

Wenn Sie meinen früheren Artikel noch nicht gelesen haben, empfehlen wir Ihnen, vor diesem zu lesen: Mein Leitfaden für eine automatisierte Datenforschungsumgebung und eine systematische Methode zur Entwicklung von Handelsstrategien, die auf der Quantifizierungsplattform der Erfinder aufgebaut wurde.

Die Adresse ist hier:https://www.fmz.com/digest-topic/4187undhttps://www.fmz.com/digest-topic/4169 这两篇文章.

Über den Aufbau einer Forschungsumgebung

Dieses Tutorial ist für Amateure, Ingenieure und Datenwissenschaftler aller Fähigkeitsniveaus konzipiert. Egal, ob Sie ein Branchen-Bull oder ein Programmierer sind. Die einzigen Fähigkeiten, die Sie benötigen, sind ein grundlegendes Verständnis der Python-Programmiersprache und ausreichende Kenntnisse der Befehlszeile (wenn Sie ein Datenwissenschaft-Projekt einrichten können).

  • Installieren Sie die Erfinder-Quantifizierungs-Manager und installieren Sie Anaconda

发明者量化平台FMZ.COM除了提供优质的各大主流交易所的数据源,还提供一套丰富的API接口以帮助我们在完成数据的分析后进行自动化交易。这套接口包括查询账户信息,查询各个主流交易所的高,开,低,收价格,成交量,各种常用技术分析指标等实用工具,特别是对于实际交易过程中连接各大主流交易所的公共API接口,提供了强大的技术支持。

All diese Funktionen sind in einem Docker-ähnlichen System verpackt, und wir müssen nur unsere eigenen Cloud-Dienste kaufen oder leasen, um das Docker-System zu installieren.

In der offiziellen Bezeichnung der Quantifizierungsplattform der Erfinder wird das Docker-System als Host-System bezeichnet.

Über die Implementierung von Administratoren und Roboter lesen Sie in meinem früheren Artikel:https://www.fmz.com/bbs-topic/4140

Leser, die sich einen Cloud-Deployment-Manager kaufen möchten, können sich an diesen Artikel wenden:https://www.fmz.com/bbs-topic/2848

Nachdem wir einen guten Cloud-Dienst und ein gutes Administrator-System erfolgreich bereitgestellt haben, werden wir nun den größten Templar von Python installieren: Anaconda

Der einfachste Weg, um alle hierfür notwendigen Programmierumgebungen (Dependenzen, Versionsmanagement usw.) zu realisieren, ist Anaconda.

Da wir Anaconda auf einem Cloud-Service installieren, empfehlen wir, dass der Cloud-Server die Anaconda-Version für Linux-Systeme mit der Befehlszeile installiert.

Über die Installation von Anaconda lesen Sie im offiziellen Anaconda-Handbuch:https://www.anaconda.com/distribution/

Wenn Sie ein erfahrener Python-Programmierer sind und keine Notwendigkeit haben, Anaconda zu verwenden, dann ist das völlig in Ordnung.

Entwicklung von Handelsstrategien

Die endgültige Ausgabe der Handelsstrategie sollte folgende Fragen beantworten:

  • Orientierung: Feststellen, ob ein Asset billig, teuer oder fair ist.

  • 开仓条件:如果资产价格便宜或者昂贵,你应该做多或者做空.

  • Verbriefung: Sollten Sie verbriefen, wenn der Preis des Vermögenswertes angemessen ist und wir eine Position in diesem Vermögenswert (vorheriges Kauf oder Verkauf) halten?

  • Preisspektrum: Preis (oder Bereich), bei dem ein Börsengeschäft durchgeführt wird

  • Quantität: Anzahl der Transaktionsmittel (z. B. Anzahl der digitalen Währungen oder Anzahl der Hände an Kommoditäts-Futures)

Maschinelles Lernen kann zur Beantwortung jeder dieser Fragen verwendet werden, aber für den Rest dieses Artikels werden wir uns auf die Beantwortung der ersten Frage konzentrieren, nämlich die Handelsrichtung.

Strategische Methoden

Es gibt zwei Arten von Methoden, eine ist modelbasiert, die andere ist datenbasiert. Die beiden sind grundsätzlich gegensätzliche Methoden.

Bei der modellbasierten Strategiegestaltung beginnt man mit einem Markt-Low-Efficiency-Modell, das mathematische Ausdrücke (z. B. Preis, Ertrag) konstruiert und ihre Wirksamkeit über längere Zeiträume testet. Das Modell ist oft eine vereinfachte Version eines wirklich komplexen Modells, dessen Bedeutung und Stabilität über längere Zeiträume überprüft werden muss.

Auf der anderen Seite suchen wir zuerst nach Preismustern und versuchen, Algorithmen in Datenmining-Methoden zu verwenden. Die Ursachen für diese Muster sind unwichtig, da sich nur bestimmte Muster in Zukunft wiederholen werden. Dies ist eine blinde Analysemethode, bei der wir eine strenge Prüfung benötigen, um echte Muster aus den zufälligen Modellen zu erkennen.

Es ist offensichtlich, dass maschinelles Lernen leicht für Methoden der Datenmining angewendet werden kann. Lassen Sie uns sehen, wie maschinelles Lernen benutzt wird, um Handelssignale durch Datenmining zu erzeugen.

Die Code-Beispiele verwenden die auf der Erfinder-Quantifizierung-Plattform basierenden Retrieval-Tools und die automatische Transaktions-API-Schnittstelle. Nach der Einführung des Hosts und der Installation von Anaconda in den oben genannten Abschnitten müssen Sie nur die Datenwissenschaftsanalytik und das bekannte Machine-Learning-Modell scikit-learn installieren.

pip install -U scikit-learn

Technische Signalgestaltung mit Hilfe von Machine Learning

  • Datenentdeckung

Bevor wir anfangen, ist ein Standard-Maschinenlernproblemsystem wie folgt dargestellt:

img

Maschinelles Lernen Problemsystem

Die Eigenschaften, die wir erstellen wollen, müssen eine gewisse Vorhersagekraft haben (x), wir wollen die Zielvariablen (y) vorhersagen und mit historischen Daten ein ML-Modell trainieren, das Y so nahe wie möglich an den tatsächlichen Werten vorhersagen kann.

Schritt 1: Stellen Sie Ihre Probleme fest.

  • Was möchten Sie prognostizieren? Was sind gute Prognosen? Wie bewerten Sie die Ergebnisse?

Das heißt, in unserem Rahmen oben, was ist Y?

img

Was wollen Sie vorhersagen?

Möchten Sie zukünftige Preise, zukünftige Rendite/Pnl, Kauf/Verkauf-Signale, Optimierung der Portfolioverteilung und Effizienz bei der Handelsausführung prognostizieren?

Nehmen wir an, wir versuchen, den Preis auf der nächsten Zeitscheibe vorherzusagen. In diesem Fall ist Y ((t) = Preis ((t + 1)).

Beachten Sie, dass Y (t) nur in der Rücksichtnahme bekannt ist, aber wenn wir unser Modell verwenden, werden wir den Preis für die Zeit t (t + 1) nicht wissen. Wir verwenden unser Modell, um Y (t) zu prognostizieren, und vergleichen es nur mit dem tatsächlichen Wert in der Zeit t + 1. Das bedeutet, dass Sie Y nicht als Eigenschaft im Prognosemodell verwenden können.

Sobald wir das Ziel Y kennen, können wir auch entscheiden, wie wir unsere Vorhersagen bewerten. Dies ist wichtig, um die verschiedenen Modelle zu unterscheiden, mit denen wir Daten ausprobieren werden. Entsprechend dem Problem, das wir lösen, wählen wir ein Indikator, das die Effizienz unseres Modells misst. Wenn wir zum Beispiel Preise prognostizieren, können wir die Quadratwurzelfehler als Indikator verwenden.

img

ML-Framework zur Vorhersage von zukünftigen Preisen

Um das zu demonstrieren, werden wir ein Prognosemodell erstellen, um den zukünftigen erwarteten Benchmarkwert einer hypothetischen Anlage zu prognostizieren, bei der:

basis = Price of Stock — Price of Future

basis(t)=S(t)−F(t)

Y(t) = future expected value of basis = Average(basis(t+1),basis(t+2),basis(t+3),basis(t+4),basis(t+5))

Da es sich um eine Regressionsfrage handelt, werden wir das Modell auf RMSE (Gemeinschaftswurzelfehler) bewerten. Wir werden auch Total Pnl als Bewertungskriterium verwenden.

Hinweis: Für die mathematische Kenntnis von RMSE, lesen Sie die entsprechenden Informationen in der Enzyklopädie

  • 我们的目标:创建一个模型,使预测值尽可能接近Y.

Zweiter Schritt: Zuverlässige Daten sammeln

Sammeln und bereinigen von Daten, die Ihnen helfen, Probleme zu lösen

Wenn wir einen Preis prognostizieren, können Sie die Preisdaten der Anlage, die Handelsvolumendaten der Anlage, ähnliche Daten der entsprechenden Anlage, die Indexparität der Anlage, die Gesamtmarktindikatoren, die Preise anderer entsprechender Vermögenswerte usw. verwenden.

Dazu müssen Sie Datenzugriffsrechte einstellen und sicherstellen, dass Ihre Daten korrekt sind und fehlende Daten (sehr häufige Probleme) beheben. Sie müssen auch sicherstellen, dass Ihre Daten unvoreingenommen sind und alle Marktbedingungen (z. B. die gleiche Anzahl von Szenarien für Gewinn und Verlust) vollständig repräsentieren, um Modellfehler zu vermeiden.

Wenn Sie die Quantifizierungsplattform der Erfinder nutzen, dannFMZ.COMWir haben Zugang zu kostenlosen globalen Daten von Google, Yahoo, NSE und Quandl; tiefgreifende Daten von inländischen Commodity-Futures wie CTP und EOS; und Daten von Mainstream-Digital-Currency-Exchanges wie Binance, OKEX, Huobi und BitMex.

Um die Demonstration zu erleichtern, verwenden wir die folgenden Daten für die Auquan MQK-Kerns der virtuellen Investitionsmarke, und wir verwenden ein sehr praktisches Quantifizierungs-Tool namens Auquan Kerns Toolbox, um mehr zu erfahren:https://github.com/Auquan/auquan-toolbox-python

# Load the data
from backtester.dataSource.quant_quest_data_source import QuantQuestDataSource
cachedFolderName = '/Users/chandinijain/Auquan/qq2solver-data/historicalData/'
dataSetId = 'trainingData1'
instrumentIds = ['MQK']
ds = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
def loadData(ds):
    data = None
    for key in ds.getBookDataByFeature().keys():
        if data is None:
            data = pd.DataFrame(np.nan, index = ds.getBookDataByFeature()[key].index, columns=[])
        data[key] = ds.getBookDataByFeature()[key]
    data['Stock Price'] =  ds.getBookDataByFeature()['stockTopBidPrice'] + ds.getBookDataByFeature()['stockTopAskPrice'] / 2.0
    data['Future Price'] = ds.getBookDataByFeature()['futureTopBidPrice'] + ds.getBookDataByFeature()['futureTopAskPrice'] / 2.0
    data['Y(Target)'] = ds.getBookDataByFeature()['basis'].shift(-5)
    del data['benchmark_score']
    del data['FairValue']
    return data
data = loadData(ds)

Mit dem oben genannten Code hat Auquans Toolbox die Daten heruntergeladen und in das Datenstück-Wörterbuch geladen. Jetzt müssen wir die Daten in unserem bevorzugten Format bereitstellen. Die Funktion ds.getBookDataByFeature (,) gibt das Datenstück-Wörterbuch zurück, wobei jede Eigenschaft eine Datenstück ist.

Schritt 3: Daten aufteilen

  • Erstellen von Trainingssets aus Daten, cross-verifisieren und testen diese Daten

Das ist ein wichtiger Schritt!Bevor wir weitermachen, sollten wir die Daten in Trainingsdatensätze aufteilen, um Ihr Modell zu trainieren; Testdatensätze, um die Modellleistung zu bewerten.

img

Daten in Trainings- und Testsätze aufteilen

Da die Trainingsdaten für die Bewertung von Modellparametern verwendet werden, kann es sein, dass Ihr Modell diese Trainingsdaten zu sehr anpasst, und die Trainingsdaten können die Modellleistung irreführen. Wenn Sie keine einzelnen Testdaten behalten und mit allen Daten trainieren, werden Sie nicht wissen, wie gut oder schlecht Ihr Modell auf neue, unsichtbare Daten abschneidet. Dies ist einer der Hauptgründe, warum trainierte ML-Modelle mit Real-Time-Daten scheitern: Menschen trainieren alle verfügbaren Daten und sind begeistert von den Trainingsdatenindikatoren, aber das Modell kann keine sinnvollen Vorhersagen aus untrainierten Real-Time-Daten machen.

img

Daten in Trainings-, Validierungs- und Testsätze aufteilen

Diese Methode ist problematisch. Wenn wir die Trainingsdaten wiederholt trainieren, die Leistung der Testdaten bewerten und unser Modell optimieren, bis wir mit der Leistung zufrieden sind, werden wir die Testdaten implizit als Teil der Trainingsdaten betrachten. Schließlich kann unser Modell für diese Gruppe von Trainings- und Testdaten gut funktionieren, aber es kann nicht garantiert werden, dass es die neuen Daten gut prognostiziert.

Um dieses Problem zu lösen, können wir ein separates Verifikationsdatensatz erstellen. Jetzt können Sie die Daten trainieren, die Leistung der Verifikationsdaten bewerten, optimieren, bis Sie mit der Leistung zufrieden sind, und schließlich die Testdaten testen.

Denken Sie daran, dass Sie nach Prüfung der Leistung der Testdaten nicht zurückkehren und versuchen, das Modell weiter zu optimieren. Wenn Sie feststellen, dass Ihr Modell nicht gut funktioniert, werfen Sie das Modell vollständig ab und fangen Sie neu an. Es wird empfohlen, 60% der Trainingsdaten, 20% der Verifizierungsdaten und 20% der Testdaten aufzuteilen.

Für unser Problem haben wir drei Datenmengen zur Verfügung, von denen wir eine als Trainingsmenge verwenden werden, die zweite als Verifikationsmenge und die dritte als unsere Testmenge.

# Training Data
dataSetId =  'trainingData1'
ds_training = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
training_data = loadData(ds_training)
# Validation Data
dataSetId =  'trainingData2'
ds_validation = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
validation_data = loadData(ds_validation)
# Test Data
dataSetId =  'trainingData3'
ds_test = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
out_of_sample_test_data = loadData(ds_test)

Für jede dieser Werte fügen wir die Zielvariable Y hinzu, definiert als das Durchschnitt der nächsten fünf Basiswerte.

def prepareData(data, period):
    data['Y(Target)'] = data['basis'].rolling(period).mean().shift(-period)
    if 'FairValue' in data.columns:
        del data['FairValue']
    data.dropna(inplace=True)
period = 5
prepareData(training_data, period)
prepareData(validation_data, period)
prepareData(out_of_sample_test_data, period)

Schritt vier: Charakteristik

Verhalten der Daten analysieren und prädiktive Merkmale erstellen

Jetzt beginnt die echte Konstruktion. Die goldene Regel der Merkmalwahl ist, dass die Vorhersage der Fähigkeit hauptsächlich aus den Merkmalen und nicht aus dem Modell stammt. Sie werden feststellen, dass die Auswahl der Merkmale einen weitaus größeren Einfluss auf die Leistung hat als die Auswahl des Modells.

  • Wählen Sie nicht zufällig eine große Anzahl von Merkmalen aus, ohne die Beziehung zu den Zielvariablen zu erforschen.

  • Wenige oder gar keine Beziehungen zu Zielvariablen können zu einer Überanpassung führen.

  • Die Merkmale, die Sie wählen, können sehr stark miteinander verknüpft sein, und in diesem Fall können auch eine kleinere Anzahl von Merkmalen die Ziele erklären.

  • Ich erstelle normalerweise einige intuitive Eigenschaften, um zu sehen, wie die Zielvariablen mit diesen Eigenschaften zusammenhängen und wie sie zusammenhängen, um zu entscheiden, welche Eigenschaften verwendet werden sollen.

  • Sie können auch versuchen, Kandidatencharakteristiken nach den größten Informationskoeffizienten (MIC) zu sortieren, eine Hauptbestandteilsanalyse (PCA) und andere Methoden durchzuführen

Die Transformation von Merkmalen / Normung:

ML-Modelle sind oft gut bei der Standardisierung. Regulierung ist jedoch schwierig, wenn es um Zeitreihen-Daten geht, da die zukünftige Datenreichweite unbekannt ist. Ihre Daten können über die Standardisierung hinausgehen und zu Modellfehlern führen.

  • Vergrößerung: Eigenschaften, die nach Standarddifferenz oder Vierstelligkeitsbereich aufgeteilt werden

  • Inhaber: historische Durchschnittswerte von den aktuellen abgezogen

  • Einheitlich: Zwei Rückschlüsse auf die obigen ((x - mean) / stdev

  • Regularisierung: Standardisierung der Daten in einem Bereich von -1 bis +1 und Wiederbestimmung des Zentrums in der Rücklaufzeit ((x-min) / ((max-min))

Beachten Sie, dass, da wir historische fortlaufende Durchschnitte, Standarddifferenzen, Maximalwerte oder Minimalwerte über die Rücklaufzeit hinweg verwenden, die standardisierten Werte der Eigenschaft zu einem bestimmten Zeitpunkt unterschiedliche tatsächliche Werte darstellen. Zum Beispiel, wenn der aktuelle Wert der Eigenschaft 5 ist, wird die 30-zehrliche Durchschnittswerte von 4,5 nach der Einhaltung auf 0,5 umgewandelt. Danach wird der Wert von 3.5 auf 0,5 umgewandelt, wenn die 30-zehrliche Durchschnittswerte auf 3 werden.

Für die erste Ideration in unserem Problem haben wir eine große Anzahl von Eigenschaften mit gemischten Parametern erstellt. Später werden wir versuchen zu sehen, ob die Anzahl der Eigenschaften reduziert werden kann.

def difference(dataDf, period):
    return dataDf.sub(dataDf.shift(period), fill_value=0)
def ewm(dataDf, halflife):
    return dataDf.ewm(halflife=halflife, ignore_na=False,
                      min_periods=0, adjust=True).mean()
def rsi(data, period):
    data_upside = data.sub(data.shift(1), fill_value=0)
    data_downside = data_upside.copy()
    data_downside[data_upside > 0] = 0
    data_upside[data_upside < 0] = 0
    avg_upside = data_upside.rolling(period).mean()
    avg_downside = - data_downside.rolling(period).mean()
    rsi = 100 - (100 * avg_downside / (avg_downside + avg_upside))
    rsi[avg_downside == 0] = 100
    rsi[(avg_downside == 0) & (avg_upside == 0)] = 0
return rsi
def create_features(data):
    basis_X = pd.DataFrame(index = data.index, columns =  [])
    
    basis_X['mom3'] = difference(data['basis'],4)
    basis_X['mom5'] = difference(data['basis'],6)
    basis_X['mom10'] = difference(data['basis'],11)
    
    basis_X['rsi15'] = rsi(data['basis'],15)
    basis_X['rsi10'] = rsi(data['basis'],10)
    
    basis_X['emabasis3'] = ewm(data['basis'],3)
    basis_X['emabasis5'] = ewm(data['basis'],5)
    basis_X['emabasis7'] = ewm(data['basis'],7)
    basis_X['emabasis10'] = ewm(data['basis'],10)
    basis_X['basis'] = data['basis']
    basis_X['vwapbasis'] = data['stockVWAP']-data['futureVWAP']
    
    basis_X['swidth'] = data['stockTopAskPrice'] -
                        data['stockTopBidPrice']
    basis_X['fwidth'] = data['futureTopAskPrice'] -
                        data['futureTopBidPrice']
    
    basis_X['btopask'] = data['stockTopAskPrice'] -
                         data['futureTopAskPrice']
    basis_X['btopbid'] = data['stockTopBidPrice'] -
                         data['futureTopBidPrice']

    basis_X['totalaskvol'] = data['stockTotalAskVol'] -
                             data['futureTotalAskVol']
    basis_X['totalbidvol'] = data['stockTotalBidVol'] -
                             data['futureTotalBidVol']
    
    basis_X['emabasisdi7'] = basis_X['emabasis7'] -
                             basis_X['emabasis5'] + 
                             basis_X['emabasis3']
    
    basis_X = basis_X.fillna(0)
    
    basis_y = data['Y(Target)']
    basis_y.dropna(inplace=True)
    
    print("Any null data in y: %s, X: %s"
            %(basis_y.isnull().values.any(), 
             basis_X.isnull().values.any()))
    print("Length y: %s, X: %s"
            %(len(basis_y.index), len(basis_X.index)))
    
    return basis_X, basis_y
basis_X_train, basis_y_train = create_features(training_data)
basis_X_test, basis_y_test = create_features(validation_data)

Schritt 5: Modellwahl

Auswahl des geeigneten statistischen/ML-Modells für die ausgewählte Frage

Die Wahl des Modells hängt davon ab, wie das Problem aufgebaut wird. Bist du dabei, ein Überwachungsproblem zu lösen (jeder Punkt X in der Eigenschaftsmatrix wird auf die Zielvariable Y abgebildet) oder ein unbeaufsichtigtes Lernproblem (keine gegebene Abbildung, das Modell versucht, unbekannte Muster zu lernen)? Bist du dabei, eine Regression zu lösen (wirkliche Preise in Zukunft prognostizieren) oder ein Klassifizierungsproblem (nur die Preisrichtung in Zukunft prognostizieren) (zu erhöhen/zu verringern)).

img

Überwacht oder unbeaufsichtigt lernen

img

Zurückgehen or Kategorisieren

Einige der gängigen Algorithmen für das überwachte Lernen können Ihnen helfen:

  • Lineare Regression (Parameter, Regression)

  • Logistic Regression (Parameter, Klassifizierung)

  • K-Nachbarschaft (KNN) Algorithmen (Beispiel-basiert, Regression)

  • SVM, SVR (Parameter, Klassifizierung und Regression)

  • Entscheidungsbaum

  • Die Entscheidungshölzer

Ich empfehle, mit einem einfachen Modell zu beginnen, wie z.B. einer linearen oder logischen Regression, und von dort aus nach Bedarf ein komplexeres Modell zu bauen. Ich empfehle auch, dass Sie die Mathematik hinter dem Modell lesen, anstatt es blind wie eine schwarze Box zu verwenden.

Schritt 6: Trainieren, überprüfen und optimieren (siehe Schritte 4-6 wiederholt)

img

Trainieren und optimieren Sie Ihr Modell mit Trainings- und Validierungsdatensätzen

Jetzt sind Sie bereit, das Modell zu bauen. In dieser Phase wiederholen Sie das Modell und die Modellparameter. Trainieren Sie Ihr Modell mit den Trainingsdaten, messen Sie seine Leistung mit den Verifizierungsdaten und gehen Sie dann zurück, optimieren, trainieren und bewerten Sie es.

Nur wenn Sie ein Modell haben, das Ihnen gefällt, können Sie mit dem nächsten Schritt fortfahren.

Also für unsere Demonstrationsproblematik, fangen wir mit einer einfachen linearen Regression an.

from sklearn import linear_model
from sklearn.metrics import mean_squared_error, r2_score
def linear_regression(basis_X_train, basis_y_train,
                      basis_X_test,basis_y_test):
    
    regr = linear_model.LinearRegression()
    # Train the model using the training sets
    regr.fit(basis_X_train, basis_y_train)
    # Make predictions using the testing set
    basis_y_pred = regr.predict(basis_X_test)
    # The coefficients
    print('Coefficients: \n', regr.coef_)
    
    # The mean squared error
    print("Mean squared error: %.2f"
          % mean_squared_error(basis_y_test, basis_y_pred))
    
    # Explained variance score: 1 is perfect prediction
    print('Variance score: %.2f' % r2_score(basis_y_test,
                                            basis_y_pred))
    # Plot outputs
    plt.scatter(basis_y_pred, basis_y_test,  color='black')
    plt.plot(basis_y_test, basis_y_test, color='blue', linewidth=3)
    plt.xlabel('Y(actual)')
    plt.ylabel('Y(Predicted)')
    plt.show()
    
    return regr, basis_y_pred
_, basis_y_pred = linear_regression(basis_X_train, basis_y_train, 
                                    basis_X_test,basis_y_test)

img

Lineare Regression ohne Unifizierung

('Coefficients: \n', array([ -1.0929e+08, 4.1621e+07, 1.4755e+07, 5.6988e+06, -5.656e+01, -6.18e-04, -8.2541e-05,4.3606e-02, -3.0647e-02, 1.8826e+07, 8.3561e-02, 3.723e-03, -6.2637e-03, 1.8826e+07, 1.8826e+07, 6.4277e-02, 5.7254e-02, 3.3435e-03, 1.6376e-02, -7.3588e-03, -8.1531e-04, -3.9095e-02, 3.1418e-02, 3.3321e-03, -1.3262e-06, -1.3433e+07, 3.5821e+07, 2.6764e+07, -8.0394e+06, -2.2388e+06, -1.7096e+07]))
Mean squared error: 0.02
Variance score: 0.96

Schauen wir uns die Modellkoeffizienten an. Wir können sie nicht wirklich vergleichen oder sagen, was wichtig ist, weil sie alle auf unterschiedliche Skalierungen gehören.

def normalize(basis_X, basis_y, period):
    basis_X_norm = (basis_X - basis_X.rolling(period).mean())/
                    basis_X.rolling(period).std()
    basis_X_norm.dropna(inplace=True)
    basis_y_norm = (basis_y - 
                    basis_X['basis'].rolling(period).mean())/
                    basis_X['basis'].rolling(period).std()
    basis_y_norm = basis_y_norm[basis_X_norm.index]
    
    return basis_X_norm, basis_y_norm
norm_period = 375
basis_X_norm_test, basis_y_norm_test = normalize(basis_X_test,basis_y_test, norm_period)
basis_X_norm_train, basis_y_norm_train = normalize(basis_X_train, basis_y_train, norm_period)
regr_norm, basis_y_pred = linear_regression(basis_X_norm_train, basis_y_norm_train, basis_X_norm_test, basis_y_norm_test)
basis_y_pred = basis_y_pred * basis_X_test['basis'].rolling(period).std()[basis_y_norm_test.index] + basis_X_test['basis'].rolling(period).mean()[basis_y_norm_test.index]

img

Die lineare Regression der Unifizierung

Mean squared error: 0.05
Variance score: 0.90

Das Modell verbessert nicht das vorherige Modell, aber es wird auch nicht schlechter. Jetzt können wir tatsächlich die Koeffizienten vergleichen, um zu sehen, welche Koeffizienten wirklich wichtig sind.

Lassen Sie uns die Koeffizienten betrachten.

for i in range(len(basis_X_train.columns)):
    print('%.4f, %s'%(regr_norm.coef_[i], basis_X_train.columns[i]))

Das Ergebnis:

19.8727, emabasis4
-9.2015, emabasis5
8.8981, emabasis7
-5.5692, emabasis10
-0.0036, rsi15
-0.0146, rsi10
0.0196, mom10
-0.0035, mom5
-7.9138, basis
0.0062, swidth
0.0117, fwidth
2.0883, btopask
2.0311, btopbid
0.0974, bavgask
0.0611, bavgbid
0.0007, topaskvolratio
0.0113, topbidvolratio
-0.0220, totalaskvolratio
0.0231, totalbidvolratio

Wir können deutlich sehen, dass bestimmte Merkmale einen höheren Koeffizienten haben als andere Merkmale und möglicherweise eine stärkere Vorhersage haben.

Wir wollen die Beziehung zwischen den verschiedenen Merkmalen untersuchen.

import seaborn

c = basis_X_train.corr()
plt.figure(figsize=(10,10))
seaborn.heatmap(c, cmap='RdYlGn_r', mask = (np.abs(c) <= 0.8))
plt.show()

img

Zusammenhänge zwischen den Merkmalen

Dunkelrote Bereiche zeigen hochrelevante Variablen. Lassen Sie uns wieder einige Eigenschaften erstellen/modifizieren und versuchen, unser Modell zu verbessern.

例如,我可以轻松地丢弃像emabasisdi7这样的特征,这些特征只是其他特征的线性组合.

def create_features_again(data):
    basis_X = pd.DataFrame(index = data.index, columns =  [])
    basis_X['mom10'] = difference(data['basis'],11)
    basis_X['emabasis2'] = ewm(data['basis'],2)
    basis_X['emabasis5'] = ewm(data['basis'],5)
    basis_X['emabasis10'] = ewm(data['basis'],10)
    basis_X['basis'] = data['basis']
    basis_X['totalaskvolratio'] = (data['stockTotalAskVol']
                                 - data['futureTotalAskVol'])/
                                   100000
    basis_X['totalbidvolratio'] = (data['stockTotalBidVol']
                                 - data['futureTotalBidVol'])/
                                   100000
    basis_X = basis_X.fillna(0)
    
    basis_y = data['Y(Target)']
    basis_y.dropna(inplace=True)
    return basis_X, basis_y
basis_X_test, basis_y_test = create_features_again(validation_data)
basis_X_train, basis_y_train = create_features_again(training_data)
_, basis_y_pred = linear_regression(basis_X_train, basis_y_train, basis_X_test,basis_y_test)
basis_y_regr = basis_y_pred.copy()

img

('Coefficients: ', array([ 0.03246139,
0.49780982, -0.22367172,  0.20275786,  0.50758852,
-0.21510795, 0.17153884]))
Mean squared error: 0.02
Variance score: 0.96

Schauen Sie, unsere Modellleistung hat sich nicht verändert, wir brauchen nur einige Eigenschaften, um unsere Zielvariablen zu erklären. Ich empfehle Ihnen, mehr der oben genannten Eigenschaften auszuprobieren, neue Kombinationen auszuprobieren und so weiter, um zu sehen, was unsere Modelle verbessern kann.

我们还可以尝试更复杂的模型,看看模型的变化是否可以提高性能.

  • K-Nachbarschaft (KNN) Algorithmen
from sklearn import neighbors
n_neighbors = 5
model = neighbors.KNeighborsRegressor(n_neighbors, weights='distance')
model.fit(basis_X_train, basis_y_train)
basis_y_pred = model.predict(basis_X_test)
basis_y_knn = basis_y_pred.copy()

img

  • SVR
from sklearn.svm import SVR
model = SVR(kernel='rbf', C=1e3, gamma=0.1)
model.fit(basis_X_train, basis_y_train)
basis_y_pred = model.predict(basis_X_test)
basis_y_svr = basis_y_pred.copy()

img

  • Entscheidungsbaum
model=ensemble.ExtraTreesRegressor()
model.fit(basis_X_train, basis_y_train)
basis_y_pred = model.predict(basis_X_test)
basis_y_trees = basis_y_pred.copy()

img

Schritt 7: Überprüfung der Testdaten

Überprüfung der Leistung der tatsächlichen Probendaten

img

Retest-Leistung auf (noch nicht berührte) Testdatensätze

Dies ist der entscheidende Moment. Wir starten mit der letzten Stufe der Testdaten, um unser endgültiges Optimierungsmodell zu betreiben, und wir legen es von Anfang an beiseite, die Daten, die wir bisher nicht berührt haben.

Dies gibt Ihnen eine realistische Erwartung, wie Ihr Modell auf neue und ungesehene Daten ausführt, wenn Sie mit dem Echtzeit-Handel beginnen. Daher ist es wichtig, sicherzustellen, dass Sie ein sauberes Datensatz haben, das nicht für das Training oder die Verifizierung des Modells verwendet wird.

Wenn Sie die Rückmessungsergebnisse der Testdaten nicht mögen, können Sie das Modell entsorgen und von vorne beginnen. Bitte gehen Sie nicht zurück, um Ihr Modell neu zu optimieren, da dies zu einer Überanpassung führen kann!

Hier benutzen wir die Auquanchen Toolbox.

import backtester
from backtester.features.feature import Feature
from backtester.trading_system import TradingSystem
from backtester.sample_scripts.fair_value_params import FairValueTradingParams
class Problem1Solver():
def getTrainingDataSet(self):
        return "trainingData1"
def getSymbolsToTrade(self):
        return ['MQK']
def getCustomFeatures(self):
        return {'my_custom_feature': MyCustomFeature}
def getFeatureConfigDicts(self):
                            
        expma5dic = {'featureKey': 'emabasis5',
                 'featureId': 'exponential_moving_average',
                 'params': {'period': 5,
                              'featureName': 'basis'}}
        expma10dic = {'featureKey': 'emabasis10',
                 'featureId': 'exponential_moving_average',
                 'params': {'period': 10,
                              'featureName': 'basis'}}                     
        expma2dic = {'featureKey': 'emabasis3',
                 'featureId': 'exponential_moving_average',
                 'params': {'period': 3,
                              'featureName': 'basis'}}
        mom10dic = {'featureKey': 'mom10',
                 'featureId': 'difference',
                 'params': {'period': 11,
                              'featureName': 'basis'}}
        
        return [expma5dic,expma2dic,expma10dic,mom10dic]    
    
    def getFairValue(self, updateNum, time, instrumentManager):
        # holder for all the instrument features
        lbInstF = instrumentManager.getlookbackInstrumentFeatures()
        mom10 = lbInstF.getFeatureDf('mom10').iloc[-1]
        emabasis2 = lbInstF.getFeatureDf('emabasis2').iloc[-1]
        emabasis5 = lbInstF.getFeatureDf('emabasis5').iloc[-1]
        emabasis10 = lbInstF.getFeatureDf('emabasis10').iloc[-1] 
        basis = lbInstF.getFeatureDf('basis').iloc[-1]
        totalaskvol = lbInstF.getFeatureDf('stockTotalAskVol').iloc[-1] - lbInstF.getFeatureDf('futureTotalAskVol').iloc[-1]
        totalbidvol = lbInstF.getFeatureDf('stockTotalBidVol').iloc[-1] - lbInstF.getFeatureDf('futureTotalBidVol').iloc[-1]
        
        coeff = [ 0.03249183, 0.49675487, -0.22289464, 0.2025182, 0.5080227, -0.21557005, 0.17128488]
        newdf['MQK'] = coeff[0] * mom10['MQK'] + coeff[1] * emabasis2['MQK'] +\
                      coeff[2] * emabasis5['MQK'] + coeff[3] * emabasis10['MQK'] +\
                      coeff[4] * basis['MQK'] + coeff[5] * totalaskvol['MQK']+\
                      coeff[6] * totalbidvol['MQK']
                    
        newdf.fillna(emabasis5,inplace=True)
        return newdf
problem1Solver = Problem1Solver()
tsParams = FairValueTradingParams(problem1Solver)
tradingSystem = TradingSystem(tsParams)
tradingSystem.startTrading(onlyAnalyze=False, 
                           shouldPlot=True,
                           makeInstrumentCsvs=False)

img

Die Ergebnisse des Tests, Pnl in US-Dollar (Pnl berücksichtigt keine Transaktionskosten und sonstigen Gebühren)

Schritt 8: Weitere Methoden zur Verbesserung des Modells

Scroll-Authentifizierung, Sammellernen, Bagging und Boosting

Es gibt einige Dinge, an denen Sie sich verbessern können, außer mehr Daten zu sammeln, bessere Features zu erstellen oder mehr Modelle auszuprobieren.

1. Roll-Authentifizierung

img

Roll-Authentifizierung

Marktbedingungen bleiben selten gleich. Nehmen wir an, Sie haben Daten für ein Jahr und Sie trainieren mit Daten von Januar bis August und testen Ihr Modell mit Daten von September bis Dezember. Vielleicht trainieren Sie am Ende gegen eine sehr spezifische Reihe von Marktbedingungen. Vielleicht gibt es keine Marktfluktuation in der ersten Hälfte des Jahres, und einige extreme Nachrichten führen zu einem starken Anstieg des Marktes im September.

Es könnte besser sein, eine Forward-Rolling-Verification zu versuchen, eine Ausbildung von Januar bis Februar, eine Prüfung von März, eine Neuausbildung von April bis Mai, eine Prüfung von Juni usw.

2. Gruppenlernen

img

Gruppenlernen

Einige Modelle können sich gut bei der Vorhersage bestimmter Szenarien eignen, während andere Szenarien oder in bestimmten Fällen die Modelle extrem übermäßig fit sind. Eine Methode zur Verringerung von Fehlern und Übermäßigkeiten ist die Verwendung von Sammlungen verschiedener Modelle. Ihre Vorhersage wird das Durchschnitt der Vorhersagen vieler Modelle sein, die von verschiedenen Modellen ausgeglichen oder reduziert werden können.

img

Verpackung

img

Erhöhung

Für eine kurze Einführung werde ich diese Methoden überspringen, aber Sie können mehr Informationen online finden.

Lassen Sie uns eine Sammelmethode für unser Problem versuchen.

basis_y_pred_ensemble = (basis_y_trees + basis_y_svr +
                         basis_y_knn + basis_y_regr)/4

img

Mean squared error: 0.02
Variance score: 0.95

Wir haben so weit viel Wissen und Informationen gesammelt. Lassen Sie uns kurz zurückgehen:

  • Lösen Sie Ihre Probleme

  • Verwenden Sie Daten, um zuverlässige Daten zu sammeln und zu reinigen

  • Daten in Trainings-, Validierungs- und Testsätze aufteilen

  • Erstellen und analysieren von Merkmalen

  • Bewegungsorientierte Auswahl des Trainingsmodells

  • Trainieren Sie Ihre Modelle mit Trainingsdaten und machen Sie Vorhersagen

  • Überprüfen und optimieren Sie die Leistung der Prüfsätze neu

  • Überprüfung der Endleistung des Testsets

Aber es ist noch nicht vorbei, du hast jetzt nur noch ein zuverlässiges Vorhersagemodell.

  • Entwicklung von Signalen auf Basis von Vorhersagemodellen zur Identifizierung von Handelsrichtungen

  • Entwicklung konkreter Strategien zur Identifizierung von Offsetpositionen

  • Exekutionssysteme zur Identifizierung von Positionen und Preisen

Das ist die Quantitative Plattform für Erfinder.FMZ.COMIn Inventor's Quantify-Plattform gibt es viele ausgebildete Alternativstrategien, die mit der in diesem Artikel beschriebenen Methode des maschinellen Lernens kombiniert werden, die Ihre spezifischen Strategien wie Tigerwings unterstützen. Strategy Square befindet sich in:https://www.fmz.com/square

Wichtige Hinweise auf die Transaktionskosten:你的模型会告诉你所选资产何时是做多或做空。然而,它没有考虑费用/交易成本/可用交易量/止损等。交易成本通常会使有利可图的交易成为亏损。例如,预期价格上涨0.05美元的资产是买入,但如果你必须支付0.10美元进行此交易,你将最终获得净亏损$0.05。在你考虑经纪人佣金,交换费和点差后,我们上面看起来很棒的盈利图实际上是这样的:

img

Die Rückmessung nach den Transaktionsgebühren und dem Punktverzögerung ergab, dass Pnl in Dollar liegt.

Die Transaktionsgebühren und -differenzen machen mehr als 90% unseres PNL aus!

Schließlich wollen wir einige der häufigsten Fallen betrachten.

Was tun und was nicht

  • Ich möchte, dass Sie sich nicht zu sehr anpassen.

  • Nicht nach jedem Datenpunkt neu trainieren: Dies ist ein häufiger Fehler, den Menschen in der Entwicklung von maschinellem Lernen machen. Wenn Ihr Modell nach jedem Datenpunkt neu trainiert werden muss, ist es wahrscheinlich kein sehr gutes Modell. Das heißt, es muss regelmäßig neu trainiert werden und nur mit einer angemessenen Häufigkeit trainiert werden (z. B. wenn eine Tagesprognose durchgeführt wird, dann am Ende der Woche).

  • Vermeiden Sie Abweichungen, insbesondere Progressive Abweichungen: Dies ist ein weiterer Grund, warum ein Modell nicht funktioniert, und stellen Sie sicher, dass Sie keine Informationen aus der Zukunft verwenden. In den meisten Fällen bedeutet dies, dass Sie die Zielvariable Y nicht als Merkmal im Modell verwenden. Während des Retro-Tests können Sie sie verwenden, aber sie werden nicht verwendet, wenn Sie das Modell tatsächlich ausführen, was Ihr Modell unbrauchbar macht.

  • Warnung bei Daten-Mining-Abweichungen: Da wir versuchen, eine Reihe von Modellierungen unserer Daten durchzuführen, um festzustellen, ob sie geeignet sind, stellen Sie sicher, dass Sie, wenn es keine besondere Ursache dafür gibt, strenge Tests durchführen, um die zufälligen Muster von den tatsächlichen Mustern zu trennen, die möglicherweise auftreten.

Vermeiden Sie Überanpassung

Das ist sehr wichtig, und ich finde es notwendig, es noch einmal zu erwähnen.

  • Übermäßige Anpassung ist die gefährlichste Falle in der Handelsstrategie

  • Ein komplexer Algorithmus kann sich bei Rückmeldungen hervorragend entwickeln, aber bei neuen, unsichtbaren Daten scheitern. Dieser Algorithmus enthüllt keine Trends in den Daten und kann keine tatsächlichen Vorhersagen machen.

  • Machen Sie Ihr System so einfach wie möglich. Wenn Sie feststellen, dass Sie viele komplexe Funktionen benötigen, um Daten zu interpretieren, sind Sie möglicherweise zu fit.

  • Teilen Sie Ihre verfügbaren Daten in Trainings- und Testdaten und überprüfen Sie immer die Leistung der echten Probendaten, bevor Sie mit dem Modell in Echtzeit handeln.


Verwandt

Mehr

Ein Blatt WissenDanke, Vater.

- Das ist nicht wahr.Sehr gute Artikel, Ideen und Zusammenfassungen für Anfänger.

LallalademaxiaDas ist ein Schlagzeug!