4.6 Wie man Strategien in der C++-Sprache umsetzt

Schriftsteller:Gutes, Erstellt: 2019-05-06 13:00:27, aktualisiert:

Zusammenfassung

In dem vorherigen Artikel haben wir die Prämisse der Umsetzung der Handelsstrategie von der Einführung der C++-Sprache, der grundlegenden Grammatik und der Strategiestruktur erklärt.

Einführung in die Strategie

Einer der am häufigsten verwendeten Indikatoren in der technischen Analyse, KDJ, wurde von den meisten Händlern auf der ganzen Welt anerkannt.

KDJ basierte auf der statistischen Theorie, ein zufälliger Wert (RSV) wurde durch das Verhältnis der letzten 9 K-Linies höchsten, niedrigsten und Schlusskurs berechnet. dann berechnen K-Wert, D-Wert und J-Wert nach dem gleitenden Durchschnitt, und zeichnen eine Grafik, um die Preisentwicklung zu beurteilen.

img

Durch die Kombination der Vorteile von Momentum-Konzept, Strength-Indikator und gleitendem Durchschnitt messen wir den Grad der Veränderung des Aktienpreises von der normalen Bereichsbewegung. Wenn der K-Wert größer als der D-Wert ist, zeigt dies an, dass der Aktienpreis derzeit in einem Aufwärtstrend ist. Wenn daher die K-Linie die D-Linie von unten nach oben überquert, ist es Zeit, die Aktie zu kaufen. Umgekehrt, wenn der K-Wert kleiner als der D-Wert ist, zeigt es an, dass der Aktienmarkt derzeit in einem Abwärtstrend ist. Wenn daher die K-Linie die D-Linie von oben nach unten überquert, ist es Zeit, die Aktie zu verkaufen.

Berechnungsmethode für den KDJ-Indikator

Die Berechnung des KDJ-Indikators ist kompliziert. Zuerst wird der zufällige Wert (RSV) berechnet, und dann der K-Wert, der D-Wert und der J-Wert berechnet.

  • RSV = (Schlusskurs - niedrigster Preis in N-Zeitraum) / (höchster Preis in N-Zyklen - niedrigster Preis in N-Zyklen) * 100

  • K-Wert = Mittelwert der N-Zyklen RSV

  • D-Wert = Mittelwert von N Zyklen K

  • J-Wert = 3 * K-Wert -2 * D-Wert

void main(){ // the program starts from this main function
    while (true){ // enter the loop
        auto ct = exchange.SetContractType(symblo); //set the contract type
        auto r = exchange.GetRecords(); // get the K line array
        auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator 
        auto k = arr[0]arr[0].size() - 2]; // get the previous k line KDJ indicator K value
        auto d = arr[1]arr[1].size() - 2]; // get the previous k line KDJ indicator D value
        auto j = arr[2]arr[2].size() - 2]; // get the previous k line KDJ indicator J value
    }
}

Strategie Logik

Es gibt viele Möglichkeiten, KDJ zu verwenden, die allein oder in Kombination mit anderen Indikatoren verwendet werden können. In diesem Artikel werden wir es auf die einfachste Weise verwenden, nämlich: Wenn der K-Wert größer als der D-Wert ist, glauben wir, dass die Kaufkraft stärker wird, eine Welle eines steigenden Marktes gebildet wurde und das Eröffnungssignal für die Long-Position erzeugt wurde; wenn der K-Wert kleiner als der D-Wert ist, glauben wir, dass die Verkaufskraft stärker wird und eine Welle eines Abwärtstrends erzeugt wurde.

img

Wenn sich der D-Wert nach Eröffnung der Position von oben nach unten ändert, glauben wir, dass die Kaufkraft schwächer wird oder die Verkaufskraft stärker wird und das Schließsignal für die Long-Position erzeugt wird; wenn die Short-Position eröffnet wird, ändert sich der D-Wert von unten nach oben, glauben wir, dass die Stärke der Verkaufskraft schwächer wird oder dass die Kaufkraft stärker wird und Schließsignale für die Short-Position erzeugt werden.

Handelsbedingungen

  • Offene Long-Position: Wenn keine Position besteht und der Wert K größer ist als der Wert D

  • Kurze Position: Wenn keine Position besteht und der Wert K kleiner als der Wert D ist

  • Schließung von Long-Positionen: Wenn eine Long-Position gehalten wird und der Wert D kleiner als der Wert D der durchläufigen K-Linie ist

  • Schließung einer Shortposition: Wenn eine Shortposition gehalten wird und der Wert D größer ist als der Wert D der durchläufigen K-Linie

Umsetzung des Strategiecodes

