Д.Катс.Д.Маккормик.Энциклопедия торговых стратегий. Донна л. Маккормик
Скачать 5.96 Mb.
|
ГЛАВА 11 НЕЙРОННЫЕ СЕТИ 257 дают, и наоборот. Хорошая прогностическая модель — Святой Грааль тор- говли, который дает возможность продавать вблизи максимума и покупать вблизи минимума. Однако при неточной работе все преимущества про- гностической модели будут перевешены расходами на неудачные сделки. МОДЕЛЬ НА ОБРАЩЕННОМ ВО ВРЕМЕНИ МЕДЛЕННОМ %К Первый шаг в разработке нейронной сети с прогностическими функция- ми — это подготовка обучающего набора фактов, т.е. выборки данных, содержащей примеры для обучения сети, а также для оценки некоторых статистических показателей. В данном случае набор фактов генерирует- ся на основе данных из пределов выборки по всем рынкам в составе порт- феля: таким образом, набор фактов будет велик — 88 092 точки данных. Этот набор генерируется только для обучения, но не для тестирования по причинам, которые будут пояснены далее. Для получения набора фактов под данную модель сперва следует про- извести расчеты целевого показателя — обращенного во времени Мед- ленного %К. Каждый факт затем записывается в файл при проходе через все точки данных для всех рынков в составе портфеля. Для каждого тор- гового дня процесс создания факта начинается с расчета входных пере- менных. Это делается путем расчета разности между парой цен и делени- ем результата на квадратный корень количества дней, лежащих между этими двумя ценами. Квадратичная поправка используется, поскольку в случайном рынке стандартное отклонение между двумя днями примерно пропорционально квадратному корню от количества дней между ними. Эта поправка сделает вклад каждой разницы цен в факт примерно рав- ным. В этом эксперименте в каждом факте содержится 18 изменений цены, рассчитанных с квадратичной поправкой. Эти 18 значений будут служить как 18 входов нейронной сети после дополнительной обработки. Пары цен (использованные при расчете изменений) выбираются с возрастающим расстоянием между ценами, т.е. чем дальше во времени, тем расстояние между точками данных больше. Первые несколько пар перед текущим днем берутся с расстоянием в один день, т.е. цена преды- дущего дня вычитается из цены текущего и т.д. После нескольких таких пар шаг изменяется до 2 дней, затем до 4,8 и т.д. Точная расстановка вклю- чена в код программы в виде таблицы. Смысл этого состоит в получении максимально точной информации о новейших процессах. Чем дальше во времени от текущего дня находятся данные, тем больше вероятность того, что только долговременные процессы будут иметь значение, следователь- но, можно обойтись меньшим разрешением. Такая выборка дней должна обеспечивать достаточное разрешение для регистрации циклов и других явлений с периодом от 1 — 2 до 50 дней и более. Такой подход принят в соответствии с рекомендацией Марка Джурика (jurikres.com). 258 ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Собрав для будущего факта 18 скорректированных квадратным кор- нем разностей для входов, мы используем процедуру нормализации. Це- лью нормализации является удаление информации, заложенной в ампли- туде, при сохранении формы волны. При обращении с 18 переменными входа как с вектором, нормализация состоит в масштабировании вектора в единицы длины. Расчеты включают возведение каждого элемента век- тора в квадрат, сложение квадратов, вычисление квадратного корня и за- тем деление каждого элемента на полученное число. Так получаются пе- ременные входа для нейронной сети — фактически, программа нейрон- ной сети в дальнейшем еще раз будет масштабировать эти входы, приво- дя их значения к уровням, допустимым для входных нейронов. Для каждого факта целью (т.е. зависимой переменной регрессии) яв- ляется попросту значение обращенного во времени Медленного %К. Вход- ные переменные и цель для каждого факта выдаются в простом ASCII- формате в виде файла, который может анализироваться качественным пакетом для разработки нейронных сетей. Полученный набор фактов используется для обучения сети прогнози- рованию обращенного во времени Медленного %К, т.е. относительного положения сегодняшней цены закрытия и, предположительно, завтраш- ней цены открытия по отношению к диапазону цен за последующие 10 дней (обращенный во времени Медленный %К с периодом 10 дней). Следующий шаг разработки нейронного прогностического устрой- ства — реальная тренировка нескольких сетей на полученном наборе фактов. Обучают серию нейронных сетей различного размера, причем метод отбора наиболее хорошо обученной и устроенной сети не состоит, как можно было бы подумать, в проверке ее эффективности на данных вне пределов выборки. Вместо этого проводится коррекция коэффици- ентов корреляции (показателей прогностических способностей каждой сети), причем коэффициент коррекции зависит от размера выборки дан- ных и количества параметров (связей между нейронами) в исследуемой сети. При этом используется то же уравнение, что и при коррекции мно- жественных корреляций, получаемых при многовариантной регрессии (см. главу о статистике и оптимизации). Чем больше и сложнее сеть, тем сильнее будут скорректированы (в меньшую сторону) коэффициенты корреляции. Этот подход помогает оценить степень излишней подгонки системы под исходные данные. Чтобы большая сеть превзошла малень- кую, она должна давать значительно больший коэффициент корреляции. Этот метод позволяет выбирать лучшие сети без обычного обращения к данным вне пределов выборки. Все сети проходят полное обучение, т.е. не делается попыток скомпенсировать снижение степеней свободы мень- шим обучением сети. Наилучшие сети, отобранные на основе скорректированных корре- ляций, затем тестируются с настоящей моделью входа, стандартизован- ным выходом на всех рынках как в пределах, так и вне пределов выборки. ГЛАВА 11 НЕЙРОННЫЕ СЕТИ 259 Как было сказано выше, излишне подогнанные сети должны иметь очень низкие значения корреляции после проведения ее коррекции. Большое количество фактов в наборе (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] уровней капитала при закрытых позициях 260 ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК //объявляем локальные переменные 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) ; ГЛАВА 11 НЕЙРОННЫЕ СЕТИ . 261 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) ; } } 262 ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Код включает две функции — обычную функцию Model, реализую- щая торговую модель, и процедуру подготовки входов нейронной сети PrepareNeurallnputs. Процедура, которая подготавливает входы, требует для работы индекса текущего дня (cb) и серии цен закрытия (cls). Функция PrepareNeurallnputs при наличии индекса текущего дня и серии цен закрытия рассчитывает для данного факта все входы, необхо- димые нейронной сети. В списке параметр pbars указывает на относитель- ный по сравнению с текущим (приравненным к нулю) номер дня из про- шлых данных, используемый для вычисления вышеописанных разностей цен. Первый блок кода после объявления переменных запускает таблицу факторов подстройки цен. Таблица запускается на первом проходе фун- кции и содержит квадратные корни количества дней между каждой из пар цен, используемых для расчета разностей. Следующий блок кода рас- считывает скорректированные разности, а также суммы их квадратов, т.е. квадрат амплитуды или длину результирующего вектора. Код, реализующий торговую модель, основан на наших обычных прин- ципах. После объявления переменных ряд параметров копируется в ло- кальные переменные для простоты ссылок. Затем рассчитываются сред- ний истинный интервал, используемый для стандартного выхода, и обра- щенный во времени Медленный %К с периодом 10 дней. Один из параметров (mode) выбирает режим работы кода. Mode = 1 запускает код для подготовки факта; файл открывается, заголовок (состо- ящий из числа входов — 18 и числа целей — 1) записывается, и счет фак- тов начинается с нуля. Это производится только при открытии первого из рынков в составе портфеля. Файл остается открытым все время дальней- шей обработки, вплоть до конца обработки последнего символа в порт- феле. После заголовка в файл записываются факты. Все данные до нача- ла периода выборки и после окончания периода вне выборки игнориру- ются. Используются только данные в пределах выборки. Каждый факт, записанный в файл, состоит из номера факта, 18 переменных входов, рас- считанных процедурой PrepareNeurallnputs, и цели (значения обращен- ного во времени Медленного %К). Пользователю сообщается информа- ция о продвижении работы. Если mode выбирается равным 2, то нейронная сеть, обученная на вы- шеописанном файле с фактами, используется для генерации торговых вхо- дов. Первый блок кода открывает и загружает нужную сеть до начала рас- четов по первому рынку. После выполнения стандартных функций обнов- ления симулятора, расчета количества контрактов, избежания дней с ос- тановленной торговлей и т.п. запускается блок, генерирующий сигналы входа и выхода. Функция PrepareNeurallnputs вызывается для получения входных данных, соответствующих текущему дню. Сеть обрабатывает эти данные, и на основании ее выхода генерируются сигналы на вход в рынок. Правила генерации сигналов таковы: если на выходе нейронной сети значение превышает порог thresh, то подается сигнал на продажу — сеть ГЛАВА 11 НЕЙРОННЫЕ СЕТИ 263 предсказывает высокое значение обращенного во времени Медленно- го %К, т.е. текущая цена закрытия, возможно, близка к максимуму на бли- жайшее будущее. Если на выходе сети значение составляет менее 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. Показатели обучения нейронных сетей для прогнозирования обращенного во времени Медленного % К Название NN1.NET NN2.NET NN3.NET NN4.NET NN5.NET NN6.NET NN7.NET NN8.NET NN9.NET Реальное число Размер 18-4-1 18-6-1 18-8-1 18-10-1 18-12-1 18-16-1 18-20-1 18-14-4-1 18-20-6-1 88092 Число связей 76 114 152 190 228 304 380 312 486 Корреляция 0,093 0,118 0,122 0,124 0,144 0,156 0,172 0,169 0,201 Подразумевалось Корреляция после коррекции 0,082 0,105 0,106 0,104 0,123 0,130 0,143 0,145 0,169 40000 0,054 0,072 0,058 0,029 0,058 0,031 0,022 0,070 0,055 13000 симой информации будет уступать реальному. Мы использовали два раз- ных прореживания данных, представленных в двух столбцах. Процесс коррекции корреляций подобен процессу коррекции вероятностей мно- жественных тестов при оптимизации: при прогонке параметра через ряд значений полученные результаты для соседних значений, скорее всего, будут подобны, что снижает эффективное количество тестов по сравне- нию с реальным. Результаты обучения для модели обращенного во времени Медленного %К Как следует из табл. 11-1, значения некорректированной корреляции не- уклонно возрастали с увеличением сети в отношении количества связей. Если же провести коррекцию коэффициентов корреляции, то для эффек- тивной выборки величиной 13 000 точек картина драматически меняется: наиболее эффективными оказываются малые 3-слойные сети с 6 нейро- нами в среднем слое и наименьшая из двух 4-слойных сетей. При более умеренной коррекции ожидаемая прогностическая способность оказалась наибольшей для двух 4-слойных сетей, как видно из множественных кор- реляций результата с целью. |