<< Пред. стр.

стр. 31
(общее количество: 46)

ОГЛАВЛЕНИЕ

След. стр. >>

Собрав для будущего факта 18 скорректированных квадратным кор-
нем разностей для входов, мы используем процедуру нормализации. Це-
лью нормализации является удаление информации, заложенной в ампли-
туде, при сохранении формы волны. При обращении с 18 переменными
входа как с вектором, нормализация состоит в масштабировании вектора
в единицы длины. Расчеты включают возведение каждого элемента век-
тора в квадрат, сложение квадратов, вычисление квадратного корня и за-
тем деление каждого элемента на полученное число. Так получаются пе-
ременные входа для нейронной сети — фактически, программа нейрон-
ной сети в дальнейшем еще раз будет масштабировать эти входы, приво-
дя их значения к уровням, допустимым для входных нейронов.
Для каждого факта целью (т.е. зависимой переменной регрессии) яв-
ляется попросту значение обращенного во времени Медленного %К. Вход-
ные переменные и цель для каждого факта выдаются в простом ASCII-
формате в виде файла, который может анализироваться качественным
пакетом для разработки нейронных сетей.
Полученный набор фактов используется для обучения сети прогнози-
рованию обращенного во времени Медленного %К, т.е. относительного
положения сегодняшней цены закрытия и, предположительно, завтраш-
ней цены открытия по отношению к диапазону цен за последующие
10 дней (обращенный во времени Медленный %К с периодом 10 дней).
Следующий шаг разработки нейронного прогностического устрой-
ства — реальная тренировка нескольких сетей на полученном наборе
фактов. Обучают серию нейронных сетей различного размера, причем
метод отбора наиболее хорошо обученной и устроенной сети не состоит,
как можно было бы подумать, в проверке ее эффективности на данных
вне пределов выборки. Вместо этого проводится коррекция коэффици-
ентов корреляции (показателей прогностических способностей каждой
сети), причем коэффициент коррекции зависит от размера выборки дан-
ных и количества параметров (связей между нейронами) в исследуемой
сети. При этом используется то же уравнение, что и при коррекции мно-
жественных корреляций, получаемых при многовариантной регрессии
(см. главу о статистике и оптимизации). Чем больше и сложнее сеть, тем
сильнее будут скорректированы (в меньшую сторону) коэффициенты
корреляции. Этот подход помогает оценить степень излишней подгонки
системы под исходные данные. Чтобы большая сеть превзошла малень-
кую, она должна давать значительно больший коэффициент корреляции.
Этот метод позволяет выбирать лучшие сети без обычного обращения к
данным вне пределов выборки. Все сети проходят полное обучение, т.е.
не делается попыток скомпенсировать снижение степеней свободы мень-
шим обучением сети.
Наилучшие сети, отобранные на основе скорректированных корре-
ляций, затем тестируются с настоящей моделью входа, стандартизован-
ным выходом на всех рынках как в пределах, так и вне пределов выборки.
НЕЙРОННЫЕ СЕТИ 259
ГЛАВА 11




Как было сказано выше, излишне подогнанные сети должны иметь очень
низкие значения корреляции после проведения ее коррекции. Большое
количество фактов в наборе (88 092) должно помочь избежать вредного
влияния подгонки для сетей умеренного размера.


Код модели обращенного Медленного %К
static void PrepareNeurallnputs (float *var, float *cls, int cb) {

// Преобразование исходных цен закрытия
// во входную информацию для нейронной сети.
// var - вывод: массив [1..18] переменных для нейросети
// cls - ввод: массив [1..] цен закрытия
// cb - ввод: индекс текущего дня

static pbars[] = { 0, 0,1,2,3,4,5,6,8,10,12,16,20,24,32,34,
40,48,64,96 };
static float pfac[19], amp;
static int notfirstpass, k;
// инициализируем таблицу фактора корректировки разницы
if(notfirstpass == FALSE) (
for(k = 1; k <= 18; k++)
pfac [k] = 1.0 / sqrt (pbars [k+1] - pbars[k]);
notfirstpass = TRUE;
}

// считаем откорректированные ценовые разницы и квадраты амплитуды
amp = 0.0;
for (k = 1; k <= 18; k++) (
var [k] = pfac [k] *
(cls[cb - pbars[k]] - cls (cb - pbars[k+1] ]);
amp += var [k] * var [k] ;
}

// нормирование вектора ценовых разниц к единице амплитуды
amp = 1.0 / sqrt(amp);
for(k = 1; k <= 18; k++)
var[k] = amp * var[k];
}

