WWW.DISSERS.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА

   Добро пожаловать!

Pages:     | 1 |   ...   | 3 | 4 || 6 | 7 |

«THE ENCYCLOPEDIA OF TRADING STRATEGIES JEFFREY OWEN KATZ, Ph.D. DONNA L. McCORMICK McGraw-Hill New York San Francisco Washington, D.C. Auckland Bogota Caracas Lisbon London Madrid Mexico City Milan ...»

-- [ Страница 5 ] --

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Теория групп фильтров недавно стала гораздо сложнее с появлением теории малых волн. На практическом уровне эта теория позволяет конструировать весьма изящные цифровые фильтры с большим числом полезных свойств. Использованные в нижеприведенных тестах фильтры основаны с рядом допущений на волнах Мореле. В принципе волны Мореле ведут себя подобно локализованным преобразованиям Фурье. Они захватывают информацию о циклической активности в данный момент времени, причем влияние других точек данных на результат очень быстро убывает при удалении этих точек от текущей. В отличие от фильтров Баттеруорта волны Мореле имеют максимальную временную локализацию для данного уровня избирательности (степени сглаживания). Это очень важно для фильтров, настроенных на поиск потенциально выгодных циклов на основе максимально свежих данных. Кроме того, использованные в тестах фильтры имеют преимущество очень высокой фазовой устойчивости, что принципиально важно при работе с циклами различной длины для определения моментов рыночных событий. Такие высокоуровневые фильтры могут быть использованы в составе групп, согласно методике, подобной описанной в нашей работе от мая 1997 г. Волновые фильтры, использованные в тестах, подобны квадратичным зеркальным фильтрам, которые имеют два выхода. Один выход по фазе в точности соответствует любому рыночному сигналу, имеющему частоту, равную центральной частоте полосы пропускания. Второй выход сдвинут по фазе ровно на 90°, т.е. его пики и провалы соответствуют нулевым значениям первого выхода, и наоборот. В математическом смысле эти выходы ортогональны. Используя их для вычисления мгновенной амплитуды циклической активности (на частоте настройки фильтра), достаточно взять сумму квадратов двух выходов, а затем извлечь из нее квадратный корень. Для определения силы циклического процесса не требуется искать максимумы и минимумы в фильтрованном сигнале и измерять их амплитуды. Кроме того, нет необходимости использовать экзотические методы, вроде расчета корреляции между фильтрованным сигналом и ценами в пределах примерно одного цикла, как мы делали в 1997 г. Если один из фильтров в составе группы обнаружит сильный цикл, то пара выходов этого фильтра может подавать сигнал торговой системе в любой желаемой фазе этого цикла. На рис. 10-1 изображен отклик фильтра на циклический процесс с постоянной амплитудой и возрастающим периодом. Центральная частота фильтра соответствует периоду 12. Вторая линия сверху изображает выходной сигнал фильтра с совпадающей фазой. Очевидно, что когда период входящего сигнала приближается к центру полосы пропускания, амплитуда выходного сигнала фильтра возрастает, достигая в центре полосы максимального значения. Когда период сигнала начинает превышать значение полосы пропускания, амплитуда на выходе падает. Вблизи центрального значения полосы пропускания выходной сигнал практически Рисунок 10-1.

Обработка сигнала квадратичным зеркальным волновым фильтром.

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК полностью совпадает с входящим. Третья линия (выход с фазой, смещенной на 90°) показывает такую же последовательность изменения амплитуды, за исключением фазового сдвига. Вблизи центрального значения полосы пропускания выходной сигнал смещен точно на 90°. Последняя, четвертая линия, изображает мгновенную мощность по данным двух предыдущих. Эта линия показывает амплитуду циклической активности на частоте, соответствующей середине полосы пропускания. На графике максимум наблюдается при периоде 13, а не в центре полосы пропускания фильтра (12), причиной этому — небольшое искажение, возникающее изза быстрого изменения периода исходного сигнала. Поскольку фильтр использует данные нескольких циклов, возникает искаженный общий результат. Тем не менее, очевидно, что на основе такого фильтра можно организовать выгодную торговлю. Масштаб оси Y не имеет значения и выбран просто для представления сигналов на разных линиях в пределах одного графика. На рис. 10-2 изображена частота (или же период) и фазовый ответ фильтра. В этом случае середина полосы пропускания фильтра установлена на периоде 20. Кривая относительной мощности изображает мощность выходного сигнала при изменяющейся частоте входного сигнала, амплитуда которого постоянна. Фильтр пропускает сигнал максимально при частоте, соответствующей середине полосы пропускания, а при удалении от нее в обе стороны выходная мощность быстро и плавно снижается. В кривой нет вторичных пиков, и мощность выходного сигнала при значительной разнице частот падает до нуля. Фильтр никак не реагирует на появление трендов, что весьма полезно для трейдеров. Такой фильтр способен работать с данными, не очищенными от трендов и не подвергнутыми дополнительной переработке. Фазовый ответ фильтра также демонстрирует полезные характеристики. На большей части спектра ответ находится в пределах ± 90°. На центральной частоте фазового сдвига нет, т.е. выходной сигнал в точности синхронизован с входным, что может обеспечить идеальные входы в рынок. Как и в случае с мощностью, кривая фазового ответа плавная и гладкая — любой ученый или инженер высоко оценил бы эффективность такого фильтра. При построении подобного графика для фильтров Баттеруорта в 1997 г. результаты были гораздо менее удовлетворительными, особенно в отношении фазового ответа и задержки. При незначительном изменении периода сигнала возникали большие сдвиги по фазе, что в реальном применении разрушило бы любые попытки использовать такой фильтр для осмысленных входов в рынок. На рис. 10-3 изображен импульсный ответ обоих выходов волнового фильтра — совпадающего по фазе с входным сигналом и ортогонального. Эти кривые напоминают почти идеальные экспоненциально затухающие синусоиды или косинусоиды. Впрочем, затухание не совсем экспоненциально, и относительные амплитуды пиков подвергаются незаметным подстройкам для избежания влияния трендов.

Рисунок 10-2.

Частота и фаза выходного сигнала квадратичного зеркального волнового фильтра.

ГЛАВА 10 Входы НА ОСНОВЕ циклов В дополнение к данным, представленным на графиках, были проведены другие тесты с использованием «плазмод». Плазмодой называют набор данных, подобранных так, чтобы содержать предполагаемые в реальных данных характеристики. Идея состоит в проверке того, насколько алгоритм или модель может обнаружить и проанализировать эти характеристики. Хорошая торговая система на основе циклов должна проявлять высокую эффективность на синтетической серии данных, состоящей из большого количества шума и изредка встроенных циклов. Фильтры, описанные в следующих тестах, работали в такой ситуации очень хорошо. ПОЛУЧЕНИЕ ЦИКЛИЧЕСКИХ ТОРГОВЫХ СИГНАЛОВ ВХОДА С ИСПОЛЬЗОВАНИЕМ ГРУПП ФИЛЬТРОВ Одним из способов получения сигналов входа является использование серии фильтров, настроенных на различные частоты или периоды, которые целиком перекрывают весь диапазон анализируемых частот. Если в одном из этих фильтров возникает сильный резонанс при отсутствии активности в других, можно предположить наличие на рынке сильного цикла. На основе поведения выходов фильтров определяются ожидаемые моменты возникновения ценовых минимумов (сигнал к покупке) и максимумов (сигнал к продаже). Поскольку наиболее сильно реагирующий фильтр не должен вызывать запаздывания и фазовых сдвигов, при его должной работе и реально существующих циклах на рынке можно получать чрезвычайно своевременные сигналы. Один из традиционных способов использования циклов на рынке — это попытка продавать по циклическим максимумам и покупать по циклическим минимумам. Получаемая от групп фильтров или других источников информация может также дополнять другие системы или адаптировать индикаторы к текущему состоянию рынка. Пример того, как метод обнаружения периода доминирующего цикла и соотношения сигнал/шум включается в другую торговую систему, можно найти у Ружжиеро (Ruggiero, 1997). ХАРАКТЕРИСТИКИ ЦИКЛИЧЕСКИХ ВХОДОВ Исследуемые ниже циклические входы (нацеленные на продажу по максимуму и покупку по минимуму) имеют ряд важных характеристик: высокий процент прибыльных сделок, низкое проскальзывание, способность захватывать максимально возможную часть каждого движения рынка — одним словом, мечта трейдера. Это справедливо только при условии, что на рынке действительно существуют предсказуемые циклы, которые можно обнаружить и, что еще важнее, экстраполировать имеющимися методами. Считается, что на рынках примерно 70% времени присутствует цик ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК лическая активность. Даже если четкие циклы, ведущие к выгодным сделкам, возникают гораздо реже, использование близких защитных остановок позволяет сводить к минимуму потери от неудачных сделок. Главный недостаток циклических входов состоит в том, что ввиду широкого распространения весьма мощных алгоритмов анализа циклов, например метода максимальной энтропии, рынки изменили свою природу и стали «менее уязвимыми» для подобных методов. Предсказуемые циклы обнаруживаются и нивелируются настолько быстро, что их исследования зачастую теряют смысл. Поскольку описываемые циклические входы по природе своей направлены против циклов, то при отсутствии продолжения циклов (т.е. при продолжении тренда) трейдер понесет потери, если не будут применены эффективные методы управления капиталом (защитные остановки). Пригодность к реальной работе сложных методик анализа циклов и будет рассмотрена в наших тестах. МЕТОДОЛОГИЯ ТЕСТИРОВАНИЯ Во всех тестах циклических моделей входа используется стандартный портфель из 36 рынков. Количество контрактов для покупки или продажи на каждом рынке подбиралось для соответствия долларовой волатильности двух контрактов S&P 500 на конец 1998 г. Использован стандартный выход: защитная остановка закрывает любую позицию, убытки которой превышают одну единицу волатильности. Кроме того, лимитный приказ закрывает позиции, прибыль которых превышает четыре единицы волатильности, а рыночный приказ по цене закрытия закрывает позиции, не закрытые предыдущими выходами в течение 10 дней. Правила входов рассмотрены в обсуждении модели и индивидуальных тестов. Все тесты проведены при помощи стандартного C-Trader toolkit. Ниже приведен код модели, основанный на волновом фильтре со стандартной стратегией выходов:

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 = x14mod01.c // parms — набор [1..MAXPRM] параметров // dt - набор [l..nb] дат в формате ГГММДД // орn — набор [1..nb] цен открытия // hi — набор [1..nb] максимальных цен // 1о - набор [l..nb] минимальных цен // cls — набор [1..nb] цен закрытия // vol — набор [1..nb] значений объема // oi — набор [1..nb] значений открытого интереса // dlrv - набор [l..nb] средних долларовой волатильности / / nb — количество точек в наборе данных // ts - ссылка на класс торгового стимулятора ГЛАВА Входы НА ОСНОВЕ циклов // eqcls - набор [l..nb] уровней капитала по ценам закрытия // объявляем локальные переменные static int rc, cb, ncontracts, maxhold, ordertype, signal;

static int disp, k, modeltype, fcount, goodcycle, domperndx;

static float mmstp, ptlim, stpprice, limprice, tmp;

static float width, oldwidth, lper, sper, per, ratio;

static float exitatr[MAXBAR+1], **inphase, **inquad, **power;

static float peakpower, phase, peaknoise, domperiod;

static float buyphase, sellphase, phaseb, oldphase, oldphaseb;

static WAVFILT filter[20];

// копируем параметры в локальные переменные для удобного обращения width = parms[l];

// ширина полосы пропускания фильтра (0.05.. 0.20} disp= parms[2];

// временное смещение в градусах modeltype = parms[8];

// модель: 1=торговать развороты циклов ordertype = parms[9];

// вход: 1=на открытии, 2=по лимитному приказу, // 3=по стоп-приказу maxhold = 10;

// период максимального удержания позиции ptlim = 4;

// целевая прибыль в единицах волатильности mmstp = 1;

// защитная остановка в единицах волатильности // Создаем искусственный набор цен закрытия в // форме синусоиды. Это «плазмода» для проведения тестов. // Модель должна хорошо торговать на данном наборе цен. // #define USESIMEWAVE #ifdef USESINEWAVE per = 3.0;

ratio = exp (log (30.0/3.0) / (nb - 1));

sper=0.0;

for (cb = 1;

cb <= nb;

cb++) ( sper += 2.0 * PI * (1.0 / per);

cls[cb] = sin(sper);

per *= ratio;

} #endif // инициализируем группу равноотстоящих волновых фильтров // заново инициализируем, если параметр ширины полосы изменился if(width != oldwidth) { lper ==30.0;

// фильтр длинных периодов sper = 3.О ;

// фильтр коротких периодов fcount = 2 0 ;

// число фильтров в группе ratio = exp (log (lper / sper) / (fcount - 1) ) ;

per = sper;

for(k = 1;

k <= fcount;

k++) ( filter[k-1].build_kernel(per, width);

per *= ratio;

} oldwidth = width;

} // рассчитываем выходы фильтров и откорректированный спектр мощности // если матрицы (таблицы) пустые, то присваиваем им значения if(inphase == NULL) inphase = matrix(l,fcount,1,MAXBAR);

if(inquad == NULL) inquad = matrix(1,fcount,l.MAXBAR);

if(power == NULL) power = matrix(1,fcount,1.MAXBAR);

for(k = 1 ;

k <= fcount;

k++) { filter[k-1].apply (cls, inphase[k], inquad[k], nb);

for(cb = 1;

cb <= nb;

cb++) power [k] [cb] = (inphase [k] [cb] * inphase [k] [cb] + inquad [k] [cb] * inquad [k] [cb] ) / filter[k-1].period();

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК } // сохраняем спектральный анализ выборки в файл // эта процедура проводится для отладки // #define WRITESAMPLE #ifdef WRITESAMPLE FILE *fil = fopen("test.dat", "wt");

