So ein Ding habe ich auch mal gemacht ...

 

Eines Tages wurde mir plötzlich eine einfache Sache klar: Bei der Annäherung der kleinsten Quadrate geht es im Wesentlichen darum, eine Linearkombination von Vektoren zu minimieren. Das heißt, es kann eine Art universelle Näherungsfunktion hergestellt werden. Es ist eine beschlossene Sache, also hier ist der Titel der Funktion:

//+------------------------------------------------------------------+
//  Аппроксимация методом наименьших квадратов                       |
//+------------------------------------------------------------------+
bool LSA(double& V[], int M, int N, double& A[], double& C[]) {
// Имеется N векторов размером M
// и вектор их линейной комбинации Y размером естестственно тоже M.
// На вход функции они подаются в виде матрицы V[0..M-1][0..N],
// где Y размещён в столбце N 
// На выходе мы должны получить вектор коэффициентов C размером M.
// Нам нужна также матрица A[N][N+1] для размещения коэффициентов системы уравнений

Wichtiges Detail: Alle Felder V und A sind in Wirklichkeit eindimensional, das Feld A funktioniert zwar, aber das Feld V muss korrekt gefüllt werden.

Außerdem wird eine Funktion benötigt, um ein System linearer Gleichungen zu lösen. Als ich mir das ausdachte, kannte ich nur eine Implementierung in MQL, die Gauß-Methode, die von ANG3110 für polynomiale Regression verwendet wird. Natürlich bin ich den Weg des geringsten Widerstands gegangen und habe diesen speziellen Algorithmus für die Funktion verwendet. Mit anderen Worten: Es gibt effizientere Algorithmen, vor allem, weil die Matrix symmetrisch ist, aber ich habe sie nicht verwendet.

Wie man es benutzt:

Zunächst entscheiden wir, welche Funktion wir approximieren wollen. Es handelt sich beispielsweise um eine lineare Regression. Das heißt, wir haben eine Linearkombination von A*1 + B*X, nur zwei Vektoren, einen Einheitsvektor und das Argument selbst.

Lassen Sie uns funktionierende Arrays erstellen und ihnen irgendwo in init() Speicher zuweisen

double V[];
double A[],С[];

...

  ArrayResize(A,6);  // размер N*(N+1)
  ArrayResize(C,2);  // размер N
  ArrayResize(V,M*3);  // M*(N+1), M - не что иное как размер выборки

Nun muss nur noch das Feld V korrekt ausgefüllt und die Koeffizienten berechnet werden. Dies kann wie folgt geschehen:

    ind = 0;
    Stop = Start + M;
// Заполняем векторы
    for(pos = Start; i < Stop; i++) {
     V[ind] = 1.0;
     ind++;
     V[ind] = pos;
     ind++;
     V[ind] = Close[pos];   
     ind++;
    }
// Считаем коэффициенты
   LSA(V, M, N, A, C);

Es ist geschafft, die lineare Regression C[0] + C[1]*pos ist fertig.

Als Erstes müssen wir den Algorithmus überprüfen. Zu diesem Zweck haben wir auf der Grundlage des Indikators ang_PR (Din)-v1.mq4 ( ANG3110 ) einen polynomialen Regressionsindikator mit LSA geschrieben und die Ergebnisse verglichen. Die Ergebnisse stimmten visuell überein, das war das Ende des Tests :). Der Indikator LSA_PR.mq4 ist beigefügt.

Dateien:
pr_lsa.mq4  7 kb
 

Das alles ist schon ziemlich lange her, und vor kurzem erinnerte ich mich daran und beschloss, das Werkzeug, das ich hergestellt hatte, wieder in Betrieb zu nehmen.

Mein erster Gedanke war, nach einer Periodizität in der Kurve zu suchen. Es stellt sich die Frage, warum, denn es gibt eine diskrete Fourier-Transformation (DFT) für die Suche nach Oberwellen. Die FFT liefert jedoch nur Oberschwingungen mit einer Periode, die kürzer als die Abtastlänge ist. Wir können nun versuchen, Oberschwingungen mit einer Periode, die länger ist als die Stichprobenlänge, in das Preisdiagramm einzupassen. Natürlich ist die erfolgreiche Anpassung kein "stichhaltiges" Argument für die tatsächliche Existenz, die Frage nach dem Grad des Vertrauens in eine bestimmte Annäherung sollte separat entschieden werden.

In dem beigefügten Indikator LSA_SinLRR.mq4 wird der lineare Trend berechnet, bevor die Harmonische ausprobiert wird. Sie wird anhand des oberen Horizonts berechnet. Es werden alle möglichen Stichprobenlängen in einem bestimmten Bereich durchsucht und diejenige ausgewählt, die den geringsten RMS-Fehler bei der Stichprobenüberschreitung aufweist (der als 1/4 des Basisstichprobenumfangs angenommen wird).