static void Model (float *parms, float *dt, float *opn, float *hi,
float *lo, float *cls, float *vol, float *oi, float *dlrv, int nb,
TRDSIM its, float *eqcls) (

// Выполняет простую торговую модель на нейросетях. Она
// торгует с помощью предсказания обратного Медленного %К.
// File = xl5modOl.c
// parms - набор [1..MAXPRM] параметров
// dt — набор [1..nb] дат в формате ГГММДД
// орn - набор [l..nb] цен открытия
// hi — набор [l..nb] максимальных цен
// 1о — набор [l..nb] минимальных цен
// cls - набор [l..nbj цен закрытия
// vol — набор [l..nb] значений объема
// oi — набор [l..nb] значений открытого интереса
// dlrv - набор [1..пЬ] средних долларовой волатильности
// nb — количество дней в наборе данных
// ts — ссылка на класс торгового симулятора
// eqcls — набор [l..nb] уровней капитала при закрытых позициях
ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК
260



//объявляем локальные переменные
static int rc, cb, ncontracts, maxhold, ordertype;
static int mode, signal, factcount, k, netnum;
static FILE *fil;
static NEURALNET *nnet; static char netname [20];
static float thresh, netout, var[19];
static float mmstp, ptlim, stpprice, limprice, tmp;
static float exitatr[MAXBAR+1], revstoch[MAXBAR+1];

// копируем параметры в локальные переменные для удобного обращения
thresh = parms[l]; // порог выходных значений для сети
netnum = parms[2]; // число нейросети
mode = parms[6] ; // обучение (режим=1) или тест (режим=2)
ordertype = parms[9]; // тип входного приказа
maxhold = 10; // период максимального удержания позиции
ptlim = 4; // целевая прибыль в единицах волатильности
mmstp = 1; // защитная остановка в единицах волатильности

//выполняем вычисления по всему объему данных с помощью векторных процедур
AvgTrueRangeS(exitatr,hi,lo,cls,50,nb); // средний истинный диапазон для
// выхода
RevStochOsc(revstoch,hi,lo,cls,2,10,nb); // обратный Медленный %К

// готовим набор фактов для обучения нейросети
if(mode == 1) { // режим подготовки
// фактов (р6=1)

// открываем выходной файл и записываем N-TRAIN в файл
// заголовок перед обработкой первого рынка
if(strcmp(ts.symbol(), "SP") == 0) (
fil = fopen("yl5fac01.dat", "wt");
fprintf(fil, "%d\n%d\n", (int)18, (int)l);
factcount = 0;
}

// записываем действительные факты в файл
// делаем для каждого рынка в портфеле
for(cb = 1; cb <= nb; cb++) (
if(dt[cb] < ISJATE) continue; // период анализа
if(dt[cb+10] > OOS_DATE) break; // игнорируем данные вне пределов
// выборки
fprintf(fil, "%6d", ++factcount) ; // номер факта
PrepareNeurallnputs(var, cls, cb) ;
for(k = 1; k <= 18; k++)
fprintf(fil, "%7.3f", var[k]); // входные значения
fprintf(fil, "%7.3f\n",revstoch[cb] ); // цель
if((cb % 1000) == 1)
printf("CB = %d\n", cb); // информация о прогрессе
}

// закрываем выходной файл и выходим после обработки последнего рынка
if(strcmp(ts.symbol(), "LB") == 0) (
fclose(fil);
exit(0);
}
}

// моделируем торговлю с обученной нейросетью
if(mode == 2) { // режим торгового симулятора (рб=2)

// загружаем обученную сеть перед обработкой первого рынка
if (strcmp(ts.symbol(), "SP") == 0) (
sprintf(netname, "/nets/nn%d.net", netnum);
nnet = ntlload(netname) ;
НЕЙРОННЫЕ СЕТИ . 261
ГЛАВА 11




if(nnet == NOLL) nrerror(ntlerrm(ntlerrc()));
}

// проходим через дни, чтобы смоделировать реальную торговлю
for(cb = 1; cb <= nb; cb++) {

// не открываем позиций до начала периода выборки
// ... то же самое, что установка MaxBarsBack в TradeStation
if(dt[cb] < IS_DATE) ( eqcls[cb] = 0.0; continue; }

// выполняем ожидающие приказы и сохраняем значения капитала
rc = ts.update(opn[cb], hi[cb], lo[cb], cls[cb], cb) ;
if(rc != 0) nrerror("Trade buffer overflow");
egcls[cb] = ts.currentequity(EQ_CLOSETOTAL);

// считаем количество контрактов для позиции
// ... мы хотим торговать эквивалентом долларовой волатильности
// ... 2 новых контрактов на S&P-500 от 12/31/98
ncontracts = RoundToInteger(5673 .0 / dlrv[cb]);
if(ncontracts < 1) ncontracts = 1;

// избегаем устанавливать приказы на дни с ограниченной торговлей
if(hi[cb+l] == lo[cb+l]) continue;

// генерируем входные сигналы, цены стоп- и лимитных приказов,
// используя обученную нейросеть
signal=О;
PrepareNeurallnputs(var, cls, cb) ;
ntlset_inputv(nnet, &var[l]); // принимаем входные параметры сети
ntlfire (nnet); // запускаем сеть
netout = ntlget_output(nnet, 0); // получаем выходные данные
if(netout > thresh) signal = -1; // сигнал на продажу
if(netout < (100 - thresh))
signal = 1; // сигнал на покупку
limprice = 0.5 * (hi [cb] + lo [cb] ) ;
stpprice = cls[cb] +0.5 * signal * exitatr[cb];

// входим в сделку, используя определенный тип приказа
if(ts.position() <= 0 && signal == 1) (
switch(ordertype) { // выбираем нужный вид приказа
case 1: ts.buyopen('1', ncontracts); break;
case 2: ts.buylimit{'2 ' , limprice, ncontracts); break;
case 3: ts.buystop('3', stpprice, ncontracts); break;
default: nrerror("Invalid buy order selected");
}
)
else if(ts.position() >= 0 && signal == -1) (
switch(ordertype} { // выбираем нужный вид приказа
case 1: ts.sellopen('4', ncontracts); break;
case 2: ts.selllimit('5', limprice, ncontracts); break;
case 3: ts.sellstop('6', stpprice, ncontracts); break;
default: nrerror("Invalid sell order selected");
}
}

// симулятор использует стандартную стратегию выхода
tmp = exitatr[cb];
ts.stdexitcls('X', ptlim*tmp, mmstp*tmp, maxhold);

} // обрабатываем следующий день

// выгружаем обученную сеть после обработки последнего рынка
if(strcmp(ts.symbol(),"LB") == 0) ntldisp(nnet) ;
}
}
ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК
262



