C++ é uma linguagem de programação muito difícil. A parte difícil é principalmente aprender em profundidade, mas se você apenas escrever lógica de estratégia por C++, não precisará de muito conhecimento profundo, desde que não seja uma estratégia muito complicada.
Para algumas pessoas, usar C++ não significa que seja adequado para todos usá-lo. A razão é que a linguagem de programação é apenas uma ferramenta. Na negociação quantitativa, o C++ não é o
Mas entre as instituições de investimento quantitativo, a maioria do software do sistema de negociação quantitativo subjacente foi escrito em C ++, porque sua especificidade linguística única o torna mais eficiente e mais rápido do que outras linguagens em alguns aspectos, especialmente em cálculos numéricos.
A fim de ajudar todos a entender o conteúdo desta seção mais rapidamente, antes de introduzir a linguagem C ++, vamos olhar para a estratégia que foi escrita pelo C ++, para que você tenha uma compreensão preliminar do conceito de substantivo nesta seção.
Todos nós sabemos que o MACD tem duas curvas, ou seja, a linha rápida e a linha lenta, vamos projetar uma lógica de negociação baseada nessas duas linhas. Quando a linha rápida atravessa a linha lenta, abra uma posição longa; quando a linha rápida atravessa a linha lenta, abra uma posição curta.
Posição longa aberta: se não houver posição e a linha rápida for maior que a linha lenta.
Posição curta aberta: se não houver posição e a linha rápida for inferior à linha lenta.
fechar posição longa: se estiver a manter uma posição longa e a linha rápida for inferior à linha lenta.
posição curta de fechamento: se a posição curta de atualização for mantida e a linha rápida for superior à linha lenta.
Usando a linguagem C ++ para escrever a lógica estratégica acima, 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
}
}
}
O código acima é uma estratégia de negociação quantitativa completa escrita em C ++. Pode ser aplicada no mercado real e irá automaticamente colocar ordens. Em termos de tamanho do código, é mais complicado do que outras linguagens. Porque a linguagem C ++ é principalmente para desenvolvimento de estratégia de alta frequência na plataforma FMZ Quant.
Embora a parte de codificação seja um pouco mais do que antes, muitas bibliotecas de classes comerciais desnecessárias já foram reduzidas, e a maior parte do processamento de nível de sistema subjacente é empacotado pela plataforma FMZ Quant.
Para os iniciantes, o processo de concepção de toda a estratégia permanece inalterado: definição da variedade de mercado, obtenção de dados de linha K, obtenção de informações de posição, cálculo da lógica de negociação e colocação de ordens.
O identificador é também o nome. As variáveis e os nomes das funções em C++ são sensíveis a maiúsculas e minúsculas, o que significa que o teste do nome da variável e o teste do nome da variável são duas variáveis diferentes. O primeiro caractere do identificador deve ser uma letra, um sublinhado
mohd zara abc move_name a_123
myname50 _temp j a23b9 retVal
Os comentários de linha única começam com dois traços, começando com um traço e um asterisco ( /* ), terminando com um asterisco e um traço ( */ ), como mostrado a seguir:
// this is a single-line comment
/*
* this is a multiple-line comment
* block-level comments
*
*/
Em C++, o ponto e vírgula é o terminador da instrução. Ou seja, cada instrução deve terminar com um ponto e vírgula. Indica o fim de uma entidade lógica. Por exemplo, aqui estão três instruções diferentes:
x = y;
y = y + 1;
add(x, y);
Uma variável é uma área de armazenamento operacional. Para definir uma variável em C++, você deve primeiro definir o tipo da variável. No desenvolvimento de estratégias de negociação quantitativas, nós comumente usamos tipos são: inteiro (int ), flutuante (double ), string (string) e tipo de derivação automática (auto ).
Os números inteiros podem ser entendidos como números inteiros; os tipos de ponto flutuante podem ser entendidos como números com pontos decimais; as cadeias são literais, podem ser caracteres em inglês ou em outras línguas.
Às vezes, quando chamamos uma API, mas não sabemos se esta API nos dará que tipo de dados para retornar, então usando o tipo de derivação automática (auto) nos ajudará a determinar automaticamente o tipo de dados.
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
Uma matriz é um contêiner para armazenar dados. Uma matriz C++ pode armazenar uma coleção de ordem fixa de elementos do mesmo tipo com um tamanho fixo. Assim, em C++, para declarar uma matriz, você precisa especificar o tipo de elemento e o número de elementos. Todas as matrias têm um índice de 0 como seu primeiro elemento. Para obter os primeiros dados na matriz é " [0] ", o segundo é " [1] ", e assim por diante, como mostra a seguir:
// 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
Uma função é um conjunto de instruções que executam uma tarefa juntas. A declaração de uma função inclui: o nome da função, o tipo de retorno e os parâmetros. O tipo de retorno é o tipo de dados devolvido quando a função é executada quando eu chamo esta função; o parâmetro é opcional, e a função também não pode conter parâmetros. Quando a função é chamada, você também pode passar um parâmetro para a função. Veja o exemplo a seguir:
// 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
}
Usando o C++ para escrever estratégias quantitativas de negociação, existem três operadores comumente usados: operadores aritméticos, operadores relacionais, operadores lógicos e operadores de atribuição. O operador aritmético é a operação matemática de adição, subtração, multiplicação e divisão. O operador relacional pode comparar se os dois valores são menores ou maiores. Os operadores lógicos incluem principalmente: AND lógico, OR lógico e não lógico. O operador de atribuição é a atribuição variável que falamos 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;
}
Se houver uma expressão 100*(10-1)/(10+5), qual é o primeiro passo calculado pelo programa? Matemática do ensino médio nos diz: Se for o mesmo nível de operação, geralmente é calculado da esquerda para a direita; Se houver adições e subtrações, e multiplicação e divisão, primeiro calcule a multiplicação e divisão, em seguida, adicione e subtraia; Se houver parênteses, primeiro calcule o interior dos parênteses; Se a lei de operação for cumprida, a lei de cálculo pode ser usada para o cálculo. O mesmo princípio acima para C ++, como mostrado abaixo:
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
Normalmente, quando escrevemos código, precisamos sempre executar ações diferentes para decisões diferentes. podemos usar instruções condicionais em nosso código para realizar essa tarefa. Em C++, podemos usar as seguintes instruções condicionais:
Se instrução - Use esta instrução para executar código somente se a condição especificada for verdadeira
Se...else instrução - executar código se a condição especificada é verdadeira, o outro código executado quando a condição é falsa
Se...se...se outra instrução - use esta instrução para selecionar um de vários blocos de código para executar
Switch instrução - Use esta instrução para selecionar um dos múltiplos blocos de código para executar
Esta instrução executa o código apenas se a condição especificada for verdadeira. Por favor, use uma minúscula se. Usando uma letra maiúscula (IF) gerará um erro C++! Como mostrado abaixo:
// 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 executado se a condição especificada for verdadeira, o outro código executado quando a condição for falsa, conforme mostrado abaixo:
//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
}
Use esta instrução para selecionar um de vários blocos de código para executar
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
}
O loop For pode executar N vezes de blocos de código repetidamente, e seu fluxo de execução é assim (como mostrado abaixo):
for (int a = 10; a < 20; a++){
// code block
}
Passo 1: executar int a = 0 e executar apenas uma vez.
Passo 2: Execute a<20. Se for verdade, execute o bloco de código da linha 2.
Passo 3: Execute a ++, depois de executar a ++, a torna-se 11.
Passo 4: Execute a <20 novamente, e os segundos, terceiro e quarto passos serão executados repetidamente.
Todos nós sabemos que o mercado está em constante mudança. Se você quiser obter o mais recente K-line array, você tem que executar constantemente o mesmo código repetidamente. Então usar o while loop é a melhor escolha. Enquanto a condição especificada for verdadeira, o loop continuará a obter os dados mais recentes k-line array.
void main() {
auto ct = exchange.SetContractType(symbol); //set the trading variety
while(true) {
auto r = exchange.GetRecords(); // constantly getting k-line arrays
}
}
Os loops têm pré-condições. Somente quando essa pré-condição é "true", o loop começará a fazer algo repetidamente, até que a pré-condição seja "false", o loop terminará.
# 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
A instrução continue também salta do loop, mas não salta de todo o loop. Em vez disso, interrompa um loop e continue para o próximo loop. Como mostrado abaixo, quando a é igual a 2, o loop é interrompido e o próximo loop é continuado até que a pré-condição do loop seja "falsa" para saltar de todo o loop.
# 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
A instrução de retorno termina a execução da função e retorna o valor da função. A instrução de retorno só pode aparecer no corpo da função e qualquer outro lugar no código causará um erro de sintaxe!
# 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;
}
Na plataforma FMZ Quant, seria muito conveniente escrever uma estratégia em C ++. O FMZ Quant tem um monte de estruturas de estratégia padrão oficialmente incorporadas e bibliotecas de classes de negociação, como as seguintes:
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 mostrado acima, esta é uma estrutura de estratégia padrão, e esses formatos são fixos. Use a estrutura para escrever uma estratégia. Você só precisa escrever a lógica de estratégia a partir da segunda linha. Outra aquisição de mercado e processamento de pedidos são tratados pela estrutura e as bibliotecas de classe de negociação, você só precisa se concentrar no desenvolvimento de estratégia.
O acima é o conteúdo da linguagem C ++ início rápido. Se você precisa escrever uma estratégia mais complexa, consulte a documentação da plataforma FMZ Quant API da linguagem C ++, ou consulte diretamente o serviço oficial de atendimento ao cliente sobre o serviço de escrita
A chave para a negociação quantitativa é a estratégia de negociação, não as ferramentas de negociação (linguagem de programação).