Maschinelles Lernen im Handel: Theorie, Modelle, Praxis und Algo-Trading - Seite 20

 
interessanter Artikel https://geektimes.ru/post/144405/, vielleicht versteht jemand, wie man das in R simulieren kann
Прогнозирование финансовых временных рядов
Прогнозирование финансовых временных рядов
  • geektimes.ru
Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста. Пометьте топик понятными вам метками, если хотите или закрыть
 

Ich begann mit Clustern zu experimentieren, basierend auf den Motiven, die ich zuvor erwähnt habe. Ich stieß auf ein Problem - wenn ich versuchte, den Preis von den Stücken, die zu einem Cluster entsprechen kleben, waren die geklebten Stellen Preis Lücken (und das ist logisch, aber es ist mir nicht in den Sinn gekommen)) ) Die Frage ist, wie diese Lücken geschlossen werden können.

#  типа какая то цена
dat <- cumsum(rnorm(1000))+1000
plot(dat,t="l")


#  фун. матрицы хенкеля для имитации скользящего окна
hankel<- function(data, r=10) {
  do.call(cbind,
          lapply(0:(r-1),function(i) { data[(i+1):(length(data)-(r-1-i))]}))}
#  делаем аналог скользящего окна глубиной в 50
glubina <- 50
D <- hankel(dat,r = glubina)


#  скалирую и центрирую дату, проще сказать нормализирую
DC <- t(  apply(D, 1,    function(x) {  scale(x,T,T)  }    ))


library(SOMbrero)
#  тренирую сеть кохонена на данных чтоб получить кластера
TS <- trainSOM(DC,  dimension=c(3,3))

#  край матрицы будет вектор нашей цены без первых значений
dt <- D[,glubina] 
#  полученые кластера
cl <- TS$clustering

#  график цены , график кластеров этой цены
par(mfrow=c(2,1))
plot(dt,t="l")
plot(cl,t="l")
par(mfrow=c(1,1))


#  пробую посмотреть склееный график только одного кластера 
one_clust <- dt[cl==3]
#  график с разрывами в местах склейки
plot(one_clust,t="l")
 
Dr. Trader:

Ich habe dieses Problem auch. Normalerweise müssen Sie nur attributes(KZP) ausführen, um eine Liste der verfügbaren Variablen zu erhalten, und diese dann einfach durchgehen, z. B. KZP$window usw., und die Zahlen finden, die Sie benötigen. Aber hier werden diese Zahlen in der Funktion Zusammenfassung selbst erzeugt und nirgendwo gespeichert.

Hier ist ein Quellcode: https://cran.r-project.org/web/packages/kza/index.html, wir müssen etwas wie dieses ausführen:

Übrigens, es kann für Sie nützlich sein, wenn Sie Indikatoren verwenden, diese Funktion erkennen in einer sehr verrauschten Daten periodische Komponenten, kurz gesagt, diese Periode ändert sich ständig auf dem Markt.

Es geht darum, diesen dominanten Zeitraum ständig zu identifizieren und die Indikatoren darauf abzustimmen, nicht nur mit festen Parametern, wie es alle anderen tun. Ich habe diesen Ansatz sehr oberflächlich an einem zufälligen Datum getestet, und das Ergebnis war positiv im Vergleich zum üblichen Ansatz. Ich habe den RSI-Indikator genommen, der mit festen Parametern verloren und mit adaptiven Parametern gewonnen hat. Wenn Sie es verwenden wollen, können Sie es verwenden, und ich wäre sehr daran interessiert, das Ergebnis Ihrer Forschung zu lesen

 
mytarmailS:

Ich begann mit Clustern zu experimentieren, basierend auf den Motiven, die ich zuvor erwähnt habe. Ich stieß auf ein Problem - wenn ich versuchte, den Preis von den Stücken, die zu einem Cluster entsprechen kleben, waren die geklebten Stellen Preis Lücken (und das ist logisch, aber es ist mir nicht in den Sinn gekommen)) ) Die Frage ist, wie diese Lücken geschlossen werden können.