Код включает две функции — обычную функцию Model, реализую-
щая торговую модель, и процедуру подготовки входов нейронной сети
PrepareNeurallnputs. Процедура, которая подготавливает входы, требует
для работы индекса текущего дня (cb) и серии цен закрытия (cls).
Функция PrepareNeurallnputs при наличии индекса текущего дня и
серии цен закрытия рассчитывает для данного факта все входы, необхо-
димые нейронной сети. В списке параметр pbars указывает на относитель-
ный по сравнению с текущим (приравненным к нулю) номер дня из про-
шлых данных, используемый для вычисления вышеописанных разностей
цен. Первый блок кода после объявления переменных запускает таблицу
факторов подстройки цен. Таблица запускается на первом проходе фун-
кции и содержит квадратные корни количества дней между каждой из
пар цен, используемых для расчета разностей. Следующий блок кода рас-
считывает скорректированные разности, а также суммы их квадратов, т.е.
квадрат амплитуды или длину результирующего вектора.
Код, реализующий торговую модель, основан на наших обычных прин-
ципах. После объявления переменных ряд параметров копируется в ло-
кальные переменные для простоты ссылок. Затем рассчитываются сред-
ний истинный интервал, используемый для стандартного выхода, и обра-
щенный во времени Медленный %К с периодом 10 дней.
Один из параметров (mode) выбирает режим работы кода. Mode = 1
запускает код для подготовки факта; файл открывается, заголовок (состо-
ящий из числа входов — 18 и числа целей — 1) записывается, и счет фак-
тов начинается с нуля. Это производится только при открытии первого из
рынков в составе портфеля. Файл остается открытым все время дальней-
шей обработки, вплоть до конца обработки последнего символа в порт-
феле. После заголовка в файл записываются факты. Все данные до нача-
ла периода выборки и после окончания периода вне выборки игнориру-
ются. Используются только данные в пределах выборки. Каждый факт,
записанный в файл, состоит из номера факта, 18 переменных входов, рас-
считанных процедурой PrepareNeurallnputs, и цели (значения обращен-
ного во времени Медленного %К). Пользователю сообщается информа-
ция о продвижении работы.
Если mode выбирается равным 2, то нейронная сеть, обученная на вы-
шеописанном файле с фактами, используется для генерации торговых вхо-
дов. Первый блок кода открывает и загружает нужную сеть до начала рас-
четов по первому рынку. После выполнения стандартных функций обнов-
ления симулятора, расчета количества контрактов, избежания дней с ос-
тановленной торговлей и т.п. запускается блок, генерирующий сигналы
входа и выхода. Функция PrepareNeurallnputs вызывается для получения
входных данных, соответствующих текущему дню. Сеть обрабатывает эти
данные, и на основании ее выхода генерируются сигналы на вход в рынок.
Правила генерации сигналов таковы: если на выходе нейронной сети
значение превышает порог thresh, то подается сигнал на продажу — сеть
НЕЙРОННЫЕ СЕТИ 263
ГЛАВА 11




