4.5 Lenguaje C++ Inicio rápido

El autor:La bondad, Creado: 2019-04-30 08:50:54, Actualizado:

Resumen de las actividades

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.

img

¿Por qué deberíamos elegir C ++ para el comercio cuantitativo?

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 requerido . Si prefiere usar el lenguaje de programación de script, como Python o C++, puede ahorrar mucho tiempo y energía, que se puede usar para centrarse en el diseño de la estrategia.

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.

Estrategia completa

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.

img

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.

Identificador

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 _, y los siguientes caracteres también pueden ser números, como se muestra a continuación:

mohd    zara    abc    move_name    a_123
myname50    _temp    j    a23b9    retVal

Comentario

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
 *
 */

Bloqueo de puntos y semicolones y declaraciones

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);

Variable

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

Array

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

Función

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

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;
}

Prioridad

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

Declaraciones condicionales

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

Declaración de si

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
}

Si... otra declaración

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
}

Declaración de cambio

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
}

Para el bucle

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.

Mientras Loop

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
    }
} 

Declaración de ruptura

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

Continuar la declaración

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

Declaración de devolución

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;
}

Arquitectura estratégica

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.

En resumen

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.

Notificación de la siguiente sección

La clave para la negociación cuantitativa es la estrategia de negociación, no las herramientas de negociación (lenguaje de programación).

Ejercicios extraescolares

  • Trata de obtener datos históricos de la línea K usando el lenguaje C++ en la plataforma FMZ Quant.
  • Trate de escribir el código de la estrategia al principio de esta sección, seguido de comentarios específicos.

Más.