Logarithmieren Sie die Preisreihe und wandeln Sie sie dann in eine Differenzreihe um. Um die Reihe zusammenzufügen, lassen Sie nur die Intervalle übrig, die der gefundenen Bedingung entsprechen. Bilden Sie dann durch Summation eine neue Reihe aus dieser Reihe. Und, falls gewünscht, belichten Sie sie anschließend.
 
Anton Zverev:
Logarithmieren Sie die Preisreihe und wandeln Sie sie dann in eine Differenzreihe um. Um die Reihe zusammenzufügen, lassen Sie nur die Intervalle übrig, die der gefundenen Bedingung entsprechen. Bilden Sie dann durch Summation eine neue Reihe aus dieser Reihe. Und, falls gewünscht, belichten Sie sie anschließend.
Danke, so habe ich mir das vorgestellt, probieren wir es aus.
 

Ich habe noch ein paar weitere interessante Dinge gelernt:

Die bereits gepostete Funktion zum Aussieben von Prädiktoren (designTreatmentsN$scoreFrame) liefert eindeutig nicht den endgültigen Satz von Prädiktoren. Es werden nicht einmal 100%ig korrelierte Prädiktoren entfernt, und es kann sein, dass etwas, das Sie wollen, entfernt wird und Müll übrig bleibt. Ich habe ihre Sichtungsmethode ein wenig kompliziert - zunächst siebe ich die Prädiktoren auf die alte Weise, über designTreatmentsN$scoreFrame (ich habe den Schwellenwert zweimal erhöht - 2/N, um weniger potenziell gute Prädiktoren auszusieben). Dann entferne ich alle Prädiktoren, die mit >0,99 korrelieren (nach der zufälligen Generierung von Deltas und Summen habe ich eine Menge davon. Und ich betrachte die Korrelation der Prädiktoren untereinander, nicht mit der Zielvariablen). Dann suche ich genetisch nach dem besten Satz der verbleibenden Prädiktoren.

Ich versuche, etwas anderes aus dem Artikel über Hauptkomponenten zu verwenden. Die folgende Funktion erstellt das Hauptkomponentenmodell und gibt R^2 für den Fall zurück, dass ich alle gefundenen Hauptkomponenten verwendet habe. Es hat keine "Y-Skala" wie ein anderes Beispiel aus dem Artikel, aber dieser Weg ist schneller. Ich verwende sie jetzt zur Schätzung von Prädiktoren (wahrscheinlich umsonst, ich weiß es noch nicht :) ). Die letzte Spalte des Parameters srcTable ist die Zielvariable. Es kann zu Fehlern kommen, wenn der Prädiktor zu wenige Werte hat, und die Funktion passt möglicherweise nicht zu einigen Daten.

library('caret')
GetPCrsquared <- function(srcTable){
        targetName <- tail(colnames(srcTable),1)
        origVars <- setdiff(colnames(srcTable), targetName)
        # can try variations such adding/removing non-linear steps such as "YeoJohnson"
        prep <- preProcess(srcTable[,origVars], method = c("zv", "nzv", "center", "scale", "pca"))
        prepared <- predict(prep,newdata=srcTable[,origVars])
        newVars <- colnames(prepared)
        prepared$target <- srcTable$target
        modelB <- lm(paste(targetName, paste(newVars,collapse=' + '),sep=' ~ '),data=prepared)
        return(summary(modelB)$r.squared)
}

Während ich vorher einen R^2 von etwa 0,1 hatte, habe ich jetzt 0,3 erreicht. Das ist immer noch nicht genug, es wird empfohlen, mindestens 0,95 zu verwenden. Seltsam ist auch, dass ich bei R^2=0,1 einen Fehler von 37% im Fronttest hatte, während dieser Fehler bei R^2=0,3 auf 45% angestiegen ist. Vielleicht liegt das Problem darin, dass ich mehr Balken und mehr Indikatoren zu den Prädiktoren hinzugefügt habe. Ein Schritt vor und zwei Schritte zurück, jetzt muss ich den gesamten Satz von Indikatoren analysieren und unnötige entfernen. Oder das Hauptkomponentenmodell ist einfach nicht auf Forex anwendbar (schwer zu überprüfen, zuerst muss ich R^2 > 0,95 erreichen und sehen, was das Ergebnis im Fronttest sein wird, mit einem ungeübten Modell ist es zu früh, um Schlussfolgerungen zu ziehen).