for(cb = nb-1200;

cb < nb;

cb++) { domperndx = 0 ;

peakpower = -1.0;

for(k = 1;

k <= fcount;

k++) ( if(power[k][cb] > peakpower) { peakpower = power[k] [cb] ;

domperndx = k;

} ) phase = (180.0 / PI) * atan2 (inquad [domperndx] [cb], inphase[domperndx] for(k = 1;

k <= fcount;

k++) ( if (power [k] [cb] > 0.90 * peakpower) fprintf(fil, " **");

else if (power[k][cb] > 0.75 * peakpower) fprintf(fil, " ++");

else if (power[k][cb] > 0.5 * peakpower) fprintf(fil, " + ");

else fprintf(fil, " ");

) fprintf(fil, "%4d %7d %7d %7d %8.1f\n", (int)filter[domperndx-1].period(), (int)(inphase[domperndx] [cb]), (int)(inquad[domperndx] [cb]), (int)phase, cls [cb]);

} fclose(fil);

exit(0);

#endif // используется для отладки сигналов // #define SIGNALDEBUG #ifdef SIGNALDEBUG FILE *fil = fopen("testsig.dat", "wt");

#endif // выполняем вычисления для всех данных AvgTrueRangeS(exitatr,hi,lo,cls,50,nb) ;

[cb]);

// средний истинный диапазон для // выхода switch (modeltype) [ case 1: // Ничего не делайте! Место для будущего кода, break ;

default: nrerror ("Invalid model type");

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

cb <= nb;

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

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);

/ / н е торгуем в последние 30 дней выборки // оставляем место в массивах для будущих данных if(cb > nb-30) continue;

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

if (ncontracts < 1) ncontracts = 1;

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

// генерировать входные сигналы, цены стоп- и лимитных приказов signal = 0;

switch (modeltype) { case 1: // ищем хороший цикл для торговли domperndx = 0;

peakpower = -1.0;

for(k = 1;

k <= fcount;

k++) { if(power[k][cb] > peakpower) { peakpower = power[k][cb];

domperndx = k;

} } goodcycle = FALSE;

if(domperndx > 3 && domperndx < fcount-1) { peaknoise = 0.0;

for(k = 1;

k <= fcount;

k++) { if (abs(k - domperndx) > 2) { if (power[k] [cb] > peaknoise) peaknoise - power[k] [cb] ;

} } if(peakpower > 1.5 * peaknoise) goodcycle = TRUE;

} // генерируем торговые сигналы if (goodcycle) { domperiod = filter [domperndx-1].period() ;

phase = (180.0 / PI) * atan2(inquad[domperndx] [cb], inphase[domperndx] [cb]);

oldphase = (180.0 / PI) * atan2(inquad[domperndx] [cb-1], inphase[domperndx] [cb-1] );

phaseb - (phase<0.0) ? (360.0+phase) : phase;

oldphaseb = (oldphase<0.0) ? (360.0+oldphase) : oldphase;

sellphase = 0.0 - (disp + 180.0 / domperiod);

buyphase = 180.0 + sellphase;

if (phaseb > buyphase && oldphaseb <- buyphase) signal = 1;

// сигнал на покупку if (phase > sellphase && oldphase <= sellphase) signal = -1;

// сигнал на продажу } break;

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК } limprice = 0.5 * (hi [cb] + lo [cb] ) ;

stpprice = cls[cb] + 0.5 * signal * exitatr[cb];

// печатаем отладочную информацию #ifdef SIGNALDEBUG fprintf(fil, "%8d %8.1f %8d %8d %8d %8d\n", cb, cls[cb], signal, (int)filter[domperndx-1].period(), (int)peakpower, {int)peaknoise);

#endif // входим в сделку, используя определенный тип приказа 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);

} // обрабатываем следующий день // закрываем, если в режиме отладки #ifdef SIGNALDEBUG fclose(fil);

exit(0);

#endif } Вышеприведенный код описывает тестируемую модель. Первый важный блок кода, принципиальный для циклической модели, инициализирует индивидуальные фильтры, составляющие группу фильтров. Этот код работает только при первом проходе или при изменении параметра, влияющего на инициализацию группы фильтров, например параметра width. Если важные параметры остаются без изменений, не имеет смысла перезапускать фильтры при каждом вызове функции Model. Следующий блок применяет к входящему сигналу каждый из фильтров в составе группы. В этом блоке отведены два массива для хранения выходного сигнала группы фильтров. Первый массив хранит выход с совпадающей фазой inphase, а второй — ортогональный выход inquad. Входной сигнал представляет исходные цены закрытия. Поскольку фильтры математически оптимальны и рассчитаны на удаление трендов, предва ГЛАВА Входы НА ОСНОВЕ циклов рительная обработка данных становится излишней в отличие от менее продвинутых методик анализа. Каждая строка в массиве представляет собой выход отдельного фильтра с данной частотой или периодом, каждая колонка представляет собой торговый день. Центральные частоты или периоды фильтров расположены на равных расстояниях на логарифмической шкале, т.е. соотношение между центральной частотой данного и следующего фильтра постоянно. Селективность полосы пропускания (width) — единственный настраиваемый параметр в расчете группы фильтров, и это значение может подбираться путем оптимизации. Затем запускается обычный цикл перебора точек данных, и генерируются собственно торговые сигналы. Сначала проверяется наличие чистого, пригодного для торговли цикла. Для этого определяется мощность при периоде, имеющем максимальный резонанс с текущей активностью рынка (peakpower). Также оценивается период, на котором наблюдается максимальная мощность. Если период не попадает на одно из крайних значений рассматриваемого диапазона (диапазон составляет от 3 до 30 дней), то потенциально цикл может быть пригоден для торговли. Затем проверяется максимальная мощность на расстоянии не менее 2 полос пропускания фильтра от периода пика (peaknoise). Если отношение peakpower/ peaknoise составляет 1,5 или более, то выполняется второе условие пригодности цикла. На основе пары выходов определяется фазовый угол цикла. Затем код проверяет фазовый угол на соответствие максимуму или минимуму цены. Кроме того, в эту оценку вводится небольшое значение смещения (disp). Оно работает подобно смещению в предыдущих моделях, хотя здесь относится к фазовому углу, а не к количеству точек данных. Между фазовым углом и количеством точек данных существует прямая зависимость: период цикла, умноженный на фазовый угол в градусах и разделенный затем на 360, дает количество точек данных, соответствующее фазовому углу. Если фаза после смещения такова, что через некоторое количество градусов до или после текущего дня можно ожидать минимума, отдается приказ на покупку. Если фаза такова, что можно ожидать максимума, отдается приказ на продажу. Затем, как обычно, рассчитываются цены для лимитного и стоп-приказов. При поступлении сигналов система исполняет требуемые приказы. Другие блоки вышеприведенного кода здесь не обсуждаются, поскольку связаны с отладкой и тестированием программы. Их предназначение описано в комментариях к коду.

РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ Тестировалась только одна модель с входами по цене открытия (тест 1), по лимитному приказу (тест 2) и стоп-приказу (тест 3). Правила были простыми: покупать на предсказанных минимумах и продавать на предска ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК занных максимумах. Выходы производились при поступлении сигнала к открытию противоположной позиции или при срабатывании стандартного выхода. Эта простая торговая система сначала испытывалась на искусственных ценовых данных, созданных путем добавления шума к идеальной синусоиде с периодом от 4 до 20 дней. На этих данных были получены сигналы покупки и продажи, идеально совпадающие с максимумами и минимумами. Такое совпадение показывает, что при наличии реальных циклов система способна обнаруживать их с высокой точностью и использовать в торговле. В табл. 10-1 приведены лучшие показатели, полученные для данных, находящихся в пределах выборки, а также эффективность портфеля на данных в пределах и вне пределов выборки. В таблице: ВЫБ. — вид выборки данных (В — в пределах, ВНЕ — вне пределов выборки);

ДОХ% — доходность в процентах годовых;

Р/ПРИБ — соотношение риска/прибыли в годовом исчислении;

ВЕР — ассоциированная вероятность статистической достоверности;

СДЕЛ — число сделок на всех рынках в составе портфеля;

ПРИБ% — процент прибыльных сделок;

$СДЕЛ — средняя прибыль/убыток со сделки;

ДНИ — средняя длительность сделки в днях;

ПРИБДЛ — общая прибыль от длинных позиций в тысячах долларов;

ПРИБКР — общая прибыль от коротких позиций в тысячах долларов. Оптимизировались два параметра. Первый (Р1) определяет ширину полосы пропускания для каждого фильтра в составе группы. Второй (Р2) отображает фазовое смещение в градусах. Во всех случаях параметры прогонялись в пределах выборки для ширины полосы пропускания от 0,05 до 0,2 с шагом 0,05 и для фазового сдвига от —20 до +20° с шагом 10°. Показаны только оптимальные решения. Интересно отметить, что в общем циклическая модель имела достаточно низкую эффективность. По показателю прибыли со сделки эта модель превосходила многие рассмотренные ранее, но сильно уступала лучшим из них. В пределах выборки убыток со сделки оставил $ 1329 при входе по цене открытия, $1037 при входе по лимитному приказу и $1245 при входе по стоп-приказу. Вход по лимитному приказу обеспечил максимальный процент прибыльных сделок и минимальный средний убыток. Длинные позиции были слабо прибыльными при входе по цене открытия, более прибыльны при входе по лимитному приказу и убыточны при входе по стоп-приказу. Вне пределов выборки входы по лимитному приказу и цене открытия работали хуже, чем в пределах выборки. Средний убыток в сделке составил $3741 при входе по цене открытия и $3551 при входе по лимитному приказу. Доля прибыльных сделок также снизилась до 34%. Эффективность циклической модели вне пределов выборки была одной из худших среди всех моделей, что нельзя отнести на счет избыточной оптимизации: при других параметрах убытки были еще больше. При использовании входа по стоп-приказу эффективность вне пределов выборки не ухудшалась, средний убыток ($944) в сделке был близок к убытку в ГЛАВА 1О Входы НА ОСНОВЕ циклов Таблица 10—1.

Эффективность портфеля на данных в пределах и вне пределов выборки с лучшими параметрами, полученными в пределах выборки Выб.

Р Р РЗ дох% Р/ПРИБ ВЕР СДЕЛ ПРИБ% $СДЕЛ ДНИ ПРИБДЛ ПРИБКР Тест 1. Базовая циклическая модель, вход по цене открытия В 0,2 20 0 -10,2 -0,66 0,980 1312 1,000 547 ВНЕ 0,2 20 0 -23,2 -1,70 Тест 2. Базовая циклическая модель, вход по лимитному приказу В 0,2 20 0 -9,5 -0,46 0,926 1103 ВНЕ 0,2 20 0 -22,8 -1,47 0,999 475 Тест 3. Базовая циклическая модель, вход по стоп-приказу В 0,1 20 0 -8,3 -0,53 0,951 ВНЕ 20 0 -15,0 -0,35 0,762 0, 40 -1329 - 6 255 - -2000 - 41 -1037 - 7 621 - -1764 - 957 40 -1245 - 7 -195 - -996 - пределах выборки. Однако, несмотря на то что применение входа по стопприказу предотвратило падение эффективности, отмеченное при других видах входа, очевидно, что на новых данных система все равно убыточна. Ухудшение эффективности системы за последние годы было по сравнению с другими моделями неожиданно сильным. Одним из возможных объяснений можно считать широкое распространение в последние годы сложных циклических торговых систем. Кроме того, может сказаться влияние того, что крупные торговые фирмы широко используют сложные методы, включая описанные волновые, в исследованиях, формирующих их торговую политику. Таким образом, в последнее время становится все меньше возможностей использовать в торговле циклические свойства рынков. В табл. 10-2 показано поведение модели с различными входами на различных рынках в пределах и вне пределов выборки. В первом столбце приведено обозначение рынка, средний и правый столбцы — количество прибыльных тестов для данного рынка. Цифры в первой строке показывают вид входа: 01 — по цене открытия, 02 — по лимитному приказу и 03 — по стоп-приказу. Последняя строка показывает, на скольких рынках данная модель была выгодной. Степень прибыльности и убыточности рынков для каждой модели указана следующим образом: один минус ( — ) означает убыток в $2000 — 4000;

два минуса ( ) — убыток более $4000;

один плюс ( + ) означает прибыль от $1000 до $2000;

два плюса (+ +) — прибыль более $2000;

пустая ячейка означает прибыль до $1000 или убыток до $1999 в сделке. (Названия рынков и их символы соответствуют обозначениям табл. II-1;

часть II, введение.) ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 10—2.

Эффективность системы на различных рынках по тестам ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Только 10-летние казначейские бумаги и хлопок показали значительную прибыль в пределах выборки при использовании всех трех видов приказов, вне выборки эффективность этих рынков была ничтожной. На рынке S&P 500, где по нашим собственным данным присутствуют выраженные и пригодные для торговли циклы, в пределах выборки были получены значительные прибыли при входе по цене открытия или по лимитному приказу. Вне пределов выборки этот рынок также был высокоприбыльным при входе по лимитному приказу и по стоп-приказу и менее прибыльным при входе по цене открытия. Интересно, что на рынке NYFE, где в пределах выборки отмечена значительная прибыль при входах по цене открытия и по лимитному приказу, вне пределов выборки во всех случаях отмечались только убытки. Отмечено несколько других прибыльных сочетаний как в пределах, так и вне пределов выборки, но выраженной взаимосвязи между ними обнаружить не удалось. Возможно, рынки, обладавшие циклическими свойствами в прошлом (в пределах выборки), потеряли их к настоящему времени (вне пределов выборки), и наоборот. По крайней мере, рынок S&P 500 вел себя согласно данным нашего прошлого исследования и постоянно давал прибыль даже с такой грубой моделью. Рис. 10-4 изображает график изменения капитала при торговле портфелем для входа по цене открытия. Капитал медленно понижался примерно до августа 1992 г., после чего падение стало постоянным и быстрым.

