C++ es un lenguaje de programación muy difícil. La parte difícil es principalmente aprender en profundidad, pero si sólo escribe lógica de estrategia por C++, no necesitará mucho conocimiento profundo, siempre y cuando no sea una estrategia muy complicada.
Para algunas personas, el uso de C++ no significa que sea adecuado para que todos lo usen. La razón es que el lenguaje de programación es solo una herramienta. En el comercio cuantitativo, C++ no es el
Pero entre las instituciones de inversión cuantitativa, la mayor parte del software del sistema de comercio cuantitativo subyacente fue escrito en C++, porque su especificidad única del lenguaje lo hace más eficiente y más rápido que otros lenguajes en algunos aspectos, especialmente en cálculos numéricos. Esto también significa que C++ es más adecuado para derivados financieros y comercio de alta frecuencia.
Para ayudar a todos a entender el contenido de esta sección más rápidamente, antes de introducir el lenguaje C ++, vamos a ver la estrategia que escribió el C ++, para que tenga una comprensión preliminar del concepto de sustantivo en esta sección.
Todos sabemos que el MACD tiene dos curvas, a saber, la línea rápida y la línea lenta, vamos a diseñar una lógica de negociación basada en estas dos líneas.
Posición larga abierta: Si actualmente no hay posición, y la línea rápida es mayor que la línea lenta.
Posición corta abierta: Si actualmente no hay posición y la línea rápida es menor que la línea lenta.
cierre de la posición larga: si se mantiene actualmente una posición larga y la línea rápida es menor que la línea lenta.
Posición corta cerrada: si la posición corta se mantiene en corriente y la línea rápida es mayor que la línea lenta.
Usando el lenguaje C++ para escribir la lógica de estrategia anterior, será como:
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
}
}
}
El código anterior es una estrategia de comercio cuantitativa completa escrita en C ++. Se puede aplicar en el mercado real y colocará automáticamente órdenes. En términos de tamaño de código, es más complicado que otros lenguajes.
Aunque la parte de codificación es un poco más que antes, muchas bibliotecas de clase comercial innecesarias ya se han reducido, y la mayor parte del procesamiento de nivel de sistema subyacente está empaquetado por la plataforma FMZ Quant.
Para los principiantes, el proceso de diseño de toda la estrategia permanece sin cambios: establecer la variedad de mercado, obtener datos de la línea K, obtener información de posición, calcular la lógica de negociación y realizar órdenes.
El identificador es también el nombre. Las variables y nombres de funciones en C++ son sensibles a mayúsculas y minúsculas, lo que significa que la prueba de nombre de variable y la prueba de nombre de variable son dos variables diferentes. El primer carácter del identificador debe ser una letra, un subrayado
mohd zara abc move_name a_123
myname50 _temp j a23b9 retVal
Los comentarios incluyen comentarios de una sola línea y comentarios a nivel de bloque. Los comentarios de una sola línea comienzan con dos barra, comenzando con una barra y un asterisco ( /* ), terminando con un asterisco y una barra ( */ ), como se muestra a continuación:
// this is a single-line comment
/*
* this is a multiple-line comment
* block-level comments
*
*/
En C++, el punto y coma es el terminador de la instrucción. Es decir, cada instrucción debe terminar con un punto y coma. Indica el final de una entidad lógica.
x = y;
y = y + 1;
add(x, y);
Una variable es un área de almacenamiento operacional. Para definir una variable en C++, primero debe definir el tipo de la variable. En el desarrollo de estrategias de negociación cuantitativas, los tipos que usamos comúnmente son: entero (int ), flotante (doble ), cadena (cuadrícula) y tipo de derivación automática (auto ).
Los enteros se pueden entender como números enteros; los tipos de coma flotante se pueden entender como números con puntos decimales; las cadenas son literales, pueden ser caracteres en inglés u otros idiomas.
A veces cuando llamamos a una API, pero no sabemos si esta API nos dará qué tipo de datos para devolver, por lo que el uso del tipo de derivación automática (auto) nos ayudará a determinar automáticamente el tipo de datos.
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
Una matriz es un contenedor para almacenar datos. Una matriz C++ puede almacenar una colección de orden fijo de elementos del mismo tipo con un tamaño fijo. Así que en C++, para declarar una matriz, es necesario especificar el tipo de elemento y el número de elementos. Todas las matrices tienen un índice de 0 como su primer elemento.
// 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
Una función es un conjunto de instrucciones que ejecutan una tarea juntas. La declaración de una función incluye: el nombre de la función, el tipo de retorno y los parámetros. El tipo de retorno es el tipo de datos devuelto cuando se ejecuta la función cuando llamo a esta función; el parámetro es opcional, y la función también no puede contener parámetros. Cuando se llama a la función, también se puede pasar un parámetro a la función.
// 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
}
El operador de asignación es el operador matemático de suma, resta, multiplicación y división. El operador relacional puede comparar si los dos valores son más pequeños o más grandes. Los operadores lógicos incluyen principalmente: lógico AND, lógico OR y lógico no. El operador de asignación es la asignación variable que hablamos anteriormente.
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;
}
Si hay una expresión 100*(10-1)/(10+5), ¿qué paso se calcula primero en el programa? Matemáticas de la escuela media nos dice: Si es el mismo nivel de operación, generalmente se calcula de izquierda a derecha; Si hay adiciones y sustracciones, y multiplicación y división, primero calcule la multiplicación y división, luego agregue y resta; Si hay corchetes, primero calcule el interior de los corchetes; Si se cumple la ley de operación, la ley de cálculo se puede usar para el cálculo. el mismo principio anterior para C ++, como se muestra a continuación:
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
Por lo general, cuando escribimos código, siempre necesitamos realizar diferentes acciones para diferentes decisiones. podemos usar instrucciones condicionales en nuestro código para lograr esta tarea. En C++, podemos usar las siguientes instrucciones condicionales:
Si la instrucción - Utilice esta instrucción para ejecutar el código sólo si la condición especificada es verdadera
Si...else instrucción - ejecutar código si la condición especificada es verdadera, el otro código ejecutado cuando la condición es falsa
If...else if...else instrucción - utilizar esta instrucción para seleccionar uno de los múltiples bloques de código para ejecutar
Switch instruction - Utilice esta instrucción para seleccionar uno de los bloques de código múltiples para ejecutar
Esta instrucción sólo ejecuta el código si la condición especificada es verdadera. Por favor, use una letra pequeña si. Usar una letra mayúscula (IF) generará un error en C++! Como se muestra a continuación:
// 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
}
código de ejecución si la condición especificada es verdadera, el otro código ejecutado cuando la condición es falsa, como se muestra a continuación:
//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
}
Utilice esta instrucción para seleccionar uno de varios bloques de código para ejecutar
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
}
El bucle For puede ejecutar N veces de bloques de código repetidamente, y su flujo de ejecución es el siguiente (como se muestra a continuación):
for (int a = 10; a < 20; a++){
// code block
}
Paso 1: ejecutar int a = 0 y sólo ejecutar una vez.
Paso 2: Ejecutar a<20. Si es verdadero, ejecutar el bloque de código de la línea 2.
Paso 3: ejecutar a ++, después de ejecutar a ++, a se convierte en 11.
Paso 4: ejecuta a<20 de nuevo, y los pasos segundo, tercero y cuarto se ejecutarán repetidamente. Hasta que a<20 sea falso, si es falso, el bloque de código de la línea 2 no se ejecutará, y todo el bucle for se termina.
Todos sabemos que el mercado está cambiando constantemente. Si quieres obtener la última matriz K-line, tienes que ejecutar constantemente el mismo código una y otra vez. Luego usar el bucle while es la mejor opción. Mientras la condición especificada sea cierta, el bucle continuará obteniendo los últimos datos de la matriz k-line.
void main() {
auto ct = exchange.SetContractType(symbol); //set the trading variety
while(true) {
auto r = exchange.GetRecords(); // constantly getting k-line arrays
}
}
Los bucles tienen condiciones previas. Solo cuando esta condición es "verdadera", el bucle comenzará a hacer algo repetidamente, hasta que la condición es "falsa", el bucle terminará. Pero usando la instrucción break se puede saltar del bucle inmediatamente durante la ejecución del bucle;
# 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
La instrucción continue también salta del bucle, pero no salta de todo el bucle. En su lugar, interrumpa un bucle y continúa al siguiente. Como se muestra a continuación, cuando a es igual a 2, el bucle se interrumpe y el siguiente bucle se continúa hasta que la condición previa del bucle sea "falsa" para saltar de todo el bucle.
# 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
La instrucción de retorno termina la ejecución de la función y devuelve el valor de la función. ¡La instrucción de retorno solo puede aparecer en el cuerpo de la función y cualquier otro lugar en el código causará un error de sintaxis!
# 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;
}
En la plataforma FMZ Quant, sería muy conveniente escribir una estrategia en C ++. El FMZ Quant tiene muchos marcos de estrategia estándar incorporados oficialmente y bibliotecas de clases comerciales, como las siguientes:
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
}
}
}
Como se muestra anteriormente, este es un marco de estrategia estándar, y estos formatos están fijos. Utilice el marco para escribir una estrategia. Solo necesita escribir la lógica de la estrategia desde la segunda línea.
Lo anterior es el contenido del lenguaje C ++ de inicio rápido. Si necesita escribir una estrategia más compleja, consulte la documentación de la API del lenguaje C ++ de la plataforma FMZ Quant, o consulte directamente al servicio oficial de atención al cliente sobre el servicio de escritura.
La clave para la negociación cuantitativa es la estrategia de negociación, no las herramientas de negociación (lenguaje de programación).