Ich habe auch das GA-Paket (Genetik) und GenSA (Gradient Annealing, aus Alexey's Beispiel) verglichen. Beide Pakete erzielten das gleiche Ergebnis. Die Genetik weiß, wie man mit mehreren Threads arbeitet, und so hat sie rechtzeitig gewonnen. Aber GenSA scheint bei einem einzigen Thema zu gewinnen. Es gibt auch einen Trick zum Zwischenspeichern von Ergebnissen, ich denke, Alex wird ihn zu schätzen wissen:

fitness_GenSA_bin <- function(selectionForInputs){
        testPredictorNames <- predictorNames[ which(selectionForInputs == TRUE) ]
        #do  the fitness calculation
}

library(memoise)
fitness_GenSA_bin_Memoise <- memoise(fitness_GenSA_bin)

fitness_GenSA <- function(selectionForInputs){
        selectionForInputs[selectionForInputs>=0.5] <- TRUE
        selectionForInputs[selectionForInputs<0.5] <- FALSE
        return(fitness_GenSA_bin_Memoise(selectionForInputs))
}

library(GenSA, quietly=TRUE)
GENSA <- GenSA(fn = fitness_GenSA,
                                lower = rep(0, length(predictorNames)),
                                upper = rep(1, length(predictorNames)),
                                control=list(smooth=FALSE, verbose=TRUE)
                                ) 

Der Punkt ist, dass die Zwischenfunktion fitness_GenSA_bin_Memoise Daten aus dem Zwischenspeicher nimmt, wenn ein solcher Satz von Prädiktoren bereits mindestens einmal aufgetreten ist. Die fitness_GenSA_bin sollte die eigentlichen Berechnungen der Fitnessfunktionen enthalten und wird nur einmal für jeden einzelnen Satz aufgerufen.

mytarmailS:

Übrigens, es kann für Sie nützlich sein, wenn Sie Indikatoren verwenden, diese Funktion erkennt periodische Komponenten in sehr verrauschten Daten, kurz gesagt, diese Periode ändert sich ständig auf dem Markt.

Es geht darum, diesen dominanten Zeitraum ständig zu identifizieren und die Indikatoren darauf abzustimmen, nicht nur mit festen Parametern, wie es alle anderen tun. Ich habe diesen Ansatz sehr oberflächlich an einem zufälligen Datum getestet, und das Ergebnis war positiv im Vergleich zum üblichen Ansatz. Ich habe den RSI-Indikator genommen, der mit festen Parametern verloren und mit adaptiven Parametern gewonnen hat. Wenn Sie daran interessiert sind, können Sie es verwenden, ich bin sehr daran interessiert, das Ergebnis Ihrer Forschung zu lesen

Im Moment verwende ich nur Standardparameter für Indikatoren. Wenn ich einen Indikator verwende, ist es sinnvoller, Standardparameter für den Aktienhandel auf D1 zu verwenden, aber sie müssen angepasst werden. Ich bin nicht in der Lage, die Ergebnisse von D1 auf H1 zu verschieben, je mehr ich Indikatoren verwende, desto mehr bleibe ich auf D1 hängen. Es stellt sich heraus, dass die Parameter des Indikators je nach Zeitrahmen und Zeit geändert werden müssen, ja.

 
Dr. Trader:

Ich habe noch ein paar weitere interessante Dinge gelernt:

Die zuvor gepostete Funktion zum Aussieben von Prädiktoren (designTreatmentsN$scoreFrame) liefert eindeutig nicht den endgültigen Satz von Prädiktoren. Es werden nicht einmal 100%ig korrelierte Prädiktoren entfernt, und es kann sein, dass etwas, das Sie wollen, entfernt wird und Müll übrig bleibt. Ich habe ihre Sichtungsmethode ein wenig kompliziert - zunächst siebe ich die Prädiktoren auf die alte Weise, über designTreatmentsN$scoreFrame (ich habe den Schwellenwert zweimal erhöht - 2/N, um weniger potenziell gute Prädiktoren auszusieben). Dann entferne ich alle Prädiktoren, die mit >0,99 korrelieren (nach der zufälligen Generierung von Deltas und Summen habe ich eine Menge davon. Und ich betrachte die Korrelation der Prädiktoren untereinander, nicht mit der Zielvariablen). Dann suche ich genetisch nach dem besten Satz der verbleibenden Prädiktoren.

Ich versuche, etwas anderes aus dem Artikel über Hauptkomponenten zu verwenden. Die folgende Funktion erstellt das Hauptkomponentenmodell und gibt R^2 für den Fall zurück, dass ich alle gefundenen Hauptkomponenten verwendet habe. Es hat keine "Y-Skala" wie ein anderes Beispiel aus dem Artikel, aber dieser Weg ist schneller. Ich verwende sie jetzt zur Schätzung von Prädiktoren (wahrscheinlich umsonst, ich weiß es noch nicht :) ). Die letzte Spalte des Parameters srcTable ist die Zielvariable. Es kann zu Fehlern kommen, wenn der Prädiktor zu wenige Werte hat, und die Funktion passt möglicherweise nicht zu einigen Daten.