ЗАКЛЮЧЕНИЕ В статье, опубликованной в мае 1997 г., мы утверждали, что метод групп фильтров имеет потенциал мощной и эффективной торговой стратегии. Порой он работал невероятно успешно и был почти нечувствителен к значительным изменениям своих параметров, порой работал плохо — возможно, из-за неумелого программирования. Тогда исследовался рынок S&P 500, приносивший прибыли и в нынешнем исследовании. Результаты этого исследования удручают, тем более что теоретическая основа фильтров стала изящнее. Возможно, при использовании для анализа циклов других методов, например метода максимальной энтропии, результат был бы лучше, а возможно, и нет. Подробные же разочарования постигали и других трейдеров, пытавшихся использовать различные идеи для циклической торговли с простым принципом продажи по максимуму и покупки по минимуму. Возможно, циклы слишком уж очевидны и обнаружимы практически любым способом, что приводит к эксплуатации цикла всеми участниками рынка. В последнее время, с распространением программ для анализа циклов, это кажется наиболее вероятным. Мы считаем, что не стоит отказываться от концепции циклической торговли, но использовать обнаруженные циклы более сложными спосо ГЛАВА Входы НА ОСНОВЕ циклов бами можно в сочетании с другими критериями входов, например можно открывать позицию только при совпадении циклического максимума с сезонной точкой разворота. По нашему опыту, в случае успешной реализации циклическая торговая система дает весьма точные сигналы входа. Тем не менее убыточные сделки циклической системы могут привести к катастрофическим результатам. Такой вывод можно сделать по графику S&P 500: зачастую 4 — 5 раз подряд сделки заключаются в точном совпадении с максимумами и минимумами рынка, а порой позиция открывается именно там, где не следует. С использованием правильной стратегии выходов такая система может быть чрезвычайно выгодной — убытки должны пресекаться в корне, но при правильном прогнозе позиции нужно удерживать подольше. Высокая точность прогнозов в тех случаях, когда они верны, и очень близко расположенная защитная остановка могли бы содействовать достижению цели. Когда система улавливает точный момент максимума или минимума, рынок немедленно начинает движение в благоприятном направлении, почти без обратных движений, и защитная остановка не срабатывает. Когда модель ошибается, остановка срабатывает почти мгновенно, сводя убыток к минимуму. Поскольку у стандартных выходов защитная остановка располагалась достаточно далеко, преимущества циклической системы могли остаться нереализованными.

ЧТО МЫ УЗНАЛИ?

• Теоретически солидные, изящные и привлекательные модели не обязательно хорошо работают на реальном рынке. • Исключение: рынок S&P 500 был прибылен и в предыдущем, и в настоящем исследовании. Если модель работает, то работает очень выгодно. Как было сказано ранее при исследовании поведения S&P 500 и других рынков, можно легко и быстро обнаружить последовательности сигналов, точно предсказывающих максимумы и минимумы. • Следовательно, необходимы специализированные выходы, рассчитанные на систему, которая при срабатывании весьма точна, но в случае ошибки приводит к большим убыткам. Видимо, рынок со временем стал «менее уязвим» в отношении циклических моделей, как это было с моделями, основанными на пробоях. Очевидные, явные циклы исчезают раньше, чем большинство трейдеров успевает получить в них прибыль. Следовательно, все, что слишком гладко и привлекательно в теории, вряд ли приведет к успеху в реальной торговле.

ГЛАВА Нейронные сети Технология нейронных сетей, одного из видов искусственного интеллекта (AI), возникла на основе подражания процессам обработки информации и принятия решений, происходящих в живых организмах. Целью было моделирование поведения нервной ткани живых систем при помощи компьютерных структур, организованных из программно симулируемых нейронов и нейронных связей (синапсов). Исследования нейронных сетей на теоретическом уровне начались в 1940-х годах. Когда компьютерная технология стала достаточно мощной для реализации подобных исследований, работа началась всерьез. Во второй половине 1980-х годов системы на основе нейронных сетей стали представлять интерес для биржевой общественности. К 1989 г. ряд разработчиков уже предлагали пакеты для создания инструментов на нейронных сетях. Scientific Consultant Services разработал коммерческую систему NexTurn для прогнозирования индекса S&P 500. Интерес достиг пика в начале 1990-х годов, появились новые программы, но по причинам, о которых будет сказано ниже, к настоящему времени первоначальное увлечение финансовой общественности нейронными сетями прошло. Поскольку мы не собираемся представлять в этой книге полный курс по нейронным сетям, эта глава будет содержать краткий обзор, содержащий основное для понимания принципов работы. Те, кто заинтересуется предметом, могут обратить внимание на материалы в книгах «Virtual Trading» (Ledermanand Klein, 1995) и «Computerized Trading» (Jurik, 1999), где также имеется подробная информация о разработке систем на основе нейронных сетей, а также на ряд статей в Technical Analysis of Stocks and Commodities (Katz, апрель 1996, Katz and McCormick, ноябрь 1996 и 1997). Также следует обратить внимание на книгу «Neural Networks in Finance and Investing» (Trippi and Turban, 1993).

ЧТО ТАКОЕ НЕЙРОННЫЕ СЕТИ?

Нейронные сети представляют собой, в сущности, некие блоки со способностью к самообучению и распознаванию образов, классификации и ГЛАВА НЕЙРОННЫЕ СЕТИ прогнозированию. Они особо привлекательны для трейдеров, поскольку сети могут справляться и с оценками вероятности в неоднозначных ситуациях, и с моделями нечеткой логики, т.е. с моделями, легко определимыми на вид, но с трудом поддающимися алгоритмизации в виде точных правил. Потенциально, нейронные сети могут обнаруживать любые присутствующие в исходных данных повторяющиеся модели. Сети также могут интегрировать большие объемы информации, не захлебываясь в деталях, и могут адаптироваться к изменениям рынков и их условий. Существует большое разнообразие нейронных сетей, отличающихся своей «архитектурой», т.е. способом связи виртуальных нейронов, деталями их поведения (обработкой сигнала или «функциями передачи») и процессом обучения. Существуют различные виды архитектур сетей представляющих интерес для трейдеров, например сети Коонена и сети с квантованием обучающего вектора (LVQ), различные сети с адаптивным резонансом и периодические сети. В этой главе будет рассмотрена наиболее популярная и полезная во многих отношениях архитектура, а именно нейронная сеть с прямой связью. Как было сказано выше, сети различаются по методу обучения. Разработчики системы играют роль учителя, снабжая сеть примерами для обучения. Некоторые сети обучаются «под контролем», некоторые «без контроля». Обучение под контролем имеет место, когда сеть обучают давать правильные ответы, показывая ей примеры правильных решений;

для каждого набора входов целью сети является обеспечение правильного выхода. Обучение без контроля состоит в том, что сеть организует введенные данные так, как считает нужным, на основе найденных в них внутренних закономерностей. Вне зависимости от формы обучения основная проблема состоит в поиске соответствующих данных и придании им формы учебных примеров, фактов, которые выделяют важные модели для эффективного и направленного обучения сети, во избежание формирования заблуждений. Предварительная подготовка данных — само по себе искусство. Собственно процесс обучения обычно включает некоторый механизм обновления удельных весов или важности разных связей между нейронами в ответ на подаваемые учебные примеры. При использовании в архитектуре прямых связей часто используют обратное распространение — наиболее быструю форму оптимизации. Также эффективны генетические алгоритмы, которые требуют большого количества расчетов и времени, но обычно дают лучшие окончательные результаты.

Нейронные сети с прямой связью Сеть с прямой связью состоит из слоев нейронов. Первый слой, входной, получает информацию или вводы извне. Этот слой состоит из независи ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК мых переменных, например значении цен или индикаторов, на которых основывается система в последующих заключениях или прогнозах. Этот слой имеет множество связей со следующим, называемым скрытым слоем, поскольку он не имеет связей с внешним миром. Выходы этого слоя подаются на следующий слой, который может быть также скрытым (если это так, то процесс повторяется) или выходным слоем. Каждый из нейронов выходного слоя выдает сигнал, основанный на прогнозах, классификациях или решениях, сделанных сетью. Сети обычно определяются по количеству нейронов в каждом слое;

например сеть 10-3-1 состоит из 10 нейронов во входном, 3 в скрытом и 1 в выходном слое. Сети бывают различного размера — от нескольких нейронов до тысяч и от всего трех слоев до десятков;

сложность зависит от размаха решаемой задачи. Практически всегда бывает достаточно трех-четырех слоев. Нейронные сети с прямой связью (аналоги использованной в этой главе) включают особую форму нелинейной множественной регрессии. Сеть берет ряд входных переменных и использует их для прогнозирования цели задания, как и при регрессии. В стандартной множественной линейной регрессии, например, если ставится задача предсказать уровень холестерола (зависимая переменная) на основе потребления жиров и физической нагрузки (независимые входные переменные), то данные будут моделироваться следующим образом: прогнозируемый уровень холестерола = а + b х потребление жиров + с X нагрузку, где значения a, b и с будут определяться статистической процедурой. Будет производиться поиск множества решений задачи, которое может быть линией, плоскостью или гиперплоскостью (в зависимости от количества переменных) согласно правилу наименьших квадратов. В вышеприведенной задаче все решения находятся на плоскости: ось х представляет потребление жиров, ось у—физическую нагрузку, высота плоскости в каждой точке (х, у) представляет собой прогнозируемый уровень холестерола. При использовании технологии нейронных сетей двумерная плоскость или n-мерная гиперплоскость множественной линейной регрессии заменяется гладкой n-мерной изогнутой поверхностью с пиками и провалами, хребтами и оврагами. Например, нам требуется найти оптимальное решение для набора переменных, и задача будет сводиться к построению многомерной карты. В нейронной сети решение достигается при помощи «нейронов» — взаимосвязанных нелинейных элементов, связи которых сбалансированы так, чтобы подгонять поверхность подданные. Алгоритм обучения производит регулировку весов связей для получения максимально вписывающейся в исходные данные конфигурации поверхности. Как и в случае со стандартной множественной регрессией, где коэффициенты регрессии необходимы для определения наклона гиперповерхности, для нейронной модели требуются параметры (в виде весов связей), чтобы обеспечить наилучшее совпадение построенной поверхности, всех ее возвышений и впадин, с входными данными.

ГЛАВА НЕЙРОННЫЕ СЕТИ НЕЙРОННЫЕ СЕТИ В ТОРГОВЛЕ Нейронные сети были наиболее популярны в конце 80 — начале 90-х годов, после чего медовый месяц завершился. Что же произошло? В общем, наступило разочарование среди трейдеров, надеявшихся, что новые технологии чудесным образом обеспечат им превосходство с минимальными затратами усилий. Разработчики использовали для обучения недостаточно подготовленные исходные данные, надеясь на открытия, которые должна была сделать сама сеть. Это был наивный подход. Успех на рынке никогда не бывает таким простым и доступным для всех. Этот подход был не только неэффективен в отношении разработки сетей, но и привел к тому, что сети широко распространились. В результате любая попытка систем уловить выгодные движения рынка сводилась к нулю ввиду изменившейся природы рынка, который быстро адаптировался к новым методам торговли. Во всем обвинили саму технологию и отбросили ее, не задумавшись о неправильном подходе к ее применению. Для получения успешных результатов был необходим более осмысленный и изощренный подход. Большинство попыток разработать прогностические модели на основе нейронных сетей, простые или усложненные, были сконцентрированы на отдельных рынках. Проблема с отдельными рынками состоит в том, что количество точек данных для обучения сети весьма ограничено и ведет к переоптимизации, что, особенно в сочетании с не слишком хорошо подготовленными данными, ведет к провалу при торговле. В этой главе нейронные сети будут обучаться на основе целого портфеля ценных бумаг, валют и фьючерсов, что позволит использовать для избежания подгонки десятки тысяч точек данных — приличное количество для маленькой или средней нейронной сети. Возможно, таким образом удастся заставить работать достаточно прямолинейный алгоритм прогнозирования рынка. Фактически, такая сеть сможет служить универсальным прогностическим средством, т.е. после обучения на целом портфеле она сможет прогнозировать в отдельности каждый из рынков. ПРОГНОЗИРОВАНИЕ С ПОМОЩЬЮ НЕЙРОННЫХ СЕТЕЙ Нейронные сети будут разрабатываться с целью прогнозирования: ( I ) куда уйдет рынок в ближайшем будущем и (2) будет ли завтрашняя цена открытия представлять собой точку разворота. Для первого случая будет сооружаться сеть, прогнозирующая обращенный во времени стохастический осциллятор, а именно обращенный Медленный %К. Это, в общем, стандартный осциллятор, но рассчитываемый с обратным отсчетом времени. Такой осциллятор отражает текущее положение цены закрытия по отношению к нескольким последующим дням. Несомненно, предсказание значения такого индикатора было бы полезно для трейдера: зная, что ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК сегодняшняя цена закрытия и, вероятно, завтрашняя цена закрытия лежат внизу ценового диапазона нескольких следующих дней, можно предполагать, что это хорошая ситуация для покупки, и наоборот, если сегодняшняя цена открытия лежит вблизи максимума ближайшего будущего, время поразмыслить о продаже. Во втором случае представим моделирование ситуации с завтрашним открытием — будет ли эта цена максимумом или минимумом? Для решения этой задачи будут обучены две нейронные сети: одна на определение минимума в завтрашней цене открытия, другая на определение максимума. Возможность предсказать максимум или минимум на завтрашней цене открытия также полезно для трейдера, решающего, входить ли в рынок и какую позицию занимать—длинную или короткую. Целью этого исследования будет получение таких прогнозов в отношении любого рынка, где используется модель.

ВХОДЫ НА ОСНОВЕ НЕЙРОННОЙ СЕТИ Мы будем обучать три нейронные сети, дающие три модели входа. Две из них будут настроены на поиск точек разворота: одна будет определять минимумы, другая — максимумы. Если модель, определяющая минимум, покажет, что вероятность минимума на завтрашней цене открытия выше некоторого порога, то будет отдан приказ на покупку. Если модель, определяющая максимум, покажет, что вероятность максимума на завтрашней цене открытия выше некоторого другого порога, то будет отдан приказ на продажу. Ни одна из этих моделей не будет отдавать приказы при каких-либо других условиях. Таким образом, стратегия проста и основана только на предсказанных минимумах и максимумах. Если вероятность определения максимумов и минимумов будет выше случайной, то торговля будет прибыльной. Система обнаружения не должна быть идеальной, пусть вероятность правильного сигнала будет выше 50% — этого будет достаточно, чтобы преодолеть транзакционные затраты. Для модели, использующей обращенный во времени Медленный %К, будет использоваться подобная стратегия. Если прогноз показывает, что обращенный во времени Медленный %К имеет вероятность быть ниже установленного порога, будет отдан приказ на покупку;