Die harmonische Periode wird mit der Länge der Probe in Beziehung gesetzt, indem sie mit einem bestimmten Faktor multipliziert wird. Ist er z. B. gleich 2, enthält die Probe eine halbe Periode der Harmonischen, ist er gleich 0,5, zwei Perioden. Die Stichprobenlänge selbst wird auf die gleiche Weise wie bei der linearen Regression bestimmt, nur dass sie innerhalb des untersten Horizonts aufgezählt wird.

Um den Umfang der Berechnungen zu verringern, wird für jeden Horizont ein anderer Stichprobenschritt gewählt.

Die Vektormatrix wird wie folgt ausgefüllt

  for(i = IntShift; i < Frame; i++) {
    pos = HShift+i*Step;
    VT[ind] = MathSin(AFreq*pos);
    ind ++;
    VT[ind] = MathCos(AFreq*pos);
    ind ++;
    VT[ind] = Resid[i];   
    ind ++;
  }  //  for(i = IntShift; i < Frame; i++)

Residiert wird der Unterschied zwischen dem Preis und dem älteren Trend.

Parameter des Indikators:

extern double kPer = 4.0;   // Коэффициент для определения периода
extern int LRRank = 1;      // Номер старшего горизонта, больше 3-х не ставить
extern int FShift = 120;    // Расстояние в барах, на которое производится экстраполяция в будущее
extern int HShift = 1;      // Сдвиг текущего времени индикатора в прошлое в барах, бары правее него тоже будут проэктраполированы
extern double PointFactor = 0.1;  // Масштабирование гистограммы ошибок аппроксимации, 0.1 подойдёт для минуток на пятизнаке 
extern bool PriceClose = true; // Если false, то будет считаться по HL/2


Uff, irgendwie bin ich müde geworden, zu schreiben :)

Kurz gesagt, geht es um Folgendes: Diese Funktion erhebt nicht den Anspruch, optimal zu sein, sie ermöglicht es einfach, Annäherungen als Pfannkuchen zu machen und sie sofort zu probieren, direkt aus der Pfanne :) . Dementsprechend sind die Indikatoren so gestaltet, dass sie keinen Anspruch auf Stil und Effizienz erheben.

Dieser Fall funktioniert nicht sehr schnell, so dass der Verlauf nicht berechnet wird. Das bedeutet, dass es besser ist, im Visualizer zu lernen. Aber es wird schnell langweilig :). Aber es ist nicht auszuschließen, dass ein Patient einen Weg findet, davon zu profitieren :).


Im Allgemeinen bin ich mir bewusst, dass ich keine kohärente Beschreibung machen konnte, wenn jemand interessiert ist, kann er wahrscheinlich auf Erklärungen zählen.


Im Grunde genommen sollten wir über einen anderen Indikator sprechen, der sich besser anpasst und extrapoliert als die vorgestellten. Das heißt, ich bin davon so beeindruckt, dass ich anscheinend endlich in die Position des stückweisen Preisdeterminismus gelangt bin. Aber das macht es nicht einfacher, denn ich habe es noch nicht geschafft, die Länge dieser Stücke zu bestimmen :) .

Aber ich habe keine Energie mehr zu schreiben, ich kann nur ein paar Bilder zeigen :)

Beispiel für eine Annäherung mit erfolgreicher Extrapolation

Beispiel für eine Annäherung mit Extrapolation, die durch einen Impuls "vereitelt" wird

Dateien:
lsa_sinlr.mq4  14 kb
 
Candid:

Könnten Sie ein kleines Stück Code hinzufügen, dass HShift nicht gesetzt ist, sondern von der aktuellen Position der ersten Zeile bestimmt wird? genauer gesagt, wenn es <0 gesetzt ist - dann werden beide Mechanismen funktionieren und es wird möglich sein, es auf dem Diagramm tief in die Geschichte zu ziehen und zu analysieren, wie die Vorhersage zu diesem Zeitpunkt mit dem übereinstimmte, was danach geschah. es wird interessant sein;)

 
ForexTools:

Könnten Sie ein kleines Stück Code hinzufügen, dass HShift nicht gesetzt ist, sondern von der aktuellen Position der ersten Zeile bestimmt wird? Genauer gesagt, wenn es <0 gesetzt ist - dann werden beide Mechanismen funktionieren und Sie können es auf einem Diagramm tief in die Geschichte ziehen und analysieren, wie die Vorhersage zu diesem Zeitpunkt mit dem, was danach geschah, zusammenfiel. es wird interessant sein;)