Der erste Schritt bei der Implementierung einer Strategie mit Code ist zuerst zu prüfen, welche Daten wir benötigen? Durch welche API zu erhalten? nachdem wir die Daten bekommen haben, wie die Handelslogik zu berechnen? als nächstes, welche Art und Weise, um die Aufträge zu platzieren? schließlich, lassen Sie uns umsetzen es Schritt für Schritt:

Schritt 1: Verwendung der Strategiearchitektur und der Handelsklassenbibliothek

Die sogenannte Strategie-Architektur ist der Weg, um die gesamte Strategie zu entwerfen. Wie im Folgenden gezeigt, besteht die Architektur aus zwei Funktionen: eine ist die Hauptfunktion, das Programm beginnt von der Hauptfunktion, und seine Funktion besteht darin, mit dem Kern der Strategie-Logik umzugehen. Dinge wie: Beurteilen, ob die Verbindung mit der Börse in Ordnung ist, filtern unnötige Protokollinformationen, Steuerung der Ausführung Zeitintervall der Strategie-Logik-Kerne; und die andere ist die OnTick-Funktion, in dieser Funktion, hauptsächlich ist die Strategie-Logik, bestehend aus: Rohdaten erhalten, Daten berechnen, Aufträge platzieren und mehr.

bool onTick(){  // onTick function
    // strategy logic
}

void main(){ // program starts from here
    while (true){  // enter the loop
        if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
            sleep(1000); // pause for 1 second
            continue; // skip this loop, enter the next loop
        }
        if(!onTick()){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
            sleep(1000); // pause for 1 second
        }
    }
} 

Der obige Code ist das C++ Strategie Framework, das von den FMZ Quant Plattform Tools erstellt wurde. Dies ist ein festes Codierungsformat, alle Handelslogik beginnt von der Zeile 2, und es werden an keiner anderen Stelle Änderungen vorgenommen.

Sie können sich die Bibliothek der Handelsklasse als funktionelles Modul vorstellen. Der Vorteil der Verwendung einer Bibliothek der Handelsklasse besteht darin, dass Sie sich auf das Schreiben von Strategielogik konzentrieren können. Zum Beispiel, wenn wir die Bibliothek der Handelsklasse verwenden, um eine Position zu öffnen oder zu schließen, können wir direkt die API-Schnittstelle in der Bibliothek der Handelsklasse verwenden; aber wenn wir die Bibliothek der Handelsklasse nicht verwenden, müssen wir den Marktpreis beim Öffnen der Position erhalten.

Schritt 2: Erhalten Sie alle möglichen Daten

Die verschiedenen Rohdaten sind ein wichtiger Bestandteil der Handelslogik. Welche Art von Daten benötigen wir? Aus unserer Strategie-Handelslogik müssen wir zunächst K-Liniendaten erhalten. Mit den ursprünglichen K-Liniendaten können wir den KDJ-Indikator berechnen und schließlich die Beziehung zwischen K-Wert und D-Wert vergleichen, um festzustellen, ob Bestellungen platziert werden sollen.

  • Holen Sie die K-Liniendaten.

Zuerst müssen wir das K-Linien-Array erhalten, denn das K-Linien-Array wird verwendet, um den KDJ-Indikator zu berechnen. wie folgt:

double position = 0; // position status parameter, the default is 0 

bool onTick(string symbol){ // onTick function, all strategy logic are in this function
    auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
    if(ct == false){ // if the setting contract type and trading variety is not successful 
        return false; // return false
    }
    auto r = exchange.GetRecords(); // get the k-line array
    if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
        return false; // return false
    }
}

void main(){ // program starts from here
    while (true){  // enter the loop
        if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
            sleep(1000); // pause for 1 second
            continue; // skip this loop, enter the next loop
        }
        if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
            sleep(1000); // pause for 1 second
        }
    }
} 

Wie oben gezeigt:

Zeile 1 : Definiert eine Variable, mit der der Positionsstatus empfangen wird.

Zeilen 3 bis 12 : Eine onTick-Funktion wird definiert, und diese Funktion wird mit einem Parameter übertragen.

Zeilen 14 bis 24 : Definieren Sie eine Hauptfunktion, die nicht-Strategie-Logik verarbeitet. Das Einzige, was geändert werden kann, ist der Vertragskode this_week in Zeile 20, die nicht anderswo geändert werden muss, da dies ein festes Format ist.

Konzentrieren wir uns auf die OnTick-Funktion und sehen wir, wie sie die K-Liniendaten erhält:

Zeilen 4 bis 7 : Angabe des Vertragstyps und der Handelsvariante, wenn die Angabe des Vertragstyps und der Handelsvariante nicht erfolgreich ist, false

Zeile 8: Holen Sie sich ein K-Linien-Array, das ein festes Format ist.

