C++ - очень сложный язык программирования. Трудная часть в основном заключается в глубоком изучении, но если вы просто пишете стратегическую логику на C++, это не потребует больших глубоких знаний, пока это не очень сложная стратегия. Узнать некоторые основы будет достаточно.
Для некоторых людей использование C++ не означает, что он подходит для всех. Причина в том, что язык программирования - это просто инструмент. В количественной торговле C++ не является обязательным. Если вы предпочитаете использовать язык скриптового программирования, такой как Python или C++, вы можете сэкономить много времени и энергии, которые можно использовать для сосредоточения на разработке стратегии.
Но среди количественных инвестиционных учреждений большинство программ для базовых количественных торговых систем было написано на C++, потому что его уникальная специфика языка делает его более эффективным и быстрым, чем другие языки в некоторых аспектах, особенно в численных расчетах.
Чтобы помочь всем понять содержание этого раздела быстрее, прежде чем ввести язык C++, давайте посмотрим на стратегию, написанную C++, чтобы у вас было предварительное понимание понятия существительного в этом разделе.
Мы все знаем, что MACD имеет две кривые, а именно быструю линию и медленную линию, давайте разработаем логику торговли на основе этих двух линий. Когда быстрая линия пересекает медленную линию, открыть длинную позицию; когда быстрая линия пересекает медленную линию, открыть короткую позицию.
Открытая длинная позиция: если в настоящее время нет позиции, и быстрая линия больше медленной линии.
Открытая короткая позиция: если в настоящее время нет позиции, и быстрая линия меньше медленной линии.
закрыть длинную позицию: если в настоящее время держите длинную позицию, и быстрая линия меньше медленной линии.
закрыть короткую позицию: если текущая позиция держится короткой, и быстрая линия больше медленной линии.
Использование языка C++ для написания логики вышеуказанной стратегии будет выглядеть так:
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
}
}
}
Код выше является полной количественной торговой стратегии, написанной на C ++. Он может быть применен на реальном рынке и будет автоматически размещать заказы. С точки зрения размера кода, это более сложно, чем другие языки. Потому что язык C ++ в основном для высокочастотного развития стратегии на платформе FMZ Quant.
Хотя часть кодирования немного больше, чем раньше, так много ненужных торговых классов библиотек были уменьшены уже, и большая часть базовых системного уровня обработки упакована FMZ Quant платформы.
Для новичков процесс разработки всей стратегии остается неизменным: установка рыночного сорта, получение данных K-линии, получение информации о позиции, вычисление логики торговли и размещение заказов.
Идентификатор - это также имя. Переменные и имена функций в C++ чувствительны к буквам, что означает, что тест имени переменной и тест имени переменной - это две разные переменные. Первым символом идентификатора должна быть буква, подчерк
mohd zara abc move_name a_123
myname50 _temp j a23b9 retVal
Комментарии включают комментарии на уровне одной строки и комментарии на уровне блока. Комментарии на одной строке начинаются с двух запятой, начиная с запятой и звездочкой ( /* ), заканчивая звездочкой и запятой ( */ ), как показано ниже:
// this is a single-line comment
/*
* this is a multiple-line comment
* block-level comments
*
*/
В C++, запятая является терминатором заявления. То есть, каждое заявление должно заканчиваться запятой. Это указывает на конец логической сущности. Например, вот три различных заявления:
x = y;
y = y + 1;
add(x, y);
Переменная - это операционная область хранения. Чтобы определить переменную в C++, сначала необходимо определить тип переменной. В разработке количественных торговых стратегий мы обычно используем типы: integer (int ), float (double ), string (string) и тип автоматического вывода (auto ).
Целые числа можно понимать как целые числа; типы плавающих знаков можно понимать как числа с десятичными точками; строки являются буквальными, могут быть английскими или другими языковыми символами.
Иногда, когда мы вызываем API, но мы не знаем, даст ли этот API нам тип данных, чтобы вернуть, поэтому использование типа автоматического вывода (авто) поможет нам автоматически определить тип данных.
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
Массив - это контейнер для хранения данных. Массив C++ может хранить коллекцию элементов того же типа фиксированного порядка с фиксированным размером. Так что в C++ для декларирования массива необходимо указать тип элемента и количество элементов. Все массивы имеют индекс 0 в качестве первого элемента.
// 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
Функция - это набор инструкций, которые выполняют задачу вместе. Декларация функции включает в себя: имя функции, тип возврата и параметры. Тип возврата - это тип данных, возвращаемый при выполнении функции при вызове этой функции; параметр является необязательным, а функция также не может содержать параметров. Когда функция вызвана, вы также можете передать параметр функции. Посмотрите на следующий пример:
// 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
}
Используя C++ для написания количественных торговых стратегий, существует три широко используемых оператора: арифметические операторы, реляционные операторы, логические операторы и операторы назначения. Арифметический оператор - это математическая операция сложения, вычитания, умножения и деления. Реляционный оператор может сравнивать, меньше или больше два значения. Логические операторы в основном включают: логический AND, логический OR и логический non. Оператор назначения - это переменное назначение, о котором мы говорили ранее. Как показано ниже:
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;
}
Если есть выражение 100*(10-1)/(10+5), какой шаг сначала рассчитывается программой? Математика средней школы говорит нам: если это один и тот же уровень операции, она обычно рассчитывается слева направо; если есть сложения и вычитания, и умножение и деление, сначала вычислите умножение и деление, затем добавляйте и вычитайте; если есть скобки, сначала вычислите внутреннюю часть скобков; если соблюден закон операции, закон расчета можно использовать для расчета. тот же принцип, что и для C++, как показано ниже:
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
Обычно, когда мы пишем код, нам всегда нужно выполнять разные действия для разных решений. мы можем использовать условные инструкции в нашем коде для выполнения этой задачи. В C++, мы можем использовать следующие условные инструкции:
If statement - Используйте это заявление для выполнения кода только в том случае, если указанное условие верно
If...else statement - выполнять код, если указанное условие верно, другой код выполняется, когда условие неверно
If...else if...else statement - используйте это заявление, чтобы выбрать один из нескольких блоков кода для выполнения
Switch statement - Используйте это заявление для выбора одного из нескольких блоков кода для выполнения
Это командование выполняет код только в том случае, если указанное условие верно. Пожалуйста, используйте малую букву if. Использование большой буквы (IF) создаст ошибку C++! Как показано ниже:
// 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
}
выполнять код, если указанное условие верно, другой код, выполняемый, когда условие ложно, как показано ниже:
//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
}
Используйте это утверждение для выбора одного из нескольких блоков кода для выполнения
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
}
Кружка For может выполнять N раз блоки кода неоднократно, и ее поток выполнения выглядит следующим образом (как показано ниже):
for (int a = 10; a < 20; a++){
// code block
}
Шаг 1: выполните инт a = 0 и выполните только один раз. Его цель - объявить целое число переменной и инициировать его на 0, чтобы контролировать петлю for.
Шаг 2: Используйте a<20. Если это верно, выполните блок кода строки 2.
Шаг 3: выполните a++, после выполнения a++, a становится 11.
Шаг 4 : Используйте a<20 снова, и второй, третий и четвертый шаги будут выполняться снова и снова. Пока a<20 не будет ложным, если он ложный, блок кода строки 2 не будет выполнен, и вся петля for завершена.
Все мы знаем, что рынок постоянно меняется. Если вы хотите получить последний K-линейный массив, вы должны постоянно запускать один и тот же код снова и снова. Затем использовать петлю, пока это лучший выбор. До тех пор, пока указанное условие верно, петля будет продолжать получать последние данные K-линейного массива.
void main() {
auto ct = exchange.SetContractType(symbol); //set the trading variety
while(true) {
auto r = exchange.GetRecords(); // constantly getting k-line arrays
}
}
Лопы имеют предварительные условия. Только когда это предварительное условие "правда", петля начнет делать что-то снова и снова, пока предварительное условие не будет "ложным", петля закончится. Но с помощью инструкции break можно выпрыгнуть из петли сразу во время выполнения петли;
# 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
Заявление continue также выходит из петли, но не выходит из всей петли. Вместо этого прерывайте петлю и продолжайте в следующей петле. Как показано ниже, когда a равна 2, петля прерывается, и следующая петля продолжается до тех пор, пока предпосылка петли не будет "false", чтобы выйти из всей петли.
# 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
return statement завершает выполнение функции и возвращает значение функции. return statement может появляться только в теле функции, и любое другое место в коде будет вызывать синтаксическую ошибку!
# 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;
}
На платформе FMZ Quant было бы очень удобно написать стратегию на C++. FMZ Quant имеет множество официально встроенных стандартных стратегий и библиотек торговых классов, таких как:
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
}
}
}
Как показано выше, это стандартная структура стратегии, и эти форматы фиксированы. Используйте рамку для написания стратегии. Вам нужно только написать логику стратегии со второй строки. Другие процессы захвата рынка и обработки заказов обрабатываются структурой и библиотеками торгового класса, вам просто нужно сосредоточиться на разработке стратегии.
Если вам нужно написать более сложную стратегию, пожалуйста, обратитесь к документации C++ языка API платформы FMZ Quant или напрямую обратитесь к официальной службе обслуживания клиентов о службе написания.
Ключ к количественной торговле - это стратегия торговли, а не торговые инструменты (язык программирования).