Ja, es ist ziemlich praktisch, ich gebe Ihnen eine Version. Ich sollte darauf hinweisen, dass ich nicht besonders scharf auf die grafische Steuerung bin, so dass es keine Garantie dafür gibt, dass alles reibungslos funktioniert.


Übrigens glaube ich nicht, dass ich irgendwo ausdrücklich gesagt habe, dass die Histogramme in der unteren rechten Ecke den Näherungsfehler bei der Basisstichprobe und den Extrapolationsfehler bei der Nicht-Stichprobe anzeigen. Es ist davon auszugehen, dass diese Informationen für die Beurteilung der Situation relevant sind.


P.S. Ja, ich habe eine Zeile vergessen hinzuzufügen. Anzeiger um 11:50 Uhr ersetzt

Dateien:
 

Ein paar weitere Worte. Warum genau wird ein linearer Trend angenommen? Wie auch immer, echte Trends sehen linear aus. Wenn man davon ausgeht, dass eine solche Verzerrung unbewusst erfolgen kann, dann besteht die Hoffnung, dass auch hinter den Oberschwingungen eine Realität stehen kann.

Im Prinzip ist es kein Problem, den Grad eines Polynoms zu erhöhen; ich habe mit der Option Parabel begonnen. Das ist elementar, in ein paar hinzugefügten und korrigierten Zeilen, jeder kann es selbst ausprobieren, als Übung.

 

Guten Tag.

Bitte erläutern Sie die Zeichnungen. Ich interessiere mich für die vertikalen Linien. Habe ich richtig verstanden, dass in dem Intervall zwischen den blauen Linien die Daten für die Vorhersage liegen? Was bedeutet die rote Linie? - Warum haben die roten (blauen) Prognoselinien Lücken?

Ich habe mir den Code nicht angesehen, weil Ihr Niveau der MQL-Programmierung zu niedrig für mich ist, es ist wie ein Traum, näher an dieses Niveau zu kommen ?

 

Prival:

Bitte erläutern Sie die Zeichnungen. Ich interessiere mich für die vertikalen Linien. Habe ich richtig verstanden, dass die Daten für die Vorhersage im Intervall zwischen den blauen Linien liegen? Was bedeutet die rote Linie? - Warum haben die roten (blauen) Vorhersagelinien Lücken?


Ja, die Annäherung findet zwischen den blauen Linien statt. Zwischen dem blauen und dem roten Wert wird der RMS der Extrapolation berechnet. Es liegt in unserer Macht, sie mit HShift zu verschieben (und jetzt einfach die Linie entlang des Diagramms zu ziehen) und zu sehen, was sie nicht sieht.

Die Lücken sind "Abfall", das Arbeitsfenster des Indikators verschiebt sich im Laufe der Zeit, es bleiben Spitzen zurück. Das ließe sich leicht mit einem dauerhaften Fenster beheben, aber da es sich anpasst, ist mir noch keine billige Möglichkeit eingefallen, es zu reinigen.

Ich gebe Ihnen die Version mit den übermalten Linien.

Dateien:
 

Ihr neuer Code hat nicht so funktioniert, wie ich es wollte :(

Ich habe mir die Freiheit genommen, meine Bearbeitungen herunterzureißen. Das funktioniert hervorragend, besonders in Verbindung mit ft.AutoRefresh

Dateien:
lsa_sinlr_1.mq4  16 kb
 

ForexTools:

Hier habe ich mir erlaubt, meine Bearbeitungen abzubauen. Funktioniert großartig, besonders in Verbindung mit ft.AutoRefresh

Nun, ich denke, Ihre Version ist störungssicherer, aber Sie müssen wahrscheinlich HShift-- auch dort hinzufügen, so dass, wenn es keine Benutzeraktion gibt, das Fenster mit der Zeit bewegt wird. Obwohl, hmm, vielleicht ist es genau das, was du vermeiden wolltest?
 
Natürlich sollte das Diagramm bei der Analyse der Geschichte nicht irgendwo hingehen, sondern an der Stelle "stehen", an der ich die Linie gesetzt habe
 
ForexTools:
Natürlich sollte das Diagramm bei der Analyse der Geschichte nicht irgendwo hingehen, sondern an der Stelle "stehen", an der ich die Linie gesetzt habe

Nun, ich habe zuerst eine stationäre Variante gemacht und sie dann ersetzt :). Ich interessierte mich vor allem für die Dynamik des Umzeichnens. Eigentlich ist es einfach, einen Parameter hinzuzufügen wie

if (ModeMoving) HShift--;
Aber zu gut ist auch nicht gut, lassen Sie die Variante brach liegen.