Zeilen 9 bis 11: Filtern Sie die Länge der K-Linie, denn der Parameter, den wir zur Berechnung des KDJ-Indikators verwenden, ist 9. Wenn die Anzahl der K-Linien kleiner als 9 ist, ist es unmöglich, den KDJ-Indikator zu berechnen. Also wollen wir hier die Länge der K-Linie filtern. Wenn die K-Linie kleiner als 10 ist, geben Sie einfach direkt false zurück und warten Sie weiter auf die nächste K-Linie.

  • Erhalten Sie KDJ-Indikatoren, K-Wert und D-Werte

Als nächstes müssen wir die K und D-Werte des KDJ-Indikators berechnen. Zunächst müssen wir ein Array von KDJ-Indikatoren erhalten und aus diesem Array K-Werte und D-Werte erhalten. Auf der FMZ Quant-Plattform ist es sehr einfach, das Array von KDJ zu erhalten, rufen Sie einfach die API von KDJ an, die Schwierigkeit besteht darin, den Wert von K und D-Werten zu erhalten, da das KDJ-Array ein zweidimensionales Array ist.

Das zweidimensionale Array ist eigentlich leicht zu verstehen, das ist ein Array von Arrays, die erhaltenden Sequenzen sind: Erst erhalten Sie das angegebene Array im Array und dann erhalten Sie das angegebene Element aus dem angegebenen Array, wie unten gezeigt:

#include <iostream>
using namespace std;

int main(){
    int hour [3][2] = {{100, 50}, {66, 88}, {10, 90}};
    cout << hours[0][0]; // get the hours array first elements of first element, the result is 100
    cout << hours[0][1]; // get the hours array first elements of second element, the result is 50
    cout << hours[1][0]; // get the hours array second elements of first element, the result is 66
    return(0);
}

Wie in der folgenden Abbildung dargestellt, verwendet die 12. Zeile direkt die API des FMZ Quant, um ein Array von KDJ-Indikatoren zu erhalten, das ein zweidimensionales Array ist: arr = [[K-Wert, K-Wert, K-Wert...], [D-Wert, D-Wert, D-Wert...], [J-Wert, J-Wert, J-Wert...]]

Zeile 13 ist, um den k-Wert der vorherigen K-Zeile zu erhalten, der K-Wert ist arr[0], dann das vorletzte Element von arr[0], arr[0].size() erhalten kann verwendet werden, um die Länge des Arrays von arr[0], arr[0].size() - 2 zu erwerben ist das zweite letzte Element des Arrays, setzen es zusammen sind: auto k = arr [0] [arr [0].size () - 2 ]; die Zeilen 14 und 15 sind die gleiche Berechnung.

double position = 0; // position status parameter, the default is 0 

bool onTick(string symbol){ // onTick function, all strategy logic are in this function
    auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
    if(ct == false){ // if the setting contract type and trading variety is not successful 
        return false; // return false
    }
    auto r = exchange.GetRecords(); // get the k-line array
    if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
        return false; // return false
    }
    auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator 
    auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line 
    auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
    auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
}

void main(){ // program starts from here
    while (true){  // enter the loop
        if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
            sleep(1000); // pause for 1 second
            continue; // skip this loop, enter the next loop
        }
        if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
            sleep(1000); // pause for 1 second
        }
    }
} 

Schritt 3: Bestellungen

Mit den oben genannten Daten können wir jetzt die Handelslogik und den Bestellteil schreiben. Es ist auch sehr einfach, die am häufigsten verwendete ist die if-Anweisung, die so beschrieben werden kann: wenn Bedingung 1 und Bedingung 2 wahr sind, platzieren Sie die Bestellung; wenn Bedingung 3 oder Bedingung 4 wahr sind, platzieren Sie die Bestellung. Wie unten gezeigt:

double position = 0; // position status parameter, the default is 0 

bool onTick(string symbol){ // onTick function, all strategy logic are in this function
    auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
    if(ct == false){ // if the setting contract type and trading variety is not successful 
        return false; // return false
    }
    auto r = exchange.GetRecords(); // get the k-line array
    if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
        return false; // return false
    }
    auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator 
    auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line 
    auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
    auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
    string action; // define a string variable action
    // if currently holding long position, and the previous K line's D value is less than the second last k line's D value, close all position
    // if currently holding short position, and the previous K line's D value is greater than the second last k line's D value, close all position
    if((d < dPre && position > 0) || (d > dPre && position <0)){
        action = "cover";
    }else if (k > d && position <= 0){ // if the previous K line's K value is greater than the previous K line's D value, and there are no long positions
        action = "buy"; // set the variable action to "buy"
    }else if (k < d && position >= 0){ // if the previous K line's K value is less than the previous K line's D value, and there are no short positions
        action = "sell"; // set the variable action to "sell"
    }
    if (action.size() > 0){ // if there are placing order instruction
        position = ext::Trade(action, symbol, 1); // calling the C++ trading class library, placing orders according the direction of variable "action". and also renew the position status. 
    }
    return true; // return true
    } 
}

