В предыдущей статье мы объяснили предпосылки реализации торговой стратегии с введением языка C ++, базовой грамматики и структуры стратегии.
Один из наиболее часто используемых индикаторов в техническом анализе, KDJ, был признан большинством трейдеров во всем мире.
KDJ был основан на статистической теории, случайное значение (RSV) было рассчитано по соотношению последней 9 K линии
Объединяя преимущества концепции импульса, индикатора силы и скользящей средней, мы измеряем степень изменения цены акций от движения нормального диапазона. Когда значение K больше значения D, это указывает на то, что цена акции в настоящее время находится в восходящей тенденции. Поэтому, когда линия K пересекает линию D снизу вверх, пришло время купить акции. Наоборот, когда значение K меньше значения D, это указывает на то, что фондовый рынок в настоящее время находится в нисходящей тенденции. Поэтому, когда линия K пересекает линию D сверху вниз, пришло время продать акции.
Расчет показателя KDJ сложен. Сначала рассчитывается случайное значение (RSV), а затем рассчитываются значение K, значение D и значение J. Метод его расчета следующий:
RSV = (цена закрытия - самая низкая цена N периода) / (наивысшая цена N циклов - самая низкая цена N циклов) * 100
Значение K = среднее значение N циклов RSV
D значение = среднее значение N циклов K
Значение J = 3 * значение K -2 * значение D
void main(){ // the program starts from this main function
while (true){ // enter the loop
auto ct = exchange.SetContractType(symblo); //set the contract type
auto r = exchange.GetRecords(); // get the K line array
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0]arr[0].size() - 2]; // get the previous k line KDJ indicator K value
auto d = arr[1]arr[1].size() - 2]; // get the previous k line KDJ indicator D value
auto j = arr[2]arr[2].size() - 2]; // get the previous k line KDJ indicator J value
}
}
Существует много способов использования KDJ, которые можно использовать в одиночку или в сочетании с другими индикаторами. В этой статье мы будем использовать его самым простым способом, которые следуют: Если значение K больше значения D, мы считаем, что покупательная способность укрепляется, волна растущего рынка сформирована, и генерируется сигнал открытия длинной позиции; если значение K меньше значения D, мы считаем, что продажная способность укрепляется, и волна нисходящего тренда сформирована, генерируется сигнал открытия короткой позиции.
Если после открытия позиции значение D изменяется с верхнего на нижний уровень, мы считаем, что покупательная способность ослабевает, или что продажная способность укрепляется, и генерируется сигнал закрытия длинной позиции; если открывается короткая позиция, значение D изменяется с нижнего на верхний уровень, мы считаем, что сила продажной способности ослабевает, или что покупательская способность укрепляется, и генерируются сигналы закрытия короткой позиции.
Открытая длинная позиция: если позиции нет, а значение K больше значения D
Краткая позиция: если позиции нет, а значение K меньше значения D
Закрытие длинных позиций: если длинная позиция удерживается, а значение D меньше значения D проницаемой линии K
Закрытие короткой позиции: если удерживается короткая позиция, и значение D больше значения D проницаемой линии K
Первый шаг в реализации стратегии с кодом - сначала рассмотреть, какие данные нам нужны? через какой API получить? после того, как мы получим данные, как рассчитать логику торговли? далее, каким образом разместить заказы? наконец, давайте реализуем это шаг за шагом:
Так называемая архитектура стратегии - это способ проектирования всей стратегии. Как показано ниже, архитектура состоит из двух функций: одна - основная функция, программа начинается с основной функции, и ее функция заключается в том, чтобы иметь дело с ядром логики стратегии. такие вещи, как: суждение о том, является ли соединение с биржей нормальным, фильтрация ненужной информации журнала, контроль интервала времени выполнения ядер логики стратегии; и другой - функция onTick, в этой функции, в основном, логика стратегии, включающая: получение сырых данных, вычисление данных, размещение заказов и многое другое.
bool onTick(){ // onTick function
// strategy logic
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick()){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
Вышеприведенный код - это рамка стратегии C++, созданная инструментами платформы FMZ Quant. Это фиксированный формат кодирования, вся логика торговли начинается с строки 2 и никаких изменений не производится в другом месте. Кроме того, если вы ветеран, вы можете добавлять или изменять функции в соответствии со своими потребностями.
Вы можете думать о библиотеке торгового класса как о функциональном модуле. Преимущество использования библиотеки торгового класса заключается в том, что она позволяет сосредоточиться на написании логики стратегии. Например, когда мы используем библиотеку торгового класса, чтобы открыть или закрыть позицию, мы можем напрямую использовать интерфейс API в библиотеке торгового класса; но если мы не используем библиотеку торгового класса, нам нужно получить рыночную цену при открытии позиции. Необходимо рассмотреть вопрос о неисполненных ордерах и вопрос о выводе ордеров и так далее.
Различные сырые данные являются важной частью логики торговли. Какие данные нам нужны? Из нашей логики стратегии торговли нам сначала нужно получить данные K-линии. С оригинальными данными K-линии мы можем рассчитать индикатор KDJ и, наконец, сравнить взаимосвязь между K-значением и D-значением, чтобы определить, следует ли размещать заказы. Итак, давайте получим эти данные.
Во-первых, нам нужно получить K-линейный массив, потому что K-линейный массив будет использоваться для расчета индикатора KDJ. следующим образом:
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
Как показано выше:
Строка 1 : Определяет переменную, используемую для получения статуса позиции.
Строки 3 - 12: Определяется функция onTick, и эта функция содержит параметр. Этот параметр должен быть передан в торговом диапазоне, в данном случае, с использованием еженедельной k-линии.
Строки 14 - 24: Определите основную функцию, которая обрабатывает нестратегическую логику. Единственное, что можно изменить, это контрактный код
Давайте сосредоточимся на функции onTick и посмотрим, как она получает данные K-линии:
Строки 4 - 7 : установить тип контракта и сорт торговли, если установка типа контракта и сорта торговли не удалась, возвратить false
Строка 8: Получите K-линейный массив, который имеет фиксированный формат.
9-11 строки: фильтруйте длину K-линии, потому что параметр, который мы используем для расчета показателя KDJ, равен 9. Когда число K-линий меньше 9, невозможно вычислить показатель K-линии. Итак, здесь мы хотим отфильтровать длину K-линии. Если K-линия меньше 10, просто верните false напрямую и продолжайте ждать следующей K-линии.
Далее нам нужно вычислить значения K и D индикатора KDJ. Сначала необходимо получить массив индикаторов KDJ и получить значения K и D из этого массива. На платформе FMZ Quant получить массив KDJ очень просто, просто позвоните в API KDJ, сложность заключается в получении значения K и D значений, потому что массив KDJ является двумерным массивом.
Двумерный массив на самом деле легко понять, что является массивом массива, получение последовательностей: сначала получить указанный массив в массиве, а затем получить указанный элемент из указанного массива, как показано ниже:
#include <iostream>
using namespace std;
int main(){
int hour [3][2] = {{100, 50}, {66, 88}, {10, 90}};
cout << hours[0][0]; // get the hours array first elements of first element, the result is 100
cout << hours[0][1]; // get the hours array first elements of second element, the result is 50
cout << hours[1][0]; // get the hours array second elements of first element, the result is 66
return(0);
}
Как показано ниже, 12-я строка напрямую использует API FMZ Quant для получения массива показателей KDJ, который представляет собой двумерный массив: arr = [[K value, K value, K value...], [D value, D value, D value...], [J value, J value, J value...]]
Строка 13 состоит в том, чтобы получить значение k предыдущей K-строки, значение K - arr[0], затем получить предпоследний элемент из arr[0], arr[0].size() можно использовать для получения длины массива arr[0], arr[0].size() - 2 является вторым последним элементом массива, сложив его вместе: auto k = arr [0] [arr [0].size () - 2 ]; строки 14 и 15 являются одним и тем же расчетом.
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line
auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
С помощью вышеперечисленных данных мы можем написать логику торговли и часть размещения ордера сейчас. Это также очень просто, наиболее часто используется заявление
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line
auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
string action; // define a string variable action
// if currently holding long position, and the previous K line's D value is less than the second last k line's D value, close all position
// if currently holding short position, and the previous K line's D value is greater than the second last k line's D value, close all position
if((d < dPre && position > 0) || (d > dPre && position <0)){
action = "cover";
}else if (k > d && position <= 0){ // if the previous K line's K value is greater than the previous K line's D value, and there are no long positions
action = "buy"; // set the variable action to "buy"
}else if (k < d && position >= 0){ // if the previous K line's K value is less than the previous K line's D value, and there are no short positions
action = "sell"; // set the variable action to "sell"
}
if (action.size() > 0){ // if there are placing order instruction
position = ext::Trade(action, symbol, 1); // calling the C++ trading class library, placing orders according the direction of variable "action". and also renew the position status.
}
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 if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
В приведенном выше коде строки с 19 по 28 представляют собой логику торговли и код размещения ордеров.
Строка 19 по строку 21 состоят из следующего: если в настоящее время удерживается длинная позиция, и предыдущее значение K-линии D меньше второго последнего значения K-линии D, закрыть все позиции, если в настоящее время удерживается короткая позиция, и предыдущее значение K-линии D больше второго последнего значения K-линии D, закрыть все позиции. и изменить переменную
В строках 21 - 25 указаны условия для открытия длинной и короткой позиций.
В строке 26 по строку 28 выполняется логика размещения ордера. Во-первых, в соответствии с длиной переменной строки
Необходимо отметить два места:
Попробуйте (но не обязательно) написать логику стратегии по мере установления текущего условия K-линии, а затем разместить заказ на следующей k-линии. Или установлено предыдущее условие k-линии, размещая заказы на текущей k-линии, таким образом, результат бэкстеста и реальная производительность рынка не сильно отличаются.
В общем, логика закрытия позиции должна быть написана перед логикой открытия позиции. Целью этого является попытка сделать логику стратегии соответствующей вашим ожиданиям. Например, если логика стратегии просто отвечает ситуации, когда ей нужно делать противоположное направление торговли после закрытия позиции, правило такого рода ситуации заключается в том, чтобы сначала закрыть позицию, а затем открыть новую позицию. Если мы напишем логику закрытия позиции перед логикой открытия позиции, она будет идеально выполнять это правило.
Выше мы узнали, как анализировать технические индикаторы KDJ и преобразовывать их в полную количественную торговую стратегию. Включая: введение стратегии, метод расчета индикатора KDJ, логику стратегии, условия торговли, реализацию кода стратегии и т. Д. Благодаря этому сценарию стратегии мы не только познакомимся с методом программирования C ++ на платформе FMZ Quant, но и различные стратегии могут быть адаптированы в соответствии с случаями в этом разделе.
Для достижения количественной торговой стратегии необходимо обобщить наш собственный субъективный торговый опыт или систему, а затем получить необходимые сырые данные отдельно, и рассчитать данные, необходимые для логики стратегии, и, наконец, вызвать API размещения заказов для реализации торговли.
На данный момент учебник по написанию стратегии в этой серии подошел к концу, я считаю, что если вы будете следовать пошаговому руководству, которое приведет вас сюда, вы получите много. В любом случае, с точки зрения базовых курсов количественной торговли, Долгая дорога прошла более половины. В последней главе мы научим вас использовать инструменты торговли FMZ Quant backtesting, и как избежать ям в backtesting и сделать окончательную подготовку к реальной торговле на рынке. Хотя это небольшая часть контента, это большой шаг в вхождении в мир количественной торговли!
Попробуйте реализовать алгоритм индикатора KDJ с использованием языка C ++ на платформе FMZ Quant.
Постарайтесь использовать знания, представленные в этом разделе, для разработки стратегии показателей CCI.