это значит, что рынок находится вблизи минимума некоторого будущего ценового диапазона и можно быстро получить прибыль. Таким же образом, если прогнозируемое значение обращенного Медленного %К высоко и превышает некоторый верхний порог, будет отдан приказ на продажу. Эти входы, как и многие другие, рассмотренные в предыдущих главах, являются прогностическими — они предсказывают рынок, а не следуют за ним. Они подходят для торговли против тренда и при точном предсказании могут резко снизить проскальзывание, обеспечить своевременное выполнение приказов, поскольку трейдер будет покупать, когда другие про ГЛАВА НЕЙРОННЫЕ СЕТИ дают, и наоборот. Хорошая прогностическая модель — Святой Грааль торговли, который дает возможность продавать вблизи максимума и покупать вблизи минимума. Однако при неточной работе все преимущества прогностической модели будут перевешены расходами на неудачные сделки.

МОДЕЛЬ НА ОБРАЩЕННОМ ВО ВРЕМЕНИ МЕДЛЕННОМ %К Первый шаг в разработке нейронной сети с прогностическими функциями — это подготовка обучающего набора фактов, т.е. выборки данных, содержащей примеры для обучения сети, а также для оценки некоторых статистических показателей. В данном случае набор фактов генерируется на основе данных из пределов выборки по всем рынкам в составе портфеля: таким образом, набор фактов будет велик — 88 092 точки данных. Этот набор генерируется только для обучения, но не для тестирования по причинам, которые будут пояснены далее. Для получения набора фактов под данную модель сперва следует произвести расчеты целевого показателя — обращенного во времени Медленного %К. Каждый факт затем записывается в файл при проходе через все точки данных для всех рынков в составе портфеля. Для каждого торгового дня процесс создания факта начинается с расчета входных переменных. Это делается путем расчета разности между парой цен и делением результата на квадратный корень количества дней, лежащих между этими двумя ценами. Квадратичная поправка используется, поскольку в случайном рынке стандартное отклонение между двумя днями примерно пропорционально квадратному корню от количества дней между ними. Эта поправка сделает вклад каждой разницы цен в факт примерно равным. В этом эксперименте в каждом факте содержится 18 изменений цены, рассчитанных с квадратичной поправкой. Эти 18 значений будут служить как 18 входов нейронной сети после дополнительной обработки. Пары цен (использованные при расчете изменений) выбираются с возрастающим расстоянием между ценами, т.е. чем дальше во времени, тем расстояние между точками данных больше. Первые несколько пар перед текущим днем берутся с расстоянием в один день, т.е. цена предыдущего дня вычитается из цены текущего и т.д. После нескольких таких пар шаг изменяется до 2 дней, затем до 4,8 и т.д. Точная расстановка включена в код программы в виде таблицы. Смысл этого состоит в получении максимально точной информации о новейших процессах. Чем дальше во времени от текущего дня находятся данные, тем больше вероятность того, что только долговременные процессы будут иметь значение, следовательно, можно обойтись меньшим разрешением. Такая выборка дней должна обеспечивать достаточное разрешение для регистрации циклов и других явлений с периодом от 1 — 2 до 50 дней и более. Такой подход принят в соответствии с рекомендацией Марка Джурика (jurikres.com).

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