Während ich vorher einen R^2 von etwa 0,1 hatte, habe ich jetzt 0,3 erreicht. Das ist immer noch nicht genug, es wird empfohlen, mindestens 0,95 zu verwenden. Seltsam ist auch, dass ich bei R^2=0,1 einen Fehler von 37% im Fronttest hatte, während dieser Fehler bei R^2=0,3 auf 45% angestiegen ist. Vielleicht liegt das Problem darin, dass ich mehr Balken und mehr Indikatoren zu den Prädiktoren hinzugefügt habe. Ein Schritt vor und zwei Schritte zurück, jetzt muss ich den gesamten Satz von Indikatoren analysieren und unnötige entfernen. Oder das Hauptkomponentenmodell ist einfach nicht auf Forex anwendbar (schwer zu überprüfen, zuerst muss ich R^2 > 0,95 erreichen und sehen, was das Ergebnis im Fronttest sein wird, mit einem ungeübten Modell ist es zu früh, um Schlussfolgerungen zu ziehen).

Ich habe auch das GA-Paket (Genetik) und GenSA (Gradient Annealing, aus Alexey's Beispiel) verglichen. Beide Pakete erzielten das gleiche Ergebnis. Die Genetik weiß, wie man mit mehreren Threads arbeitet, und so hat sie rechtzeitig gewonnen. Aber GenSA scheint bei einem einzigen Thema zu gewinnen. Es gibt auch einen Trick zum Zwischenspeichern von Ergebnissen, ich denke, Alex wird ihn zu schätzen wissen:

Der Punkt ist, dass die Zwischenfunktion fitness_GenSA_bin_Memoise Daten aus dem Zwischenspeicher nimmt, wenn ein solcher Satz von Prädiktoren bereits mindestens einmal aufgetreten ist. Die fitness_GenSA_bin sollte die eigentlichen Berechnungen der Fitnessfunktionen enthalten und wird nur einmal für jeden einzelnen Satz aufgerufen.

Bislang verwende ich nur Standardparameter für Indikatoren. Ich stimme zu, dass Indikatoren, die hauptsächlich für D1 entwickelt wurden, im Allgemeinen nützlicher sind, wenn sie nur für diesen Zeitrahmen Standardparameter haben. Ich bin nicht in der Lage, die Ergebnisse von D1 auf H1 zu verschieben, je mehr Indikatoren ich verwende, desto mehr bleibe ich auf D1 hängen. Es stellt sich heraus, dass die Parameter des Indikators je nach Zeitrahmen und Zeit geändert werden müssen, ja.

Cool, das mit dem Caching. Ich habe versucht, es selbst zu schreiben. Aber es gibt eine fertige Lösung. Cueru. Danke, Mann.

Und welche Fitnessfunktion verwenden Sie beim Überschießen? Das habe ich verpasst. Lineare Abhängigkeit oder eine Art von Statistik?
 
Dr. Trader:

Es gibt keine "Y-Skala" wie in einem anderen Beispiel aus dem Artikel,

Ich denke, genau darum geht es in dem Artikel. Ich habe ihn noch einmal gelesen, er sagt das ausdrücklich.

Doch zurück zum allgemeinen Schema der Erstellung einer Liste von Prädiktoren.

Der Lärmschutz ist nur ein Teil des Problems und löst nicht die übrigen Probleme und Empfehlungen in diesem Bereich.

Wenn dies alles erledigt ist, läuft der nächste Arbeitsalgorithmus in einer Schleife wie folgt ab.

1. Wir nehmen einen ausgewählten und verarbeiteten Satz von Prädiktoren. Diese Liste ist konstant.

2. Für das aktuelle Fenster wählen wir die Prädiktoren mit einem der Algorithmen aus. Zum Beispiel gibt es zwei Algorithmen in caret.

3. Anpassen des Modells.

4.

5. Verschieben Sie das Fenster und gehen Sie zu Schritt 2.

Die Anzahl der Rauschprädiktoren betrug mehr als 80 aus den ursprünglichen Prädiktoren, die ich in den Händen hielt!

Der Standardalgorithmus wählt dann etwa die Hälfte der verbleibenden Prädiktoren aus, die der Algorithmus nicht als Rauschen klassifiziert. Da sich das Fenster bewegt, ändert sich die Zusammensetzung dieser Hälfte ständig. Allerdings sind der Fehler in der Trainingsmenge und der Fehler außerhalb der Stichprobe immer ungefähr gleich. Daraus schließe ich, dass mein Modell nicht übertrainiert ist und dies eine Folge der oben beschriebenen Algorithmen zur Prädiktorenauswahl ist.

 

Und welche Fitnessfunktion verwenden Sie beim Brute-Forcing?

Ich habe den Wald trainiert und einen Fehler in der Validierungsprobe zurückgegeben. Im Prinzip hat es funktioniert - wenn der Wald auch nur ein bisschen übertrainiert ist, tendiert der Fehler gegen 50%.

Jetzt verwende ich GetPCrsquared(), den obigen Code. Ich habe auch Ihr Beispiel aus feature_selector_modeller.txt, aber ich muss es herausfinden und das richtige Stück Code dort bekommen, also habe ich es noch nicht auf meinen Daten getestet.

 
SanSanych Fomenko:

Ich denke, genau darum geht es in dem Artikel. Ich habe ihn noch einmal gelesen, er sagt es ausdrücklich.

Ich habe auch die Y-Skala ausprobiert, R^2 war in beiden Fällen (mit und ohne Y-Skala) gleich (obwohl in diesen Fällen unterschiedliche Pakete verwendet werden!).

Ich vermute, dass die Y-Skala mit einer geringeren Anzahl von Hauptkomponenten das gleiche gute Ergebnis liefern kann. Aber wenn selbst bei Verwendung aller Komponenten das Ergebnis immer noch nicht zufriedenstellend ist (wie in meinem Fall), gibt es keinen Unterschied. Außerdem funktioniert es schneller, was für mich jetzt noch wichtiger ist. Aber ich habe weder in der Theorie noch in der Praxis bewiesen, ob diese Methode für die Auswahl der Prädiktoren geeignet ist... Zuerst hatte ich die Idee, das Hauptkomponentenmodell für alle Prädiktoren zu erstellen und die Prädiktoren anhand der Koeffizienten der Komponenten auszuwählen. Aber dann habe ich bemerkt, dass der R^2 des Modells sinkt, wenn man Müll hinzufügt. Es wäre logisch, verschiedene Gruppen von Prädiktoren auszuprobieren und nach denjenigen zu suchen, die einen höheren R^2-Wert aufweisen, aber das ist nur eine Theorie.