C++ est un langage de programmation très difficile. La partie la plus difficile est principalement d'apprendre en profondeur, mais si vous écrivez simplement la logique de stratégie par C++, cela ne nécessitera pas beaucoup de connaissances approfondies, tant que ce n'est pas une stratégie très compliquée. Apprendre quelques bases sera suffisant.
Pour certaines personnes, l'utilisation de C++ ne signifie pas qu'il convient à tout le monde de l'utiliser. La raison en est que le langage de programmation n'est qu'un outil. Dans le trading quantitatif, C++ n'est pas le "must-required". Si vous préférez utiliser le langage de programmation de script, comme Python ou C++, vous pouvez économiser beaucoup de temps et d'énergie, ce qui peut être utilisé pour vous concentrer sur la conception de la stratégie.
Mais parmi les institutions d'investissement quantitatives, la plupart des logiciels de système de trading quantitatif sous-jacents ont été écrits en C++, car sa spécificité linguistique unique le rend plus efficace et plus rapide que les autres langages à certains égards, en particulier dans les calculs numériques.
Afin d'aider tout le monde à comprendre le contenu de cette section plus rapidement, avant d'introduire le langage C++, examinons la stratégie écrite par le C++, afin que vous ayez une compréhension préliminaire du concept de nom dans cette section.
Nous savons tous que le MACD a deux courbes, à savoir la ligne rapide et la ligne lente, nous allons concevoir une logique de trading basée sur ces deux lignes.
Position longue ouverte: si aucune position n'existe actuellement et que la ligne rapide est supérieure à la ligne lente.
Position ouverte à court terme: si aucune position n'existe actuellement et que la ligne rapide est inférieure à la ligne lente.
position longue fermée: si la position longue est actuellement maintenue et que la ligne rapide est inférieure à la ligne lente.
position courte fermée: si la position courte actuelle est maintenue et que la ligne rapide est supérieure à la ligne lente.
Utiliser le langage C++ pour écrire la logique de stratégie ci-dessus, sera comme ceci:
double position = 0; //Position status parameter, the default position is 0
uint64_t lastSignalTime = 0; // Last signal trigger time
bool onTick(string symbol) { // onTick function, inside the function is the strategy logic
auto ct = exchange.SetContractType(symbol); // set the trading variety
if (ct == false) { // if setting the trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k line array
if (!r.Valid || r.sizeO < 20) { // if get the k line array is not successful or the number of k line is less than 20
return false; // return false
}
auto signalTime = r[r.size() - 2].Time; // get the previous k line time
if (signalTime <= lastSignalTime) { // if the previous k line time is less than or equal to the last trigger signal time
return false; // return false
}
auto macd = TA.MACD(r); // calculate the MACD indicator
auto slow = macd[0][macd[0].size() - 2]; // get the previous k line MACD value
auto fast = macd[l][macd[l].size() - 2]; // get the previous k line MACD average value
string action; // define a string variable action
if (fast >= slow && position <= 0) { // if the previous k line macd value is greater than or equal to the previous k line macd average value, and there are no long position holding
action = "buy"; // assign buy to the variable action
} else if (fast <= slow && position >= 0) { // if the previous k line macd value is less than or equal to the previous k line macd average value, and there are no short position holding
action = "sell"; // assign sell to the variable action
}
if (actton.size() > 0) { // If there are orders for placing order
If (position != 0) { // If there are holding position
ext::Trade("cover", symbol); // call the C++ trading class library and close all position
}
position = ext::Trade(action, symbol, 1); // call the C++ trading class library, placing orders according the direction of variable "action", and renew the position status
lastSignalTime = signalTime; // reset the time of last trigger signal
}
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 is not successful
Sleep(1000); // pause for 1 second
continue; // skip this loop, continue to the next loop
}
if (!onTtck("this_week")) { // if the connection is ok, enter the if loop and start to execute the onTick function
Sleep(1000); // pause for 1 second
}
}
}
Le code ci-dessus est une stratégie de trading quantitative complète écrite en C++. Il peut être appliqué sur le marché réel et va automatiquement passer des commandes. En termes de taille du code, il est plus compliqué que les autres langages. Parce que le langage C++ est principalement pour le développement de stratégie à haute fréquence sur la plateforme FMZ Quant.
Bien que la partie de codage soit un peu plus importante qu'auparavant, de nombreuses bibliothèques de classes de trading inutiles ont déjà été réduites, et la plupart du traitement au niveau du système sous-jacent est condensé par la plate-forme FMZ Quant.
Pour les débutants, le processus de conception de l'ensemble de la stratégie reste inchangé: définition de la variété de marché, obtention de données de ligne K, obtention d'informations de position, calcul de la logique de négociation et placement des ordres.
L'identifiant est également le nom. Les variables et les noms de fonctions en C++ sont sensibles à la case, ce qui signifie que le test de nom de variable et le test de nom de variable sont deux variables différentes. Le premier caractère de l'identifiant doit être une lettre, un soulignement
mohd zara abc move_name a_123
myname50 _temp j a23b9 retVal
Les commentaires comprennent les commentaires d'une seule ligne et les commentaires au niveau du bloc. Les commentaires d'une seule ligne commencent par deux traits, commençant par un trait et un astérisque ( /* ), se terminant par un astérisque et un trait ( */ ), comme indiqué ci-dessous:
// this is a single-line comment
/*
* this is a multiple-line comment
* block-level comments
*
*/
En C++, le point-virgule est le terminateur d'instruction. C'est-à-dire que chaque instruction doit se terminer par un point-virgule. Il indique la fin d'une entité logique. Par exemple, voici trois instructions différentes:
x = y;
y = y + 1;
add(x, y);
Une variable est un espace de stockage opérationnel. Pour définir une variable en C++, vous devez d'abord définir le type de la variable. Dans le développement de stratégies de trading quantitatives, nous utilisons couramment des types: entier (int ), flottant (double ), chaîne (chaîne) et type de dérivation automatique (auto ).
Les entiers peuvent être compris comme des nombres entiers; les types de virgule flottante peuvent être compris comme des nombres avec des virgules décimales; les chaînes sont littérales, peuvent être des caractères anglais ou d'autres langues.
Parfois, lorsque nous appelons une API, mais nous ne savons pas si cette API va nous donner quel type de données à retourner, donc en utilisant le type de dérivation automatique (auto) nous aidera à déterminer automatiquement le type de données.
int numbers = 10; // use int to define a integer variable and assign 10 to this variable
double PI = 3.14159; // use double to define a float variable and assign 10 to this variable
string name = "FMZ Quant"; // use string to define a string variable and assign "FMZ Quant" to this variable
auto bar = exchange.GetRecords(); // use auto to define a variable (automatic derivation type) and assign k line array to this variable
Un tableau est un conteneur pour stocker des données. Un tableau en C++ peut stocker une collection d'éléments du même type dans un ordre fixe avec une taille fixe. Ainsi, en C++, pour déclarer un tableau, vous devez spécifier le type d'élément et le nombre d'éléments. Tous les tableaux ont un indice de 0 comme premier élément. Pour obtenir les premières données dans le tableau est " [0] ", la deuxième est " [1] ", et ainsi de suite, comme le montre le tableau ci-dessous:
// define a array, array name is balance. there are 5 floating(double) type data inside it
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
double salary = balance[0]; // get the first data in the array, the result is : 1000.0
double salary = balance[1]; // get the second data in the array, the result is : 2.0
Une fonction est un ensemble d'instructions qui exécutent une tâche ensemble. La déclaration d'une fonction comprend: le nom de la fonction, le type de retour et les paramètres. Le type de retour est le type de données retourné lorsque la fonction est exécutée lorsque j'appelle cette fonction; le paramètre est facultatif, et la fonction ne peut pas non plus contenir de paramètres. Lorsque la fonction est appelée, vous pouvez également passer un paramètre à la fonction. Regardez l'exemple suivant:
// create a function called "max"
// when this function is called, it returns the int type data
// this function has 2 parameters, and they both are int type
// this function is for passing 2 int type numbers, and return the bigger one
int max(int num1, int num2) {
int result; // define a int variable result
if (num1 > num2) // if the num1 > num2
result = num1; // assign the value of num1 to result
else // otherwise
result = num2; // assign the value of num2 to result
return result; // return the value of result
}
En utilisant C++ pour écrire des stratégies de trading quantitatives, il existe trois opérateurs couramment utilisés: opérateurs arithmétiques, opérateurs relationnels, opérateurs logiques et opérateurs d'affectation. L'opérateur arithmétique est l'opération mathématique d'addition, soustraction, multiplication et division. L'opérateur relationnel peut comparer si les deux valeurs sont plus petites ou plus grandes. Les opérateurs logiques comprennent principalement: logique AND, logique OR et logique non. L'opérateur d'affectation est l'affectation variable dont nous avons parlé plus tôt. Comme indiqué ci-dessous:
int main() {
// arithmetic operator
int a = 10;
int b = 5;
a + b; // the result is 15
a - b; // the result is 5
a * b; // the result is 50
a / b; // the result is 2
a % b; // the result is 0
a++; // the result is 11
a--; // the result is 9
// relational operators
a == b; // the result is false
a != b; // the result is true
a >= b; // the result is true
a <= b; // the result is false
logical operators
true && true // the result is true
true && false // the result is false
false || false // the result is false
true || false // the result is true
!(true) // the result is false
!(false) // the result is true
return 0;
}
S'il y a une expression 100*(10-1)/(10+5, quelle étape le programme calcule-t-il d'abord? Les mathématiques du collège nous disent: s'il s'agit du même niveau d'opération, elle est généralement calculée de gauche à droite; s'il y a des addition et soustractions, et des multiplication et division, calculez d'abord la multiplication et la division, puis additionnez et soustraisez; s'il y a des parenthèses, calculez d'abord l'intérieur des parenthèses; si la loi d'opération est respectée, la loi de calcul peut être utilisée pour le calcul. le même principe ci-dessus pour C++, comme indiqué ci-dessous:
auto num = 100*(10-1)/(10+5); // the value of num is 60
1 > 2 && (2 > 3 || 3 < 5); // the result is : false
1 > 2 && 2 > 3 || 3 < 5; // the result is : true
En général, lorsque nous écrivons du code, nous avons toujours besoin d'effectuer différentes actions pour différentes décisions. nous pouvons utiliser des instructions conditionnelles dans notre code pour accomplir cette tâche.
Si instruction - Utilisez cette instruction pour exécuter du code uniquement si la condition spécifiée est vraie
If...else instruction - exécuter le code si la condition spécifiée est vraie, l'autre code exécuté lorsque la condition est fausse
If...else if...else instruction - utilisez cette instruction pour sélectionner un des plusieurs blocs de code à exécuter
Commande de commutation - Utilisez cette instruction pour sélectionner l'un des plusieurs blocs de code à exécuter
Cette instruction n'exécute le code que si la condition spécifiée est vraie. Veuillez utiliser une minuscule si. L'utilisation d'une majuscule (IF) générera une erreur C++! Comme indiqué ci-dessous:
// grammar
if (condition) {
//execute code only if the condition is true
}
//example
if (time<20) { // if current time is less than 20:00
x = "Good day"; // when the time is less that 20:00, assign the "good day" to x
}
code exécuté si la condition spécifiée est vraie, l'autre code exécuté si la condition est fausse, comme indiqué ci-dessous:
//grammar
if (condition) {
// execute code if the condition is true
} else {
// the other code executed when the condition is false
}
//example
if (time<20) { // if current time is less than 20:00
x = "Good day"; // when the time is less that 20:00, assign the "good day" to x
} else { // otherwise
x = "Good evening"; // assign the "Good evening" to x
}
Utilisez cette instruction pour sélectionner un des plusieurs blocs de code à exécuter
switch (condition)
{
case 1: // code to be executed if condition = 1;
break;
case 2: // code to be executed if condition = 2;
break;
default: // code to be executed if condition doesn't match any cases
}
La boucle For peut exécuter N fois de blocs de code à plusieurs reprises, et son flux d'exécution est le suivant (comme indiqué ci-dessous):
for (int a = 10; a < 20; a++){
// code block
}
Étape 1: Exécuter int a = 0 et exécuter une seule fois. Son but est de déclarer une variable entière et de l'initialiser à 0 pour contrôler la boucle for.
Étape 2: Exécuter a<20. Si c'est vrai, exécuter le bloc de code de la ligne 2.
Étape 3: Exécuter un ++, après avoir exécuté un ++, un devient 11.
Étape 4: exécutez a<20 à nouveau, et les deuxième, troisième et quatrième étapes s'exécuteront à plusieurs reprises.
Nous savons tous que le marché est en constante évolution. Si vous voulez obtenir le dernier tableau de lignes K, vous devez exécuter constamment le même code encore et encore. Ensuite, utiliser la boucle while est le meilleur choix. Tant que la condition spécifiée est vraie, la boucle continuera à obtenir les dernières données de tableau de lignes K.
void main() {
auto ct = exchange.SetContractType(symbol); //set the trading variety
while(true) {
auto r = exchange.GetRecords(); // constantly getting k-line arrays
}
}
Les boucles ont des conditions préalables. Seulement lorsque cette condition préalable est " vrai ", la boucle commencera à faire quelque chose à plusieurs reprises, jusqu'à ce que la condition préalable soit " faux ", la boucle se terminera. Mais en utilisant l'instruction break, vous pouvez sauter de la boucle immédiatement pendant l'exécution de la boucle;
# including <iostream>
using namespace std;
int main() {
for(int a = 0; a < 5; a++) {
if(a == 2) break;
cout << a << endl;
}
return 0;
}
// print out : 0, 1
L'instruction continue saute également de la boucle, mais elle ne saute pas de la boucle entière. Au lieu de cela, interrompez une boucle et continuez à la boucle suivante. Comme indiqué ci-dessous, lorsque a est égal à 2, la boucle est interrompue et la boucle suivante est poursuivie jusqu'à ce que la précondition de la boucle soit " fausse " pour sauter de la boucle entière.
# including <iostream>
using namespace std;
int main() {
for(int a = 0; a < 5; a++) {
if(a == 2) continue;
cout << a << endl;
}
return 0;
}
// print out : 0, 1, 3, 4
L'instruction de retour termine l'exécution de la fonction et renvoie la valeur de la fonction. L'instruction de retour ne peut apparaître que dans le corps de la fonction, et tout autre endroit dans le code provoquera une erreur de syntaxe!
# including <iostream>
using namespace std;
int add(int num1, int num2) {
return num1 + num2; // The add function returns the sum of two parameters
}
int main()
{
cout << add(5, 10); // call the add function, and print out the result:50
return 0;
}
Sur la plateforme FMZ Quant, il serait très pratique d'écrire une stratégie en C++. Le FMZ Quant a beaucoup de cadres de stratégie standard officiellement intégrés et de bibliothèques de classes de trading, telles que les suivantes:
bool onTick() { //onTick function
// strategy logic
}
void main() { // program starts from here
while (true) { // enter the loop
if (exchange.IO("status") == 0) { // if the exchange connection is not stable
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if (!onTick()) { // if the exchange connection is stable, enter this if statement, start to execute the onTick function
sleep(1000);// pause for 1 second
}
}
}
Comme indiqué ci-dessus, il s'agit d'un framework de stratégie standard, et ces formats sont fixes. Utilisez le framework pour écrire une stratégie. Vous n'avez qu'à écrire la logique de la stratégie à partir de la deuxième ligne.
Si vous avez besoin d'écrire une stratégie plus complexe, veuillez vous référer à la documentation de l'API de la langue C ++ de la plate-forme FMZ Quant, ou consultez directement le service client officiel sur le service de rédaction.
La clé du trading quantitatif est la stratégie de trading, pas les outils de trading (langage de programmation).