ГЛАВА НЕЙРОННЫЕ СЕТИ Как было сказано выше, излишне подогнанные сети должны иметь очень низкие значения корреляции после проведения ее коррекции. Большое количество фактов в наборе (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 ИССЛЕДОВАНИЕ входов в РЫНОК //объявляем локальные переменные 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) ;

ГЛАВА НЕЙРОННЫЕ СЕТИ.

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 ИССЛЕДОВАНИЕ входов в РЫНОК Код включает две функции — обычную функцию Model, реализующая торговую модель, и процедуру подготовки входов нейронной сети PrepareNeurallnputs. Процедура, которая подготавливает входы, требует для работы индекса текущего дня (cb) и серии цен закрытия (cls). Функция PrepareNeurallnputs при наличии индекса текущего дня и серии цен закрытия рассчитывает для данного факта все входы, необходимые нейронной сети. В списке параметр pbars указывает на относительный по сравнению с текущим (приравненным к нулю) номер дня из прошлых данных, используемый для вычисления вышеописанных разностей цен. Первый блок кода после объявления переменных запускает таблицу факторов подстройки цен. Таблица запускается на первом проходе функции и содержит квадратные корни количества дней между каждой из пар цен, используемых для расчета разностей. Следующий блок кода рассчитывает скорректированные разности, а также суммы их квадратов, т.е. квадрат амплитуды или длину результирующего вектора. Код, реализующий торговую модель, основан на наших обычных принципах. После объявления переменных ряд параметров копируется в локальные переменные для простоты ссылок. Затем рассчитываются средний истинный интервал, используемый для стандартного выхода, и обращенный во времени Медленный %К с периодом 10 дней. Один из параметров (mode) выбирает режим работы кода. Mode = 1 запускает код для подготовки факта;

файл открывается, заголовок (состоящий из числа входов — 18 и числа целей — 1) записывается, и счет фактов начинается с нуля. Это производится только при открытии первого из рынков в составе портфеля. Файл остается открытым все время дальнейшей обработки, вплоть до конца обработки последнего символа в портфеле. После заголовка в файл записываются факты. Все данные до начала периода выборки и после окончания периода вне выборки игнорируются. Используются только данные в пределах выборки. Каждый факт, записанный в файл, состоит из номера факта, 18 переменных входов, рассчитанных процедурой PrepareNeurallnputs, и цели (значения обращенного во времени Медленного %К). Пользователю сообщается информация о продвижении работы. Если mode выбирается равным 2, то нейронная сеть, обученная на вышеописанном файле с фактами, используется для генерации торговых входов. Первый блок кода открывает и загружает нужную сеть до начала расчетов по первому рынку. После выполнения стандартных функций обновления симулятора, расчета количества контрактов, избежания дней с остановленной торговлей и т.п. запускается блок, генерирующий сигналы входа и выхода. Функция PrepareNeurallnputs вызывается для получения входных данных, соответствующих текущему дню. Сеть обрабатывает эти данные, и на основании ее выхода генерируются сигналы на вход в рынок. Правила генерации сигналов таковы: если на выходе нейронной сети значение превышает порог thresh, то подается сигнал на продажу — сеть ГЛАВА НЕЙРОННЫЕ СЕТИ предсказывает высокое значение обращенного во времени Медленного %К, т.е. текущая цена закрытия, возможно, близка к максимуму на ближайшее будущее. Если на выходе сети значение составляет менее 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 точек. Последние строки содержат реальное количество точек данных, а также их количество, предполагаемое при расчете коррекции. Количество точек данных, использованное при расчете коррекции коэффициентов корреляции, меньше, чем реальное их количество в наборе для обучения. Причина в повторяемости фактов, а именно в том, что факт, основанный на некоторой точке данных, с большой вероятностью будет весьма подобен факту, основанному на соседней точке. Из-за этого «эффективное» число точек данных в отношении статистически незави ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 11—1.

Показатели обучения нейронных сетей для прогнозирования обращенного во времени Медленного % К Размер 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 Число связей Корреляция 0,093 Корреляция после коррекции 0,082 0,054 0,072 0,058 0,029 0, Название NN1.NET NN2.NET NN3.NET NN4.NET NN5.NET NN6.NET NN7.NET NN8.NET NN9.NET Реальное число 76 114 152 190 228 304 380 312 0,118 0,122 0,124 0,144 0,156 0,172 0,169 0, Подразумевалось 0,105 0,106 0,104 0,123 0,130 0,143 0,145 0, 0, 0,022 0,070 0,055 симой информации будет уступать реальному. Мы использовали два разных прореживания данных, представленных в двух столбцах. Процесс коррекции корреляций подобен процессу коррекции вероятностей множественных тестов при оптимизации: при прогонке параметра через ряд значений полученные результаты для соседних значений, скорее всего, будут подобны, что снижает эффективное количество тестов по сравнению с реальным. Результаты обучения для модели обращенного во времени Медленного %К Как следует из табл. 11-1, значения некорректированной корреляции неуклонно возрастали с увеличением сети в отношении количества связей. Если же провести коррекцию коэффициентов корреляции, то для эффективной выборки величиной 13 000 точек картина драматически меняется: наиболее эффективными оказываются малые 3-слойные сети с 6 нейронами в среднем слое и наименьшая из двух 4-слойных сетей. При более умеренной коррекции ожидаемая прогностическая способность оказалась наибольшей для двух 4-слойных сетей, как видно из множественных корреляций результата с целью.

ГЛАВА НЕЙРОННЫЕ СЕТИ При более консервативной оценке (с меньшей эффективной выборкой и, следовательно, с большей коррекцией коэффициентов корреляции) на основе данных табл. 11 -1 для работы в модели было выбрано две сети — сеть 18-6-1 (rm2.net) и сеть 18-14-4-1 (nn8.net). Они были признаны лучшими из сетей, способными потенциально эффективно работать вне пределов выборки. Для теста модели входа в рынок программа прогонялась со значением mode = 2;

как обычно, тестировались все входы — по цене открытия, по лимитному приказу и по стоп-приказу. МОДЕЛИ НА ОСНОВЕ ТОЧКИ РАЗВОРОТА Для работы таких моделей требуются два дополнительных набора фактов, идентичных фактам для обращенного во времени Медленного %К во. всем, кроме целевого параметра. Цель первого набора равна 1, что обозначает нижнюю точку разворота (минимум), когда завтрашняя цена открытия ниже цен трех предыдущих и десяти последующих дней. Если это условие не выполняется, то значение цели приравнивается к 0. Целью второго набора является 1, т.е. максимум, являющийся точкой разворота в случае, если завтрашняя цена открытия выше цен трех предыдущих и десяти последующих дней. Если это условие не выполняется, то значение цели приравнивается к 0. Если считать, что на рынке присутствуют устойчивые модели, то нейронная сеть должна иметь способность усваивать их и предсказывать положение завтрашней цены открытия. В отличие от набора фактов для обращенного во времени Медленного %К в этих наборах факты генерируются только в тех случаях, когда завтрашняя цена открытия имеет вероятность стать точкой разворота. Например, если завтрашняя цена открытия выше сегодняшней цены открытия, то, согласно предыдущим правилам, завтрашнее открытие уже не может считаться точкой разворота, что бы ни случилось в дальнейшем. Зачем заставлять сеть делать прогнозы, когда нет никакой неопределенности? Прогнозирование производится только в случаях, когда завтрашняя цена открытия может составить точку разворота, и факты генерируются только для таких случаев. Обработка вводов, использование статистики и другие аспекты методологии тестирования для моделей, основанных на точке разворота, идентичны используемым для модели на обращенном во времени Медленном %К. Обе модели в принципе идентичны, различаются только цели предсказания и, следовательно, цели для обучения нейронных сетей. Кроме того, ввиду отличия прогнозов различаются правила получения сигналов входа на их основе. Выходы обученных сетей представляют вероятности (от 0 до 1) присутствия максимума или минимума. Два набора правил для двух моделей генерации сигналов входа таковы: для первой модели — если прогноз ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК минимума выше некоего порога, следует покупать;

для второй модели — если прогноз максимума выше некоторого порога, следует продавать. Для обеих моделей порог представляет собой доверительный уровень для заключения о будущем максимуме или минимуме рынка, которое делает нейронная сеть перед отдачей приказа.

// запись фактов в файл for(cb = 1;

cb <= nb;

cb++) { if(dt[cb] < IS_DATE) continue;

if(dt [cb+10] > OOS_DATE) break;

// период анализа // игнорируем данные вне пределов // выборки пропускаем эти факты номер факта if(opn[cb+l] >= Lowest (opn, 3, cb)} continue;

// fprintf(fil, "%6d", ++factcount);

// PrepareNeurallnputs{var, els, cb) ;

for(k = 1;

k <= 18;

k++) fprintf(fil, "%7.3f", var[k] );

// if(opn[cb+l] < Lowest {opn, 9, cb+10)) netout = 1.0;

else netout =0.0;

// fprintf(fil, "%6.1f\n", netout);

// цель if{(cb % 500) == 1) printf("CB = %d\n", cb);

// стандартные входные данные считаем цель информация о прогрессе } // генерируем входные сигналы, цены лимитных приказов и стоп-приказов signal=0;

if(opn[cb+1] < Lowest (opn, 3, cb)) { // пускаем только эти PrepareNeurallnputs(var, cls, cb) ;

// обрабатываем данные ntlset_inputv{nnet, &var[l]);

// передаем в сеть входные данные ntlfire (nnet);

// запускаем тест netout = ntlget_output(nnet, 0);

// получаем выходные данные netout *= 100.О;

// переводим в проценты if(netout > thresh) signal = 1;

// сигнал на покупку } limprice = 0.5 * (hi[cb] + lo [cb]);

stpprice = cls [cb] + 0. 5 * signal * exitatr[cb] ;

Поскольку код для модели, прогнозирующей минимумы, почти идентичен коду модели на основе обращенного во времени Медленного %К, выше приведены только два измененных блока. В первом блоке обращенный Медленный %К не используется, а вместо этого рассчитывается цель — серия нулей или единиц, указывающая на наличие (1) или отсутствие (0) минимумов. При записи фактов вместо значения Медленного %К записываются значения цели. Во втором блоке вводятся правила для сравнения выхода нейронной сети с соответствующим порогом и генерации собственно сигналов входа в рынок. В обоих блоках включен код, препятствующий записи фактов и использованию прогнозирования в случае, когда завтрашняя цена открытия не может образовать минимум согласно правилам. В коде ниже приведены аналогичные правила прогнозирования максимумов.

ГЛАВА НЕЙРОННЫЕ СЕТИ if(dt[cb+10] > OOS_DATE) break;

if(opn[cb+l] <= Highest(opn, 3, cb)) continue;

fprintf{fil, "%6d", ++factcount);

PrepareNeurallnputs(var, cls, cb) ;

for (k = 1;

k <= 18;

k++) fprintf(fil, "%7.3f", var[k]);

if{opn[cb+l] > Highest(opn, 9, cb+10)) netout = 1.0;

else netout =0.0;

fprintf(fil, "%6.1f\n", netout);

if({cb % 500) == 1) printf("CB = %d\n", cb);

/ / игнорируем данные вне пределов // выборки // пропускаем эти факты // номер факта // стандартные входные значения // считаем цель // цель // информация о прогрессе } // генерируем входные сигналы, цены лимитных приказов и стоп- приказов signal=0;

if(opn[cb+l] > Highest(opn, 3, cb)) { // запускаем только эти PrepareNeurallnputs{var, cls, cb) ;

// обрабатываем данные ntlset_inputv(nnet, &var[l]);

// передаем в сеть входные значения ntlfire (nnet);

// запускаем сеть netout = ntlget_output(nnet, 0);

// получаем выходные значения netout *= 100.О;

// переводим в проценты if(netout > thresh) signal = -1;

// сигнал на продажу } limprice = 0.5 * (hi[cb] + lo[cb]);

stpprice = cls[cb] + 0.5 * signal * exitatr[cb];

Методология тестирования модели, основанной на точке разворота Методология идентична использованной для модели на обращенном во времени Медленном %К. Набор фактов генерируется, загружается в N-TRAIN, масштабируется и перетасовывается. Набор сетей по 3 — 4 слоя нейронов обучается до максимальной сходимости и «полируется». Рассчитываются статистические показатели, такие как скорректированная на избыточную подгонку корреляция. Результаты тестирования моделей, основанных на точке разворота Прогнозирование минимумов. Структура табл. 11-2 идентична табл. 11-1. Как и в случае с нейронной сетью, обучавшейся прогнозированию обращенного во времени Медленного %К, между числом связей в сети и множественной корреляцией выхода с целью наблюдалось растущая связь;

т.е. корреляция была выше для более крупных сетей. Сеть, в общем, обучалась на наборе из 23 900 фактов, что меньше, чем сеть для прогноза обращенного Медленного %К. Различие в количестве фактов объясняется тем, что использовались только случаи, где завтрашняя цена открытия могла представлять точку разворота. Поскольку факты для прогнозирования минимумов ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 11—2.

Название 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 23900 Число связей Корреляция Корреляция после коррекции 0,094 0,050 0,025 0,049 0,064 -0,019 -0,060 0,057 0, 76 114 152 190 228 304 380 312 0,109 0,121 0,146 0,166 0,167 0, 0, 0,100 0,122 0,141 0,137 0,148 0,188 0, 0,260 0, 0,294 Подразумевалось 0, Таблица 11—3.

Название 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 25919 Число связей Корреляция Корреляция после коррекции 0,088 0,097 0,035 -0, 76 114 152 190 228 304 380 312 0,103 0,117 0,138 0,158 0,166 0,197 0, 0,229 0,274 Подразумевалось 0,116 0,133 0,138 0,166 0, 0,202 0,240 0, 0,037 -0,029 0, 0,015 0,119 0, ГЛАВА НЕЙРОННЫЕ СЕТИ отстояли дальше друг от друга, резонно заключить, что избыточность в этой выборке будет ниже. При коррекции использовались следующие эффективные размеры выборок: 23 919 фактов (исходная) и 8000 (эффективная выборка со сниженным количеством фактов). После коррекции наилучшие результаты были показаны самой большой из двух 4-слойных сетей, вторая 4-слойная сеть также была весьма результативной. Кроме этих двух сетей 3-слойная сеть с 10 нейронами среднего слоя также показала хорошие результаты. Для тестирования торговой эффективности была выбрана большая сеть из 4 слоев (nn9.net) и маленькая сеть из трех слоев (nn4.net). Прогнозирование максимумов. В табл. 11-3 приводятся показатели различных нейронных сетей, обученных на наборе из 25 919 фактов. Показатели и здесь были напрямую связаны с размером сети — большее количество связей приводило к лучшему результату. После умеренной коррекции коэффициентов корреляции только малая 4-слойная сеть не подчинилась этой закономерности, показав большую, чем ожидалось, корреляцию. При более сильной коррекции (в расчете на высокую степень излишней подгонки под исходные данные) выделялись только две 4-слойные сети, причем наибольшая сеть (nn9.net) показала самую высокую корреляцию. Одна из 3-слойных сетей (nn4.net) также показала достаточно высокий результат и была отобрана для проведения собственно теста.

РЕЗУЛЬТАТЫ ТОРГОВЛИ ДЛЯ ВСЕХ МОДЕЛЕЙ В табл. 11-4 приведены лучшие показатели, полученные для данных, находящихся в пределах выборки, а также эффективность портфеля на данных в пределах и вне пределов выборки. Приведены показатели для всех комбинаций приказов, сетей и моделей. В таблице: ВЫБ — вид выборки данных (В — в пределах, ВНЕ — вне пределов выборки);

ДОХ% — доходность в процентах годовых;

Р/ПРИБ — соотношение риска/прибыли в годовом исчислении;

ВЕР — ассоциированная вероятность статистической достоверности;

СДЕЛ — число сделок на всех рынках в составе портфеля;

ПРИБ% — процент прибыльных сделок;

$СДЕЛ — средняя прибыль/ убыток со сделки;

ДНИ — средняя длительность сделки в днях;

ПРИБДЛ — общая прибыль от длинных позиций в тысячах долларов;

ПРИБКР— общая прибыль от коротких позиций в тысячах долларов. Столбцы PI, P2, РЗ представляют значения параметров: Р1 — пороговое значение, Р2 — номер нейронной сети (согласно табл. 11-1 — 11-3), РЗ— не использовался. Во всех случаях приведены те пороговые значения Р1, которые обеспечивали максимальную эффективность в пределах выборки. Вне пределов выборки были использованы те же значения. Порог для обращенного во времени Медленного %К оптимизировался для каждого вида приказов с помощью прогонки параметра Р1 от 50 до ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 11—4.

Эффективность портфеля с лучшими параметрами по данным выборки для каждого из тестов в пределах и вне пределов выборки ГЛАВА НЕЙРОННЫЕ СЕТИ Таблица 11—4.

Эффективность портфеля с лучшими параметрами по данным выборки для каждого из тестов в пределах и вне пределов выборки (продолжение) 90 с шагом 1. Для моделей прогнозирования разворотных точек пороговые значения прогонялись от 20 до 80 с шагом 2. В обоих случаях оптимизация проводилась только в пределах выборки, и лучшие параметры затем использовались и в пределах, и вне пределов выборки во время тестирования, как и в других главах этой книги. Результаты торговли для модели, основанной на обращенном Медленном %К Две выбранные нейронные сети с максимальной вероятностью устойчивой работы вне пределов выборки (согласно их скорректированным корреляциям) были исследованы в отношении их торговой эффективности. Первая сеть была 3-слойной (18-6-1 нейронов), вторая 4-слойной (18-14-4-1 нейронов).

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Результаты для сети 18-6-1. В пределах выборки, как и ожидалось, результаты были великолепными. Средняя сделка приносила более $6000 прибыли при всех видах входов, годовая прибыль составляла от 192,9% (вход по цене открытия, тест 1) до 134,6% (вход по стоп-приказу, тест 3). Такие результаты были получены на основе подгонки под данные сложной модели из 114 свободных параметров. Стоит ли за этим что-то, кроме излишней подгонки? Видимо, да. При использовании входа по стоп-приказу вне пределов выборки удалось получить некоторую прибыль — средняя сделка принесла $362. Хотя вне пределов выборки другие виды входов были убыточными, эти убытки были меньше, чем наблюдавшиеся при тестировании других систем в предыдущих главах: при входе по цене открытия убытки составляли только $233 в сделке, а при входе по лимитному приказу (тест 2) — $331. Как это случалось и с другими моделями, вход по стоп-приказу работал лучше,чем вход по лимитному приказу. Вне пределов выборки система была прибыльна со всеми видами входов при торговле только длинными позициями. Короткие позиции были убыточны со всеми видами входов. Эффективность системы в пределах выборки была потрясающей для всех видов входов и на всех рынках с несколькими исключениями. Наихудшей была эффективность на рынке евродоллара, видимо, ввиду свойственных этому рынку высоких транзакционных расходов. Слабо работала система на рынках серебра, соевого масла, казначейских облигаций и векселей, канадского доллара, британского фунта, золота и какао. Видимо, особенности этих рынков затрудняют нейросети, поскольку остальные рынки были высокоприбыльными. Многие из этих рынков также работали плохо с другими моделями. Вне пределов выборки торговля была успешной для всех видов приказов на рынках казначейских облигаций (неприбыльных в пределах выборки), немецкой марки, швейцарского франка, иены, неэтилированного бензина, золота (также неприбыльного в пределах выборки), палладия и кофе. Многие другие рынки также были прибыльны с двумя или тремя видами входов. При использовании входа по стоп-приказу (наилучшего в целом) значительную прибыль приносили даже рынки S&P 500 и NYFE, а также живого скота, соевых бобов, соевой муки и овса. На рис. 11-1 изображен график изменения капитала для модели на основе прогнозирования обращенного во времени Медленного %К с входом по стоп-приказу. Как видно, капитал увеличивается в пределах выборки и в течение половины периода вне выборки, после чего начинается медленное снижение. Результаты для сети 18-14-4-1. Эта сеть в пределах выборки работала значительно лучше, чем вне ее пределов. В пределах выборки прибыль варьировалась от 328,9% в год (при входе по стоп-приказу, тест 6) до 534,7% (вход по цене открытия, тест 4). Во всех случаях средняя Прибыль в сделке Рисунок 11-1.

График изменения капитала для модели, основанной на обращенном во времени Медленном %К, нейронная сеть 18-6-1, вход по стоп-приказу.

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК превышала $6000. Как обычно, длинные позиции были прибыльнее коротких. Вне пределов выборки все виды входов были убыточны, но, как и в предыдущем наборе тестов, эти убытки были меньше, чем характерные для торговых систем, описанных в других главах, т.е. ближе к $1000, чем к $2000. Эта сеть также проводила гораздо больше сделок, чем предыдущая, причем лучше всего работал вход по лимитному приказу (тест 5). Убытки длинных позиций были меньше, чем коротких, за исключением входа по стоп-приказу, где убыток коротких позиций был сравнительно небольшим. Повышенная эффективность в пределах выборки и резкое падение эффективности за ее пределами — четкий признак избыточной подгонки под данные, которой достигла большая сеть с 320 параметрами, подстроившись под особенности учебного набора данных, но потеряв эффективность вне выборки. В пределах выборки практически все рынки были прибыльны со всеми видами входов за тремя исключениями: серебро, канадский доллар и какао. Эти рынки в целом трудно поддаются любой системе. Вне пределов выборки система была прибыльна со всеми видами входов на ряде рынков: немецкой марки, канадского доллара, сырой нефти, мазута, палладия, откормленного скота, живого скота и леса. По крайней мере с одним из видов входов работали прибыльно еще несколько рынков. График изменения капитала показывал постоянный рост вплоть до конца периода выборки, откуда начиналось плавное снижение, что характерно для поведения переоптимизированной системы. Для выборки из 88 092 фактов такая нейронная сеть, возможно, была слишком большой. Результаты торговли для модели, основанной на нижней точке разворота Две выбранные нейронные сети с максимальной вероятностью устойчивой работы вне пределов выборки (согласно их скорректированным корреляциям) были исследованы в отношении их торговой эффективности. Ниже рассмотрена эффективность большей (18-20-6-1) и меньшей из них (18-10-1). Результаты для сети 18-10-1. В пределах выборки эта сеть работала чрезвычайно прибыльно, что при такой степени подгонки неудивительно. Вне пределов выборки и эта система относилась к числу сильно убыточных. Для всех трех видов входов (по цене открытия, по лимитному приказу и по стоп-приказу — тесты 7, 8 и 9 соответственно) средний убыток в сделке составил около $2000, что типично для многих рассмотренных ранее убыточных моделей. Убытки были тем более примечательны, что модель вела торговлю только длинными позициями, обычно более выгодными, чем короткие.

ГЛАВА НЕЙРОННЫЕ СЕТИ В пределах выборки только четыре рынка не были высокоприбыльными: британский фунт, серебро, живой скот и кукуруза. Рынок серебра, как известно, вызывал проблемы у всех испытанных моделей. Вне пределов выборки сеть приносила прибыль при всех видах входов на рынках S&P 500, иены, сырой нефти, неэтилированного бензина, палладия, соевых бобов и соевого масла. По крайней мере с одним из видов входов работали прибыльно еще несколько рынков. График изменения капитала показывал постоянный рост вплоть до конца периода выборки, откуда начиналось постоянное снижение. Результаты для сети 18-20-6-1. Эти данные получены в тестах 10, 11 и 12 (вход по цене открытия, по лимитному приказу и стоп-приказу соответственно). Эффективность этой сети в пределах выборки взлетела до невероятного уровня. При входе по цене открытия годовая прибыль составила 768%, причем 83% из 699 сделок были прибыльны. Средняя прибыль в сделке составила $18 588. Как ни странно, при большем размере этой сети и, следовательно, большей возможности подгонки под данные ее эффективность вне пределов выборки по показателю средней прибыли в сделке превосходила меньшую по размерам сеть, особенно в случае входа по стоп-приказу, где убыток составил всего $518. Все рынки в пределах выборки без исключения были прибыльными с использованием любых входов. Вне пределов выборки со всеми видами входов прибыльными были рынки S&P 500, британского фунта, платины, палладия, соевой муки, пшеницы, канзасской пшеницы, миннесотской пшеницы и леса. Результаты торговли для модели, основанной на верхней точке разворота Две выбранные нейронные сети с максимальной вероятностью устойчивой работы вне пределов выборки (согласно их скорректированным корреляциям) были исследованы в отношении их торговой эффективности. Ниже рассмотрена эффективность большей (18-20-6-1) и меньшей из них (18-10-1). Результаты для сети 18-10-1. Как обычно, в пределах выборки эта сеть была чрезвычайно прибыльной. Вне пределов выборки прибыль была получена с использованием двух видов входных приказов — по цене открытия (тест 13) и по лимитному приказу (тест 14). При использовании входа по стоп-приказу (тест 15) были получены умеренные убытки. Это неожиданно, учитывая то, что короткие позиции обычно бывали менее прибыльными, чем длинные. Разбор отдельных рынков показывает, что в пределах выборки только рынки канадского доллара, откормленного скота, соевого масла, пше ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК ницы и какао не были прибыльны со всеми тремя видами входов. Вне пределов выборки при использовании всех трех входов значительные прибыли были получены на рынках немецкой марки, иены, сырой нефти, мазута, откормленного скота, живого скота и кукурузы. Прибыльность рынков иены, сырой нефти и до некоторой степени кукурузы соответствовала хорошей работе на этих рынках модели нижней точки разворота. Вне пределов выборки эти рынки работали прибыльно с обеими моделями точек разворота (нижней и верхней). График изменения капитала (рис. 11-2 для входа по цене открытия) показывает резкий рост капитала до августа 1993 г., а затем более медленный подъем в течение всего остального периода выборки и двух третей периода вне выборки. После этого начинается плавное снижение. Результаты для сети 18-20-6-1. Как и ожидалось, эта сеть, наибольшая из двух выбранных, показала самую высокую эффективность в пределах выборки. Вне пределов выборки эта сеть работала со всеми видами входов отвратительно (тесты 16, 17и 18 — вход по цене открытия, по лимитному приказу и стоп-приказу соответственно). Наименее убыточные результаты были получены при использовании входа по стоп-приказу. В пределах выборки только рынки серебра, пшеницы, сахара и апельсинового сока не приносили прибыли со всеми тремя видами входов. Вне пределов выборки только рынок какао был прибылен со всеми тремя входами. Как ни странно, все рынки металлов показывали высокие прибыли при входе по цене открытия и по лимитному приказу вне пределов выборки, равно как и рынки откормленного скота, какао и хлопка. Анализ капитала портфеля показывает невероятно гладкую и устойчивую прибыль в пределах выборки и убытки вне пределов выборки для всех видов входов.

ОБЗОР РЕЗУЛЬТАТОВ В табл. 11-5 и 11-6 приведены результаты работы всех моделей, основанных на нейронных сетях на различных рынках. В первом столбце указано обозначение рынка, средний и правый столбцы содержат количество выгодных тестов для данного рынка. Цифры в первой строке указывают на номер теста. Последняя строка показывает, на скольких рынках данная модель была выгодной. Степень прибыльности и убыточности рынков для каждой модели указана следующим образом: один минус ( — ) означает убыток в $2000 — 4000, два минуса ( ) — убыток более $4000;

один плюс (+) означает прибыль от $1000 до $2000, два плюса (+ +) — прибыль более $2000;

пустая ячейка означает прибыль до $1000 или убыток не более $1999 со сделки. (Названия рынков и их символы соответствуют обозначениям табл. II-1;

часть II, введение.) В пределах выборки все виды входов Рисунок 11-2.

График изменения капитала для модели, основанной на обращенном Медленном %К, нейронная сеть 18-10-1, вход по цене открытия.

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 11—5.

Эффективность в пределах выборки по тестам и рынкам ГЛАВА НЕЙРОННЫЕ СЕТИ Таблица 11—6.

Эффективность вне пределов выборки по тестам и рынкам ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 11—7.

Эффективность нейронных сетей, распределенная по модели, виду приказа и выборке В пределах выборки По открытию По По лимитному стопприказу приказу Модель Вне пределов выборки Среднее По По По В Вне открытию лимитному стоппределах пределов приказу приказу Медленный обращенный %К, сеть 18-6- ДОХ% $СДЕЛ 129, 181, 153, -2,9 - -2,9 - 2,7 176,2 -1,0 - ДОХ% Медленный обращенный %К, сеть 18-14-4-1 534,7 547,4 7080 8203 $СДЕЛ 328,9 -17,7 - -17,4 - -16,2 - 470, -17, - Точка разворота, длинные сделки, сеть 18-10-1 ДОХ% 311.1 308,4 9316 9373 $СДЕЛ 236,8 -16, - -16, - -11, - 285,4 -14,6 - ДОХ% Точка разворота, длинные сделки, сеть 18-20-6-1 768,0 742,0 468,8 18588 18569 16392 $СДЕЛ -13,4 - -12,7 - -1,8 - 659, -9, - Точка разворота, короткие сделки, сеть 18-10-1 ДОХ% 206,8 209,0 $СДЕЛ 8448 175,4 12,1 8,0 -6,2 - 197,1 4,6 - Точка разворота, короткие сделки, сеть 18-20-6-1 ДОХ% 601,9 603,8 387,3 18550 18905 6320 $СДЕЛ Среднее -19, - -19, - -22, - 531, -20, - ДОХ% $СДЕЛ 435, 432, 291, -9,7 - -10,1 - -9,2 - 386, -9, - со всеми моделями давали огромные прибыли (табл. 11-7). При усреднении по всем моделям лучше всего работали входы по цене открытия и по лимитному приказу, а хуже всего вход по стоп-приказу, но разница была очень небольшой. В пределах выборки наибольшая средняя прибыль в сделке отмечена для больших сетей на принципе максимальной и минимальной точек разворота. Вне пределов выборки лучше всего работал вход по стоп-приказу. В общем, лучше всего при усреднении по входам работали модель на обращенном во времени Медленном %К и модель на верхней точке разворота.

ГЛАВА НЕЙРОННЫЕ СЕТИ ЗАКЛЮЧЕНИЕ При первой попытке применить для анализа индивидуальных рынков нейронную сеть (Katz, McCormick, ноябрь 1996) мы пришли к выводу о полной бесполезности такого подхода. Поведение некоторых из проведенных сейчас тестов вне пределов выборки немного обнадеживает по сравнению с нашим опытом исследования простых нейронных сетей. Эти результаты, почти несомненно, обусловлены большим количеством точек данных в обучающем наборе, включающем все рынки в составе портфеля, а не какой-либо один рынок. В общем, чем больше выборка, используемая для обучения (или оптимизации), тем больше вероятность сохранения положительной эффективности вне ее пределов. Увеличить размер выборки можно, используя более старые данные, что вполне возможно для ряда включенных в наше исследование рынков. Кроме того, можно ввести в портфель дополнительные рынки, что, возможно, представляет собой оптимальный способ улучшения обучающего набора. Принцип оптимизации состоит в том, что вероятность устойчивых результатов повышается со снижением количества параметров модели. Учитывая в чем-то положительные результаты некоторых из тестов, возможно, имеет смысл продолжать исследования с более усложненными моделями. Как вариант можно было бы улучшить предварительную обработку данных в смысле уменьшения общего числа вводов без потери важной прогностической информации — это может сделать систему очень прибыльной. При меньшем количестве вводов в сети будет меньше связей для оценки, следовательно, подгонка под кривую — важная проблема, судя по результатам и уровням усадки, — будет представлять меньшую угрозу.

ЧТО МЫ УЗНАЛИ?

При выполнении некоторых условий нейронные сети могут использоваться в системной торговле. Критическим моментом для избежания вредной подгонки под исторические данные (в противоположность полезной оптимизации) является достижение адекватного соотношения размера выборки данных и количества свободных параметров сети. • Подгонка под исторические данные является значительной проблемой при использовании нейронных сетей. Следует обращать внимание на любой метод, способный уменьшить общее количество свободных параметров без потери важной информации, например тщательную предварительную обработку и сжатие информации. Для обучения нейронных сетей необходимо использовать выборки большого размера. Поэтому обучение на целом порт ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК феле финансовых инструментов приводит к лучшим результатам, чем обучение на отдельных рынках, несмотря на потерю рыночной специфики. Один из возможных подходов — расширять количество рынков в портфеле и, по возможности, объем обучающей выборки данных. Доведя это до предела, возможно, имеет смысл обучать сеть на сотнях рынков разнообразных товаров, валют и ценных бумаг в попытке создать «универсальную систему прогнозирования цен». Если в таком всемирном пространстве рынков существуют прогностически полезные модели, то такая попытка, вероятно, действительно будет оправданной. Некоторые из рынков работают плохо даже в пределах выборки, другие удерживают прибыльность вне ее пределов, как это случалось с некоторыми моделями в предшествующих главах. Одни рынки, следовательно, больше подходят для применения определенных методов, чем другие. Поиск подходящих рынков на основе эффективности вне пределов выборки может стать полезным подходом при разработке и использовании торговых систем на основе нейронных сетей.

ГЛАВА Генетические алгоритмы Основываясь на моделях, используемых в биологии и экономике, математик и психолог Джон Холланд (John Holland) разработал алгоритм генетической оптимизации. Алгоритм впервые был опубликован в книге Холланда «Адаптация в естественных и искусственных системах» (J. Holland, Adaptation in Natural and Artificial Systems, 1975). Генетические алгоритмы (ГА) впервые стали применяться в компьютерных дисциплинах в начале 1990-х годов (Yuret and de la Maza, 1994). Торговое сообщество впервые обратило на них внимание около 1993г., когда появилось несколько статей (Burke, 1993;

Katz and McCormick, 1994;

Oliver, 1994) и компьютерных программ. С тех пор несколько фирм добавили генетическое обучение в свои программные пакеты, а у некоторых есть даже программы генетической оптимизации профессионального уровня. В торговом обществе ГА никогда не пользовались таким успехом, как нейронные сети. Популярность этой технологии никогда не росла из-за самой ее природы. Среднему человеку трудно понять генетический алгоритм и более чем сложно применять его правильно. Однако, по нашему мнению, ГА могут быть крайне выгодны для проектировщиков торговых систем. В данной книге представлен общий обзор ГА и их применения в торговле. Читателям, заинтересованным в детальном изучении этого предмета, следует прочитать книгу Девиса (Davis, 1991), а также нашу главу в книге «Virtual Trading» (Katz, McCormick, 1995a, 1995b) и наши статьи (Katz, McCormick, июль/август 1994, декабрь 1996, январь 1997, февраль 1997).

ЧТО ТАКОЕ ГЕНЕТИЧЕСКИЕ АЛГОРИТМЫ? Генетический алгоритм решает проблему, используя процесс, подобный биологическому развитию. Он работает как рекомбинация и мутация генетических последовательностей. Рекомбинация и мутация — генетические операторы, т.е. они управляют генами. Ген — это последовательность кодов (генотипов), которая содержит всю информацию, необходимую для ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК того, чтобы создать функциональный организм с определенными характеристиками (генотипом). Хромосома — последовательность генов. В случае генетической оптимизации, используемой для решения задач, связанных с торговлей, последовательность кодов обычно принимает форму ряда чисел. При моделировании эволюционного процесса ГА участвует в отборе и сопряжении членов из популяции (хромосом). Сопряжение — это процесс, содержащий скрещивание и мутацию. При скрещивании элементы, которые включают гены различных хромосом (члены популяции или решения), комбинируются, чтобы создавать новые хромосомы. Мутацией называют возникновение случайных изменений в этих элементах. Это обеспечивает дополнительное изменение в наборах создаваемых хромосом. Как и в процессе биологического отбора (где менее пригодные члены популяции оставляют меньше потомства), менее пригодные решения удаляются. При этом более пригодные решения размножаются, создавая другое поколение решений, которое может содержать несколько лучшие решения, чем предыдущие. Процесс рекомбинации, случайной мутации и отбора является чрезвычайно мощным механизмом решения задач. РАЗВИТИЕ МОДЕЛЕЙ ВХОДА, ОСНОВАННЫХ НА ПРАВИЛАХ Что бы произошло, если ГА позволяли искать не просто лучшие параметры (именно так чаще всего используют ГА), но и лучшие правила? В этой главе приводится результат использования ГА для развития законченной модели входа путем поиска оптимальных правил и параметров для этих правил. Несмотря на сложность, эта методология оказалась эффективной в нашем первом исследовании (Katz, McCormick, февраль 1997). Как можно использовать ГА для поиска наилучших торговых правил? Доморощенный ГА просто жонглирует числами. Необходимо найти способ нумерации различных наборов правил. Этого можно достичь многими способами. Простой и эффективный метод включает в себя построение набора шаблонов правил. Шаблон правила — это частичное описание правила с оставленными пробелами, которые необходимо заполнить. Например, если некоторые из правил предыдущих глав рассмотреть как шаблоны правил, то пробелами будут значения периодов усреднения, порогов и других параметров. Шаблоны правил, определенные таким образом, несложно пронумеровать, поставив в соответствие каждому шаблону набор чисел. Первое число в наборе используется как индекс в таблице шаблонов правил. Оставшиеся числа набора используются для заполнения пробелов в шаблоне, в результате чего мы получаем четко определенное правило. Приведенный ниже компьютерный код содержит функцию C++ (Rules), которая производит нумерацию шаблонов;

она будет описана позже. Хотя в данном исследовании ис ГЛАВА ГЕНЕТИЧЕСКИЕ АЛГОРИТМЫ пользовался язык C++, данный метод также можно реализовать в TradeStation с помощью программы TS-EVOLVE, созданной Scientific Consultant Services (516-696-3333). Термин генетический поиск означает использование ГА для поиска самых лучших решений, т.е. имеющих максимальную функцию пригодности. Как правило, набор потенциальных решений, в котором ведется поиск, достигает огромных размеров. В данном приложении мы хотим использовать эволюционный процесс, чтобы выявить набор чисел (генотипов), которые соответствуют основанным на правилах моделям входов (фенотипам) с максимальной функцией пригодности (или торговой эффективности). Иными словами, мы собираемся заняться селективным выращиванием методов входа, основанных на правилах! Вместо того чтобы начинать с конкретного принципа, на котором основывается модель (сезонность, пробой), в данном случае для начала возьмем набор идей, которые могут способствовать созданию выгодного метода входа. Вместо того чтобы последовательно проверять ценность этих подходов, будет сделано нечто необычное: генетическому процессу эволюции представится возможность создать наилучшую модель входа из набора необработанных идей. ГА будут искать в чрезвычайно большом множестве решений наилучшую модель входа, которая может быть получена для определенных данных и шаблонов правил. Количество правил для каждой модели будет ограничено во избежание подгонки под исторические данные. Данная задача сводится к поиску оптимальных наборов чисел. Без использования ГА такой массированный поиск решений был бы практически невозможен и неразумен в любом смысле. Конечно, вместо ГА всегда можно осуществить лобовую оптимизацию — особенно, если вы располагаете несколькими тысячелетиями на проведение этой работы. В качестве другой альтернативы можно воспользоваться эмпирическим поиском оптимальных правил, т.е. попытаться найти наилучшие правила с помощью наблюдений, однако этот подход не обязательно позволит максимизировать такую сложную функцию, как соотношение риск/прибыль. ГА обеспечивают эффективный способ выполнения очень больших поисков, особенно когда нет простых эвристических методов решения данной задачи.

ЭВОЛЮЦИОННЫЙ ПОИСК МОДЕЛИ ВХОДА В данном примере популяция моделей входа с тремя правилами была получена с помощью генетического оптимизатора OptEvolve, написанного на С ++ (Scientific Consultants Services, 516-696-3333). Каждый ген соответствует блоку из четырех чисел и шаблону правила — таким образом создается соответствие наборов чисел и наборов правил. Каждая хромосома содержит три гена и состоит из 12 чисел: первые четыре числа соответствуют первому гену (или правилу), следующие четыре соответствуют второ ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК му гену (или правилу), а последние четыре соответствуют третьему гену (или правилу). ГА должен знать размер гена, чтобы не разрушить важные гены при выполнении скрещивания. Скрещивание должно произойти только на границах генов (блоков из четырех чисел). В настоящем примере это будет достигнуто путем приравнивания размера гена, который является параметром генетического оптимизатора, к четырем. Как упомянуто, каждый ген составлен из четырех чисел. Первое число является индексом в таблице возможных шаблонов правил. Например, если это число 1, то выбирается шаблон сравнения цен, в котором различие между двумя ценами закрытия сравнивается с некоторым порогом (см. код). Остальные три числа в гене соответствуют значению порога и двум анализируемым периодам для сравниваемых цен. Если первое число из блока 4 чисел равно 2, то будет выбран шаблон сравнения цены и скользящего среднего. В этом случае два из оставшихся трех чисел контролировали бы период скользящего среднего и направление сравнения (должна ли цена быть выше или ниже скользящего среднего). Вообще, если первое число в блоке из четырех чисел равно n, тогда используется шаблон для правила n, а любые требуемые параметры определены оставшимися тремя числами в блоке из четырех чисел. Эта схема кодирования облегчает поддержание расширяемой базы данных для шаблонов правил. Каждый из трех блоков четырех чисел связан с соответствующим правилом. Модель входа, состоящая из трех правил, соответствует любой хромосоме, состоящей из 12 чисел. Шаблоны правил Первый шаблон правила (case l в функции Rules) определяет сравнение между двумя ценами и порогом: правило принимает значение ИСТИНА (TRUE), если цена закрытия 1b1 дней назад больше, чем некоторый пороговый фактор (thr) плюс цена закрытия 1b2 дней назад. В остальных случаях правило принимает значение ЛОЖЬ (FALSE). Неизвестные (1b1, 1b2 и thr) оставлены пустыми для будущего использования при реализации программы. Этот шаблон был включен, потому что тот вид правил, которые он представляет, был полезен в предыдущих исследованиях. Второй шаблон правила (case 2) включает простые скользящие средние, которые часто используются для определения тренда. Обычно считается, что рынок будет двигаться вверх, если цена выше ее скользящего среднего, и опускаться вниз, если цена ниже ее скользящего среднего. В шаблоне присутствуют только два неизвестных: первый (per) контролирует число дней в скользящем среднем и второй (v4) контролирует направление сравнения (выше или ниже). Третий шаблон правила (case 3) идентичен второму (case 2), за исключением того, что вместо простого скользящего среднего используется экспоненциальное.

ГЛАВА ГЕНЕТИЧЕСКИЕ АЛГОРИТМЫ Было много рассуждений относительно важности данных по суммарной величине открытых позиций на рынке (открытому интересу). Лэрри Виллиамс (Larry Williams, 1979) упомянул, что снижение открытого интереса в течение периодов застоя цен указывает на потенциал для сильного подъема. Сокращение открытого интереса может быть интерпретировано как снижение количества обращающихся на рынке контрактов, создавая условия, когда спрос на контракты может перевесить предложение. Четвертый шаблон правила (case 4) просто вычисляет процентное снижение открытого интереса за период от 1Ь1 дней назад до 1 дня назад (открытый интерес, как правило, не публикуется для текущего дня) и сравнивает эту величину с порогом (thr). Если снижение больше, чем порог, то правило принимает значение ИСТИНА. В остальных случаях оно принимает значение ЛОЖЬ. Порог и период (1b1) — неизвестные, которые будут использованы при реализации программы. Пятый шаблон правила (case 5) подобен четвертому шаблону, но рассчитывает повышение, а не падение открытого интереса. Если происходит увеличение, большее чем пороговое значение, то правило возвращает значение ИСТИНА. Другие ситуации соответствуют значению ЛОЖЬ. Шестой шаблон правила (case 6) может называться условием «нового максимума». Шаблон запрашивает, отмечен ли 1b1-дневный новый максимум за период последних 1b2 дней. К примеру, правило может звучать так: «Если достигнут новый 50-дневный максимум в пределах последних 10 дней, то правило принимает значение ИСТИНА, в других случаях — ЛОЖЬ». Это правило пытается найти простое условие пробоя, учитывая пробои, которые произошли несколько дней назад (возможно, сопровождаемые откатами к предыдущим уровням сопротивления, ставшими уровнями поддержки, что расценивается другим правилом как хорошая точка входа). В данном правиле есть два пробела, которые необходимо будет заполнить при проведении расчетов: 1b1 и 1b2. Седьмой шаблон правила (case 7) идентичен шестому, за исключением того, что определяются новые минимумы, а не новые максимумы. Восьмой шаблон правила (case 8) исследует индекс среднего направленного движения относительно двух порогов (thr1 и thr2). Этот индикатор является мерой наличия тренда, как обсуждалось в главе, посвященной пробоям. Если среднее направленное движение (ADX) выше нижнего порога и ниже верхнего порога, то правило возвращает значение ИСТИНА. В других случаях правило возвращает значение ЛОЖЬ. Девятый шаблон правила (case 9) выполняет сравнение порогов со значением стохастического осциллятора, аналогично шаблону 8. Десятый шаблон правила (case 10) оценивает направление наклона осциллятора MACD. Длины (1b1 и 1b2) двух скользящих средних, которые составляют MACD, и направление наклона (v4) необходимы для выбора значения ИСТИНА или ЛОЖЬ и определены как параметры.

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК МЕТОДОЛОГИЯ ТЕСТИРОВАНИЯ Ниже приводятся шаги, необходимые для эволюционного создания модели входа, основанной на шаблонах правил, используемых в этом исследовании: 1. Выберите произвольную хромосому с 12 элементами. Она представляет собой потенциальное решение (случайное и, вероятно, не очень хорошее). Поставьте в соответствие каждому параметру правил определенное число, чтобы получить три полностью определенных правила (одно для каждого гена), и определите значение ИСТИНА/ЛОЖЬ для всех дней во временном ряду. Обработайте ценовые данные день за днем. Если в данный день все три правила возвращают значение ИСТИНА и если нет текущей длинной (или короткий) позиции, то модель получает рыночный приказ на покупку (или продажу) при завтрашнем открытии. Если имеется позиция, используйте стандартную стратегию выхода для осуществления выхода. Оцените торговую эффективность потенциального решения. Для этого определите «пригодность решения» как соотношение риск/прибыль в годовом выражении — величина, которая фактически является значением {-критерия. Сообщите генетическому оптимизатору, насколько пригодно (в вышеупомянутом смысле) потенциальное решение (хромосома). Это позволит генетическому оптимизатору обновить популяцию хромосом. Если решение отвечает определенным критериям, то следует сгенерировать сводку эффективности системы и другую информацию и сохранить эти данные в файле для последующего рассмотрения. Повторять вышеупомянутые шаги снова и снова до тех пор, пока не пройдет достаточное число «поколений».

2.

3.

4. 5.

6..

7.

8.

Так как вышеупомянутые шаги повторяются, решения или «поколения», созданные генетическим оптимизатором, в среднем становятся лучше и лучше. Большое количество отдельных эффективных решений появится в течение эволюционного процесса. Большинство решений будет записано в файле, созданном в ходе неоднократного выполнения первых семи вычислительных шагов. Ниже будет рассмотрен код, написанный на C++, который осуществляет вышеупомянутые шаги.

ГЛАВА ГЕНЕТИЧЕСКИЕ АЛГОРИТМЫ Из-за природы правил, вероятно, будет различным поведение моделей при открытии длинных и коротких позиций. В связи с этим модели входа для длинных позиций найдены и проверены отдельно от моделей входа для коротких позиций. Эффективность модели оценивается на всем портфеле. Цель состоит в том, чтобы найти набор правил, которые обеспечивают наилучшую эффективность торговли всем портфелем финансовых инструментов. Процедура, используемая здесь, отличается от наших более ранних исследований (Katz, McCormick, февраль 1997), где поиск оптимальных правил проводился на каждом рынке в отдельности -— подход, в большей степени подверженный эффектам «вредной» подгонки под исторические данные. Напомним вывод, полученный в отношении нескольких моделей, которые были первоначально оптимизированы на индивидуальных инструментах: при использовании одной модели для всех рынков без оптимизации или настройки под отдельный рынок эффективность данной модели может существенно понизиться. В нижеследующих тестах использовалась стандартная платформа C++, стандартные приказы входа и стратегия выхода.

static int EventPresent (int *es, int m, int cb) { // Используется функцией Rules для облегчения кодирования int i ;

for(i=cb-m+l;

i<=cb;

i++) if(es[i]) return TRUE;

return FALSE ;

} static void Rules (float *opn, float *hi, float *lo, float *cls, float *vol, float *oi, float *atr, int nb, int vl, float v2, float v3, float v4, int *ans) { // // // // // // // Процедура определяет шаблоны правил, используемых в генетическом процессе эволюции модели, основанной на правилах. opn, hi, lo, cls — стандартные ценовые данные [l..nb] vol, oi — объем и открытый интерес [l..nb] nb — количество дней vl, v2, v3, v4 — селектор правил и параметры ans — выходные ценовые данные [l..nb] // локальные макрофункции #define LinearScale(х,a,b) ( (х)* ( {b}-(а))/1000.0+(а) ) #define BiasedPosScale(х,а) (0. 000001*(х)*(х)*{а}) #define Compare{a,b,dir) (((dir)> = 0)?((a)>(b) }: (fa)<(b))) // локальные переменные static int lbl, lb2, per, cb, maxlb=100;

static float thr, fac, thr2, thrl, tmp, tiny=l.ОЕ-20;

static int IsNewHigh[MAXBAR+l], IsNewLow[MAXBAR+l];

static float Serl[MAXBAR+1] ;

// шаблоны правил switch(vl} { // выбираем правило case 1: // сравнение изменения цены с порогом ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК lb1 = (int)BiasedPosScale(v2, 5 0. 0 ) ;

lb2 = (int)BiasedPosScale(v3, 5 0. 0 ) ;

fac = LinearScale(v4, - 2. 5, 2. 5 ) * s q r t ( a b s ( l b l - I b 2 ) > ;

for(cb-maxlb;

cb<=nb;

cb++) { thr = fac * atr [cb];

ans[cb] = cls[cb-lbl] - cls[cb-lb2] > thr;

] break;

case 2: // сравнение цены с простым скользящим средним per = 2 + (int)BiasedPosScale(v2, 48.0);

Averages(Serl, cls, per, nb) ;

for(cb=maxlb;

cb<=nb;

cb++) ans[cb] = Compare(cls[cb], Serl[cb], V4-500.0);

break;

case 3: // сравнение цены с экспоненциальным скользящим средним per = 2 + (int)BiasedPosScale(v2, 48.0);

XAverageS(Serl, cls, per, nb) ;

for(cb-maxlb;

cb<=nb;

cb++) ans[cb] = Compare(cls[cb], Serl[cb], V4-500.0);

break;

case 4: // сравнение падения открытого интереса с пороговым значением 1b1 = 2 + (int)BiasedPosScale (v2, 48.0);

thr = LinearScale(v3, 0.01, 0.50);

for{cb=maxlb;

cb<=nb;

cb++) { tmp = (oi[cb-lbl] - oi[cb-l]) / (oi [cb-lbl] + tiny);

ans [cb] = tmp > thr;

] break;

case 5: // сравнение увеличения открытого интереса с пороговым значением 1b1 = 2 + (int) BiasedPosScale(v2, 48.0);

thr = LinearScale(v3, 0.01, 0.99);

for(cb=maxlb;

cb<=nb;

cb++) { tmp = (oi [cb-1] - oi[cb-lblj) / (oi [cb-lbl] + tiny) ;

ans [cb] = tmp > thr;

} break;

case 6: // недавние новые максимумы 1bl = 2 + (int)BiasedPosScale(v2, 48.0);

1b2 = 1 + (int)BiasedPosScale(v3, 8.0);

for(cb=lbl+3;

cb<=nb;

cb++) IsNewHigh[cb] = hi [cb] > Highest(hi, 1b1, cb-1);

for(cb-maxlb;

cb<=nb;

cb++) ans[cb] = EventPresent(IsNewHigh, 1b2, cb) ;

break;

case 7: // недавние новые минимумы 1bl = 2 + (int)BiasedPosScale(v2, 48.0);

1b2 = 1 + (int)BiasedPosScale(v3, 8.0);

for(cb=lbl+3;

cb<=nb;

cb++) IsNewLow[cb] = lo[cb] < Lowest(lo, 1b1, cb-1) ;

for(cb=maxlb;

cb<=nb;

cb++) ans[cb] = EventPresent(IsNewLow, 1b2, cb);

break;

case 8: // среднее направленное движение thrl = LinearScale(v2, 5.0, 50.0);

thr2 = thrl + LinearScale(v3, 5.0, 20.0);

ГЛАВА ГЕНЕТИЧЕСКИЕ АЛГОРИТМЫ AvgDirMov{hi, lo, cls, nb, 14, Serl);

for(cb=maxlb;

cb<=nb;

cb++) ans [cb] = (Serl[cb] > thrl && Serl [cb] < thr2) && Compare (Serl[cb], Serl[cb-l], v4-500.0);

break;

case 9: // Медленный %К thr = LinearScale(v2, 5.0, 95.0);

fac = LinearScale(v3, 1.0, 20.0);

thrl = thr - fac;

thr2 = thr + fac;

StochOsc(Serl, hi, lo, cls, 2, 10, nb) ;

for(cb=maxlb;

cb<=nb;

cb++) ans [cb] = (Serl[cb) > thrl && Serl [cb] < thr2) && Compare(Serl[cb], Serl[cb-1], V4-500.0);

break ;

case 10: // направление наклона MACD lb1 = 2 + (int)BiasedPosScale(v2, 18.0);

lb2 = lbl + 1 + (int)BiasedPosScale(v3, 48.0);

MacdOsc(Serl, cls, 1, lbl, lb2, nb) ;

for(cb=maxlb;

cb<=nb;

cb++) ans[cb] = Compare(Serl[cb], Serl[cb-2], v 4 - 5 0 0. 0 ), • break;

default:

nrerror("Undefined rule template selected");

break;

] // первые maxlb элементов результата должны иметь значение ЛОЖЬ memset (&ans [1], 0, sizeof(*ans) * maxlb);

#undef BiasedPosScale #undef LinearScale } 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 = xl6modOl.c parms — набор [1..MAXPRM] параметров dt — набор [1..nb] дат в формате ГГММДД орn - набор [l..nb] цен открытия hi — набор [l..nb] максимальных цен 1о — набор [l..nb] минимальных цен cls - набор [l..nb] цен закрытия vol — набор [l..nb] значений объема oi - набор [l..nb] значений открытого интереса dlrv — набор [l..nb] средней долларовой волатильности nb — количество дней в наборе данных ts — ссылка на класс торгового симулятора eqcls — набор [l..nb] уровней капитала при закрытых позициях // описываем локальные переменные static int rc, cb, ncontracts, maxhold, ordertype, signal;

static int disp, k, modeltype;

static float mmstp, ptlim, stpprice, limprice, tmp;

static float exitatr[MAXBAR+1] ;

static int rulel[MAXBAR+1], rule2[MAXBAR+1], rule3[MAXBAR+1];

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК // копируем параметры в локальные переменные для более удобного обращения к ним modeltype = parms[14];

// модель: 1=длинная позиция, 2=короткая ordertype = parms[15];

// вход: 1=на открытии, 2=по лимитному приказу, // 3=по стоп- приказу maxhold = 1 0 ;

// максимальный период удержания позиции ptlim = 4;

// целевая прибыль в единицах волатильности mmstp = 1;

// защитная остановка в единицах волатильности // выполнение расчетов для всей ценовой информации AvgTrueRangeS(exitatr,hi,lo,cls,50,nb);

// средний истинный диапазон для // выхода switch(modeltype) { case 1: case 2: // для моделей открытия длинных и коротких позиций // для каждого дня отдельно оценить три правила Rules (opn, hi, lo, cls, vol, oi, exitatr, nb, parms[1], parms[2], parms[3], parms[4], rulel);

Rules (opn, hi, lo, cls, vol, oi, exitatr, nb, parms[5], parms[6], parms[7], parms[8], rule2);

Rules (opn, hi, lo, cls, vol, oi, exitatr, nb, parms[9], parms[10], parms[11], parms[12], rule3};

break;

default: nrerror("Invalid model type");

/ проходим через дни, чтобы моделировать настоящую торговлю or(cb = 1;

cb <= nb;

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

continue;

} // выполняем все ожидающие приказы и сохраняем значение капитала по // закрытию rс = ts.update(opn[cb], hi[cb], lo [cb], cls[cb], cb};

if(rc != 0) nrerror("Trade buffer overflow");

eqcls[cb] = ts.currentequity {EQCLOSETOTAL};

// подсчитываем количество контрактов для торговли //... мы хотим торговать долларовым эквивалентом волатильности //... 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;

switch(modeltype) { case 1: // только длинные позиции if(rulel[cb] && rule2 [cb] && rule3[cb]) signal = 1;

break;

case 2: // только короткие позиции if(rulel[cb] && rule2 [cb] && rule3[cb]} signal = -1;

break;

] 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);

] ] // обрабатываем следующий день C++ код описывает шаблоны правил и стратегию торговой системы. Шаблоны правил определяются с помощью функции Rules. Аргументы v1, v2, v3 и v4 (четыре числа, которые содержит каждый ген) несут всю информацию, требуемую для реализации шаблонов правил. Аргумент v1 используется для выбора требуемого шаблона правила из 10 доступных;

аргументы v2, v3 и v4 используются для определения требуемых параметров каждого правила (направления сравнения, периоды скользящих средних и т.д.). Затем правило оценивается на всех днях, и оценки (1 для ИСТИНА, 0 для ЛОЖЬ) помещаются в вектор cms, возвращающий результаты функции. Макрос BiasedPosScale (x, а) используется для создания соответствия между целыми числами от 0 до 1000 и непрерывным диапазоном от 0 до а. Макрос используется, чтобы вычислить периоды обратного обзора для определения ценовых экстремумов и периоды скользящих средних v2, v3 или v4, значения которых получены из генетического алгоритма и пронумерованы целыми числами от 0 до 1000. Соответствие между номерами от 1 до 1000 и числами из диапазона от 0 до а нелинейно — оно устроено так, чтобы можно было более детально исследовать меньшие значения параметров. Например, предположим, что период скользящего среднего изменяется от 2 до 100 дней. Необходимо с одинаковой точностью производить выбор лучшего решения между периодами 2, 3 и 4 и периодами 30, 50 и 90. Точность поиска должна быть выше для маленьких чисел. Это связано с тем, что изменение периода скользящего среднего от 2 до 5 дней сильнее повлияет на результаты торговли, чем изменение от 50 до 60. Макрос LinearScale (x, а, b) выполняет линейную адресацию целочисленного диапазона 0... 1000 к диапазону а.... Макрос обычно используется при вычислении порогов или отклонений. В коде шаблона правила все параметры вычислены внутри функции Rules, а не внутри ГА. Генети ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК ческии алгоритм имеет инструкцию генерировать числа в диапазоне от 0 до 1000, за исключением элементов хромосом 1, 5 и 9, которые являются первыми числами в каждом гене и используются в качестве селекторов шаблонов правил. Масштабирование проводится внутри функции Rules, так как шаблоны для различных видов правил имеют различные диапазоны изменения параметров и контрольных значений. Процесс эволюции торговых систем начинается со случайного выбора значений хромосомы. Генетический оптимизатор выбирает два члена популяции и спаривает их (исходя из определения скрещивания, нормы мутации и размера гена). Затем полученное потомство возвращается как потенциальное решение. Когда компоненту ГА сообщают об эффективности полученного решения, он сравнивает ее с наименее пригодным членом популяции. Если пригодность потомства больше, чем у наименее пригодного члена, то ГА заменяет наименее пригодный член решения полученным потомством. Этот процесс повторяется в течение нескольких поколений и осуществляется с помощью программной оболочки (не приведенной в данной книге), которая, в свою очередь, делает повторные запросы к функции Model для моделирования торговли и оценки пригодности системы. Код функции Model почти идентичен используемому в более ранних главах. До цикла индексации дней, в котором генерируются приказы для торговли, функция Rules вызывается три раза (один раз для каждого гена), и результаты помещаются во временные ряды rule1, rule2 и ruleЗ. При этом также подсчитывается средний истинный диапазон за последние 50 дней, поскольку это необходимо для стандартного выхода и оценки правил. Внутри цикла оценивание правил производится для текущего дня (rulel[cb], rule2[cb], rule3[cb]), и если все оценки возвращают значение ИСТИНА, то генерируется сигнал на покупку (или продажу, если исследуются входы в короткую позицию). Входы запрограммированы стандартным способом для каждого из трех тестируемых приказов. В эволюционном процессе используются только данные из выборки. Выходные данные, полученные от программной оболочки, позволяют выбрать желаемое решение, которое можно использовать в торговле отдельно или в группе моделей. Решения могут быть легко сформулированы как понятные правила для оценки их «физического смысла» и использования их в качестве элементов других систем.

РЕЗУЛЬТАТЫ ТЕСТОВ Были выполнены шесть тестов. Эволюционный процесс использовался для поиска оптимальных правил входа в длинные и короткие позиции с каждым из трех приказов для входа: по цене открытия, стоп-приказу и лимитному приказу. Во всех случаях было создано 2500 поколений генетичес ГЛАВА ГЕНЕТИЧЕСКИЕ АЛГОРИТМЫ кой обработки. Задача вычисления всех решений и сохранения их в файлы потребовала всего несколько часов на быстром Pentium, что демонстрирует практическую пригодность этого метода. Для каждого теста генетический процесс произвел табличный файл (GFiles от 1 до 6), состоящий из строк, соответствующих каждому из поколений. Таким образом, каждая строка представляет определенное решение. Большинство ранних решений были мало пригодными для торговли, но качество решений улучшалось с появлением новых поколений, что характерно для ГА. Каждая строка содержит информацию относительно эффективности отдельного решения — набора параметров, который представляет ген, содержащийся в полной хромосоме. Были выбраны лучшие решения для входа в длинную и короткую позицию по цене открытия. Эти решения использовались для проведения шести тестов, результаты которых приведены ниже. В частности, было протестировано решение, которое обеспечивало лучший вход в длинную позицию по цене открытия, и его эффективность была оценена обычным способом на обеих выборках. То же самое решение было проверено и оценено с входом по стоп-приказу и лимитному приказу. Такая же процедура была проведена для коротких позиций: было определено лучшее решение для входа в короткую позицию по цене открытия. Затем решение было проверено на обеих выборках с каждым из двух типов приказов. Мы не отбирали отдельное оптимальное решение для каждого типа приказа, потому что такие действия не позволят сравнить эффективность различных видов приказов. Например, оптимальный вход по цене открытия может давать модель пробоя, в то время как оптимальный вход по стоп-приказу может наблюдаться при использовании противотрендовой модели ценового импульса. Эти модели никак не связаны друг с другом, и их результаты ничего не говорят об общей эффективности различных видов приказов. Поэтому мы сначала искали наилучшую модель с рыночным приказом по цене открытия, а затем тестировали найденную модель с другими видами приказов. Поскольку модель остается неизменной, этот подход позволяет делать значимые сравнения различных типов приказов. Решения для входов в длинную позицию Табл. 12-1 представляет торговые результаты 20 лучших решений для входов в длинные позиции по цене открытия (GFile 1). Каждая строка представляет различную торговую модель. Параметры не указываются, но представлены номера поколений (НОМЕР), вероятность или статистическая значимость (ВЕР, десятичный знак опущен, но подразумевается), средняя прибыль в долларах за сделку ($СДЕЛ), общее количество сделок (СДЕЛ), фактор прибыли (Ф.ПРИБ), доходность в процентах годовых (ДОХ%) и чистая прибыль или убыток (П/У).

ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 12—1. Лучшие 20 решений, полученные для длинных позиций с входом по цене открытия Эффективность большинства из этих моделей, по меньшей мере, впечатляет. Лучшие модели имеют статистическую значимость выше 0,00007, что означает, что эти решения имеют очень высокую вероятность прибыльной торговли в будущем. Многие решения заработали более 50% годовых. В некоторых случаях прибыли достигли значительно более высоких уровней. Хотя лимитный приказ дал много наилучших решений, остальные приказы также показали много хороших, если не великолепных результатов. Как и в предыдущих исследованиях, ГА превосходно обнаруживает многие пригодные для торговли модели.

Решения для входов в короткие позиции Табл. 12-2 представляет маленькую часть файла GFfile 4, в котором представлены найденные модели входов в короткие позиции по цене открытия. Как и в тесте 1, представлены 20 наилучших решений (отобранных по статистической значимости или соотношению риск/прибыль). И в этом случае налицо много хороших решений. Однако они уже не столь впечатляют, как решения для длинных позиций. Модели, приведенные в табл. 12-2, обладают меньшей статистической значимостью и доходностью. Другое от ГЛАВА ГЕНЕТИЧЕСКИЕ АЛГОРИТМЫ Таблица 12—2.

Лучшие 20 решений, полученные для коротких позиций с входом по цене открытия личие состоит в том, что в большинстве случаев количество сделок было очень маленьким;

оценки моделей основываются на редких событиях. Несмотря на все это, эволюционный процесс нашел много прибыльных наборов правил для входов в короткие позиции.

Результаты тестирования для стандартного портфеля Лучшее решение, показанное в табл. 12-1 (длинные позиции), и лучшее решение из табл. 12-2 (короткие позиции) были протестированы со всеми тремя видами приказов. Тесты с 1 по 3 представляют лучшую модель для длинных позиций с входом по цене открытия, протестированную с входом по цене открытия, лимитному приказу и стоп-приказу соответственно. Тесты с 4 по 6 представляют лучшую модель для коротких позиций со всеми тремя видами приказов. Табл. 12-3 содержит результаты лучших моделей с входом по цене открытия. Результаты приведены для длинных и коротких позиций на данных в пределах выборки и вне ее со всеми видами входных приказов. В таблице: ВЫБ— вид выборки данных (В— в пределах, ВНЕ— вне пределов выборки);

ДОХ% — доходность в процентах годовых;

Р/ПРИБ — ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК Таблица 12—3. Эффективность лучшей модели с входом по цене открытия, испытанной на выборке и вне ее пределов со всеми видами входных приказов ВЫ Б ДОХ% Р/ПРИБ ВЕР СДЕЛ ПРИБ% $СДЕЛ ДНИ ПРИБДЛ ПРИБКР Тест 01. Длинная позиция, вход по цене открытия В Вне 82.2 63.0 65.8 87.7 42.2 11.7 54.8 -10.0 16.5 -10.8 23.1 -13. 1.22 0.66 0.99 0.86 0.88 0.20 0.87 -0.21 0.51 -0.24 0.60 -0. 0.000 0. 0. 43 17 36 14 22 8 36 17 34 14 24 62 47 61 50 72 50 69 35 64 42 54 7 6 8 6 8 6 8 6 8 6 6 742 173 534 208 357 33 0 0 0 0 0 0 0 0 0 Тест 02. Длинная позиция, вход по лимитному приказу В Вне 0.038 0.003 0.344 0.003 0.669 0.056 0. 0. 14846 14920 16247 11929 - Тест 03. Длинная позиция, вход по стоп-приказу В Вне с Тест 04. Короткая позиция, вход по цене открытия В Вне 429 -46 252 -46 179 - Тест 05. Короткая позиция, вход по лимитному приказу В Вне - Тест 06. Короткая позиция, вход по стоп-приказу 0. 7493 - соотношение риска/прибыли в годовом исчислении;

ВЕР — ассоциированная вероятность статистической достоверности;

СДЕЛ — число сделок на всех рынках в составе портфеля;

ПРИБ% — процент прибыльных сделок;

$СДЕЛ— средняя прибыль/убыток со сделки;

ДНИ— средняя длительность сделки в днях;

ПРИБДЛ — общая прибыль от длинных позиций в тысячах долларов;

Pages:     | 1 |   ...   | 3 | 4 || 6 | 7 |



© 2011 www.dissers.ru - «Бесплатная электронная библиотека»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.