d9e5a92d

Методология тестирования нейронного компонента стратегии выходов

Мы используем наибольшую из двух лучших нейронных сетей, обученных прогнозированию обращенного во времени Медленного %К. Предварительная обработка и логика принятия решений идентичны использованным в гл. 11. Используется сеть 18- 14- 4- 1 (18 нейронов в первом слое, 14 в первом промежуточном, 4 во втором промежуточном и 1 на выходе).
Параллельно используется МССВ. В дополнение к условиям выходов МССВ вводится условие: если прогнозируемое значение обращенного во времени Медленного %К выше некоего порога, т.е. положение рынка относительно ценового диапазона ближайшего будущего высоко, то система выходит из длинной позиции. Подобным же образом, если прогноз показывает, что рыночная цена находится вблизи нижней границы диапазона цен ближайшего будущего, то система выходит из любой корот-

static void Model (float *parms, float *dt, float *opn, float *hi, float *lo, float *cls, float *vol, float *oi, float *dlrv, int nb, TRDSIM &ts, float *eqcls) {
// Выполняет случайные входы с модифицированным стандартным выходом,
// улучшенным с помощью "сигнального выхода", основанного
// на нейропредсказателе для обратного Медленного %К.
// File = x21mod01.c
// parms - набор [1..MAXPRM] параметров
// dt - набор [l..nb] дат в формате ГГММДД
// орn - набор [1..nb] цен открытия
// hi - набор [1..nb] максимальных цен
// 1о - набор [l..nb] минимальных цен
// cls - набор [1..nb] цен закрытия
// vol - набор [l..nb] значений объема
// oi - набор [1..nb] значений открытого интереса
// dlrv - набор [l..nb] средних долларовой волатильности
// nb - количество дней в наборе данных
// ts - ссылка на класс торгового симулятора


// eqcls - набор [1..nb] уровней капитала по ценам закрытия
// объявляем локальные переменные
static int rc, cb, neontracts, maxhold, signal, ranseed;
static float mmstp, ptlim, limprice, stpprice, entryprice;
static int entryposted, entrybar;
static float exitatr[MAXBAR+1] , prd[KAXBAR+1] , rnum, thresh;
static long iseed;

// копируем параметры в локальные переменные для удобного обращения
thresh = parms[1]; // порог выходных значений нейронной сети
ranseed = parms[2]; // используется для инициализации случайной
// последовательности
maxhold = 10; // период максимального удержания позиции
ptlim =4.5; // целевая прибыль в единицах среднего истинного
// диапазона
mmstp = 1.5; // защитная остановка в единицах среднего истинного
// диапазона
// выполняем вычисления по всему объему данных
AvgTrueRangeS(exitatr,hi,lo,cls,50,nb); // средний истинный
// диапазон для выхода
NeuralForecast(prd, cls, nb) ; // прогнозы
// запускаем генератор случайных чисел
// ... используем различные случайные последовательности для каждого рынка
// ... ts.model() возвращает индекс рынка (SP- 1, YX- 2, ...)
iseed = - (ranseed + 10 * ts.model{)};
rnum = ran2(&iseed);
// проходим через дни, чтобы смоделировать реальную торговлю
for(cb = 1; cb <= nb; cb++) (
// не открываем позиций до начала периода выборки
// ... то же самое, что установка MaxBarsBack в TradeStation
if(dt[cb] < IS_DATE) { eqcls[cb] = О.Э; continue; ]
// выполняем ожидающие приказы и считаем кумулятивный капитал
rc = ts.update (opn [cb] , hi [cb] , lo [cb] , cls [cb] , cb) ;
if(rc != 0) nrerror("Trade buffer overflow");

кой позиции. Выходы, запускаемые сигналами нейронной сети, произво-
дятся по цене закрытия соответствующего дня.

eqcls[cb] = ts.currentequity(EQ_CLOSETOTAL);
// считаем количество контрактов для позиции
// ... мы хотим торговать эквивалентом долларовой волатильности
// ... 2 новых контрактов на S&P- 500 от 12/31/98
ncontracts = RoundToInteger(5673.О / dlrv[cb]);
if(ncontracts < 1) ncontracts = 1;
// избегаем устанавливать приказы на дни с ограниченной торговлей
if(hi[cb+l] == lo[cb+l]) continue;
// генерируем "стандартные" случайные сигналы входа
signal = 0;
rnum = ran2(siseed);
if (rnum < 0.025) signal = - 1; // случайный короткий вход
else if (rnum > 0.975) signal = 1; // случайный длинный вход
// входим в сделки по цене открытия
entryposted = 0;
if(ts.position() <= 0 && signal == 1) (
ts.buyopen('l', ncontracts);
entryposted = - 1;
entryprice = opn[cb+l];
entrybar = cb + 1;
}
else if (ts.position)) >= 0 && signal == - 1) (
ts.sellopen('2', ncontracts);
entryposted = - 1;
entryprice = opn[cb+l];
entrybar = cb + 1;
)


// выходим из сделок, используя модифицированный стандартный выход
// вместе с нейросетевым выходом
if(entryposted > 0) (
// инициализация и выходы для длинных позиций в день входа
limprice = entryprice + ptlim * exitatr[cb];
stpprice = entryprice - iranstp * exitatr[cb] ;
ts.exitlonglimit('A', limprice);
ts.exitlongstop('В', stpprice);
if(prd[cb] > thresh) ts.exitlongclose('C' ) ;
)
else if(entryposted < 0) {
// инициализация и выходы для коротких позиций в день входа
limprice = entryprice - ptlim * exitatr[cb);
stpprice = entryprice + mmstp * exitatr[cb];
ts.exitshortlimit('D' , limprice);
ts.exitshortstop('E' , stpprice);
if(prd[cb] < 100.0- thresh) ts.exitshortclose('F') ;
}
else [
// выходы после дня входа
if(ts.position() > 0} { // длинные позиции
ts.exitlonglimit('G' , limprice);
ts.exitlongstop('H', stpprice);
if(cb- entrybar >= maxhold
prd[cb] > thresh) ts.exitlongclose('I');
}
else if (ts.position() < 0) { // короткие позиции
ts.exitshortlimit('J' , limprice);
ts.exitshortstop('K' , stpprice);
if (cb- entrybar >= maxhold
prd[cb] < 100.0- thresh) ts.exitshortclose('L') ;
}
}
} // обрабатываем следующий день
)

Вышеприведенный фрагмент кода описывает логику стратегии выходов. Параметры ptlim и mmstp имеют значения 4,5 и 1,5 соответственно, поскольку эти значения давали лучшую эффективность при торговле портфелем (см. табл. 14- 1 в гл. 14). Параметр thresh, т.е. значение порога для выходов на основе нейронного прогноза, подвергается оптимизации. Логика дополнительного выхода видна в блоке if, где сравниваются порог и прогноз, выданный сетью. Если условие выполняется, то по цене закрытия дня отдается приказ на выход из сделки. Параметр thresh прогоняется от 50 до 80 с шагом 2.

Содержание раздела