void main(){ // program starts from here
    while (true){  // enter the loop
        if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
            sleep(1000); // pause for 1 second
            continue; // skip this loop, enter the next loop
        }
        if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
            sleep(1000); // pause for 1 second
        }
    }
} 

In dem obigen Code sind Zeilen 19 bis 28 die Handelslogik und der Code für die Auftragserteilung.

Zeile 19 bis Zeile 21 sind: wenn die aktuelle Long-Position gehalten wird und der vorherige K-Lines D-Wert kleiner als der zweite letzte K-Lines D-Wert ist, schließen Sie alle Positionen, wenn die aktuelle Short-Position gehalten wird und der vorherige K-Lines D-Wert größer als der zweite letzte K-Lines D-Wert ist, schließen Sie alle Positionen. und ändern Sie die Variable action zu cover.

Die Zeilen 21 bis 25 sind: die Bedingungen für die Eröffnung einer Long- und einer Short-Position.

In Zeile 26 bis Zeile 28 wird die Platzierungsorderlogik ausgeführt. Erstens wird nach der Länge der Zeichenfolgevariable action beurteilt, ob eine Anweisung zum Platzieren von Aufträgen vorhanden ist. Ist diese vorhanden, wird der Code in Zeile 27 eingegeben und dann die FMZ Quant-Handelsklassenbibliothek aufrufen und die Platzierungsorderfunktionen vorführen.

Zwei Punkte sind zu beachten:

  1. Versuchen Sie (aber nicht unbedingt), die Strategie-Logik zu schreiben, wenn die aktuelle K-Linie-Bedingung festgelegt wird, und dann die Bestellung auf die nächste K-Linie platzieren. Oder die vorherige K-Linie-Bedingung wird festgelegt, Bestellungen auf die aktuelle K-Linie platzieren, auf diese Weise unterscheiden sich das Ergebnis des Backtests und die tatsächliche Marktleistung nicht viel. Es ist in Ordnung, nicht so zu schreiben, aber achten Sie darauf, ob die Strategie-Logik korrekt ist.

  2. Im Allgemeinen sollte die Logik der Schließposition vor der Öffnungsposition Logik schreiben. Der Zweck davon ist es, zu versuchen, die Strategie Logik Ihre Erwartungen zu erfüllen. Zum Beispiel, wenn die Strategie Logik nur die Situation zu erfüllen, wo es die entgegengesetzte Richtung des Handels nach nur schließen eine Position tun muss, die Regel dieser Art von Situation ist, die Position zuerst zu schließen und dann die neue Position zu öffnen. Wenn wir die Schließposition Logik vor der Öffnungsposition Logik schreiben, wird es perfekt diese Regel erfüllen.

Zusammenfassend

Hier haben wir gelernt, wie man technische KDJ-Indikatoren analysiert und in eine vollständige quantitative Handelsstrategie umwandelt. Dazu gehören: Strategieeinführung, KDJ-Indikatorberechnungsmethode, Strategielogik, Handelsbedingungen, Strategiecode-Implementierung usw. Durch diesen Strategiefall lernen wir nicht nur die C++-Programmiermethode auf der FMZ Quant-Plattform kennen, sondern auch die verschiedenen Strategien können entsprechend den Fällen in diesem Abschnitt angepasst werden.

Um eine quantitative Handelsstrategie zu erreichen, müssen wir unsere eigenen subjektiven Handelserfahrungen oder -systeme zusammenfassen und dann die benötigten Rohdaten separat erhalten, die für die Strategie-Logik benötigten Daten berechnen und schließlich die Platzierungs-Orders API anrufen, um den Handel zu realisieren.

Ankündigung zum nächsten Abschnitt

Bis jetzt ist das Strategie-Schreib-Tutorial in dieser Serie zum Ende gekommen, ich glaube, wenn Sie das Schritt-für-Schritt-Tutorial befolgen, das Sie hierher führt, werden Sie viel gewinnen. Auf jeden Fall ist aus der Perspektive der quantitativen Handelsgrundkurse der lange Weg mehr als halb zurückgegangen. Im letzten Kapitel werden wir Ihnen beibringen, wie Sie die FMZ Quant-Backtesting-Handelsmittel verwenden und wie Sie Pits im Backtest vermeiden und die endgültigen Vorbereitungen für den realen Markthandel treffen können. Obwohl es ein kleiner Teil des Inhalts ist, ist es ein großer Schritt, um in die Welt des quantitativen Handels einzutreten!

Nachschulübungen

  1. Versuchen Sie, den KDJ-Indikator-Algorithmus mit der C++-Sprache auf der FMZ Quant-Plattform zu implementieren.

  2. Versuchen Sie, die in diesem Abschnitt enthaltenen Erkenntnisse für die Erstellung einer CCI-Indikatorstrategie zu nutzen.


Mehr