предсказывает высокое значение обращенного во времени Медленно-
го %К, т.е. текущая цена закрытия, возможно, близка к максимуму на бли-
жайшее будущее. Если на выходе сети значение составляет менее 100 —
thresh, то подается сигнал на покупку. Например, если thresh установлен
на уровне 80, то любой предсказанный Медленный %К более 80 будет вы-
зывать сигнал на продажу, а любой Медленный %К менее 20 — сигнал на
покупку.
Кроме того, встроены еще два блока, обеспечивающие отдачу соб-
ственно приказа на вход в рынок и работу стандартизированного выхода.
Эти блоки подобны использованным в предыдущих главах.


Методология тестирования модели
на основе обращенного Медленного %К
Модель выполняется со значением mode — 1 для получения набора фак-
тов. Набор фактов загружается в N-TRAIN — набор для разработки ней-
ронных сетей Scientific Consultant Services (516-696-3333), масштабирует-
ся и перетасовывается, как это необходимо при разработке нейронной
сети. Затем обучается набор сетей, начиная с маленькой и кончая весьма
большой; в основном это простые 3-слойные сети. Также обучаются две
4-слойные сети. Все сети тренируются до максимальной конвергентнос-
ти и затем «полируются» для удаления мелких отклонений или сдвигов.
Процесс «полировки» обеспечивается снижением интенсивности обуче-
ния до очень низкой и еще примерно 50 прогонами после этого.
В табл. 11-1 приводится информация о всех сетях, обучавшихся для этой
модели, с коэффициентами корреляции и другими показателями. В табли-
це указаны название файла, содержащего сеть, размер — число слоев и
число нейронов в каждом из слоев, число связей в сети, оптимизирован-
ных при обучении (подобно количеству коэффициентов регрессии при
множественной регрессии и их связи с излишней подгонкой под истори-
ческие данные), и корреляция — множественная корреляция выхода сети
с его целевым значением. Скорректированные на излишнюю подгонку под
входные данные значения корреляции занимают два столбца: в левом —
коррекция исходя из обучения на наборе в 40 000 точек данных, в пра-
вом — исходя из 13 000 точек. Последние строки содержат реальное коли-
чество точек данных, а также их количество, предполагаемое при расчете
коррекции.
Количество точек данных, использованное при расчете коррекции
коэффициентов корреляции, меньше, чем реальное их количество в на-
боре для обучения. Причина в повторяемости фактов, а именно в том, что
факт, основанный на некоторой точке данных, с большой вероятностью
будет весьма подобен факту, основанному на соседней точке. Из-за этого
«эффективное» число точек данных в отношении статистически незави-
264 ИССЛЕДОВАНИЕ входов в РЫНОК
ЧАСТЬ II




Показатели обучения нейронных сетей для прогнозирования
Таблица 11—1.
обращенного во времени Медленного % К
Корреляция
Число связей
Размер Корреляция
Название после коррекции
76
18-4-1 0,093 0,082 0,054
NN1.NET

114 0,118 0,105 0,072
NN2.NET 18-6-1

152 0,122 0,106
NN3.NET 18-8-1 0,058

0,124
190 0,104 0,029
NN4.NET 18-10-1

0,144
228 0,123
NN5.NET 18-12-1 0,058

304 0,156 0,130 0,031
NN6.NET 18-16-1

0,172
380 0,143
18-20-1 0,022
NN7.NET

312 0,169 0,145
18-14-4-1 0,070
NN8.NET

0,201
486 0,169
18-20-6-1 0,055
NN9.NET

88092 Подразумевалось 40000 13000
Реальное число




симой информации будет уступать реальному. Мы использовали два раз-
ных прореживания данных, представленных в двух столбцах. Процесс
коррекции корреляций подобен процессу коррекции вероятностей мно-
жественных тестов при оптимизации: при прогонке параметра через ряд
значений полученные результаты для соседних значений, скорее всего,
будут подобны, что снижает эффективное количество тестов по сравне-
нию с реальным.


<< Пред. стр.

стр. 31
(общее количество: 46)

ОГЛАВЛЕНИЕ

След. стр. >>