<< Пред. стр.

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

ОГЛАВЛЕНИЕ

След. стр. >>

// parms — набор [1..MAXPRM] параметров
// dt - набор [l..nb] дат в формате ГГММДД
// орn — набор [1..nb] цен открытия
// hi - набор [l..nb] максимальных цен
// 1о — набор [1..nb] минимальных цен
// cls - набор [l..nb] цен закрытия
// vol — набор [1..nb] значений объема
// oi — набор [1..nb] значений открытого интереса
// dlrv — набор [1..nb] средних долларовой волатильности
// nb - количество торговых дней в наборе данных
// ts — ссылка на класс торгового симулятора
// eqcls — набор [1..nb] уровней капитала при закрытых позициях

// объявляем локальные переменные
static int rc, cb, neontracts, maxhold, ordertype, signal;
static int avglen, disp, k, modeltype, rnatype;
static float mmstp, ptlim, stpprice, limprice, tmp, thresh;
static float exitatr[MAXBAR+1];
static float savg[MAXBAR+1] , pchg[MAXBAR+1] , stoch[MAXBAR+1] ;
static float ma1[MAXBAR+1] , ma2 [MAXBAR+1] ;

// копируем параметры в локальные функции для удобного обращения
avglen = parms[1]; // длина скользящей средней
disp - parms[2]; // фактор смещения
thresh = parms[3]; // пороги для импульсных моделей
matype = parms[7]; // тип скользящей:
// 1=простое скользящее среднее
// 2-экспоненциальное
// 3=треугольное с передним взвешиванием
// 4-треугольное
// 5=простое центрованное
// 6 =экспоненциальное центрированное
// 7 =треугольное центрированное
modeltype = parms[8]; // тип модели:
// 1-импульс
// 2-пересечение
// 3=пересечение с подтверждением
// 4=пересечение с подтверждением и инверсией
ordertype = parms[9]; // вход: 1-на открытии, 2-по лимитному приказу,
// 3 -по стоп - приказу
maxhold = 10; // период максимального удержания позиции
рt1irn = 4 ; // целевая прибыль в единицах волатильности
mmstp = 1; // защитная остановка в единицах волатильности
// выполняем вычисления для всех данных, используя процедуры быстрой
// обработки массивов
AvgTrueRangeS(exitatr,hi,lo, cls, 50, nb) ; // средний истинный диапазон для
// выхода
ГЛАВА 8 СЕЗОННОСТЬ 187




pchg[l] = 0.0;
for(cb = 2 ; cb <= nb; cb++) {
tmp = cls[cb] - cls[cb-l]; // изменение цены
tmp = tmp / exitatr[cb]; // нормирование
pchg[cb] = clip(tmp, -2.0,2.0); // клиппинг
}
switch(modeltype) {
case 1 // данные для импульсной модели
SeasonalAvg(savg,pchg,dt,1,OOS_DATE,nb); // сезонности
MovAvg{savg,savg,matype,avglen,nb); // сглаживание
// скользящей
for(cb = 1; cb <= nb; cb++)
rna2 [cb] = fabs (savg [cb] } ;
MovAvg(mal, ma2, 1, 100, nb}; // среднее отклонение
break;
case 2: case 3: case 4: // данные для модели пересечения
SeasonalAvg(savg,pchg,dt,1,OOS_DATE,nb); // сезонности
for(cb = 2 ; cb <= nb; cb++)
savg [cb] = savg[cb-l] ; // объединение
MovAvg{mal,savg,matype,avglen,nb); // сглаживание среднего
MovAvg(ma2,rnal,matype,avglen,nb) ; // пересечение средней
if(modeltype = = 3 || modeltype == 4) // стохастический
// осциллятор
StochOsc(stoch,hi,lo,cls,1,9 , nb) ; // 9-дневный Быстрый %К;
break;
default: nrerror{"TRAPSMOD: invalid modeltype");
}
// проходим через торговые дни, чтобы смоделировать реальную торговлю
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");
eqcls [cb] = ts.currentequity(EQ_CLOSETOTAL) ;

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

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

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

// генерировать входные сигналы, цены стоп- и лимитных приказов
// для всех моделей сезонного входа
signal = 0;
switch{modeltype) {
case 1: // основная модель входа на основе порогов импульса
k = cb + disp;
tmp = thresh * mal[k];
if(savg[k] > tmp && savg [k-1] <= tmp)
signal = 1;
else if (savg [k] < -tmp && savg[k-1] >= -tmp)
signal = -1;
ЧАСТЬ II ИССЛЕДОВАНИЕ входов в РЫНОК
188



break;
case 2: // основная модель входа на пересечении
k = cb + disp;
if(CrossesAbove(mal, ma2, k)) signal = 1;
else if{CrossesBelow(mal, ma2, k)} signal = -1;
break;
case 3: // пересечение с подтверждением
k = cb + disp;
if(CrossesAbove(mal, ma2, k)) {
if(stoch[cb] < 25.0) signal = 1;
}
else if(CrossesBelow(mal, ma2, k)) (
if(stoch[cb] > 75.0) signal = -1;
}
break;
case 4: // пересечение с подтверждением и инверсией
k = cb + disp;
if(CrossesAbove(mal, ma2, k)) (
if(stoch[cb] < 25.0) signal = 1;
else if(stoch[cb] > 75.0) signal = -1;
}
else if(CrossesBelow(mal, ma2, k)) {
if(stoch[cb] > 75.0) signal = -1;
else if(stoch[cb] < 25.0) signal = 1;
)
break;
default: nrerror("TRAPSMOD: invalid modeltype");
}
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.position1) >= 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);

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



Определив локальные переменные и векторы, первый блок програм-
мы копирует различные параметры в соответствующие переменные для
более удобного и понятного обращения к ним. Параметры описаны в ссыл-
ках, размещенных в коде.
СЕЗОННОСТЬ 189
ГЛАВА 8




Следующий блок проводит все расчеты на полной серии данных. Сред-
ний истинный интервал для 50 дней рассчитывается и сохраняется в век-
торе (exitatr). Впоследствии он будет использоваться для размещения за-
щитных остановок управления капиталом и целевых уровней прибыли в
стандартизованной стратегии выхода. Средний истинный интервал в этом
векторе (или в ряду данных) также используется для нормализации воз-
никающих в ходе работы программы изменений цен.
После вычисления среднего истинного интервала рассчитываются
нормализованные и «обрезанные» изменения цен. Каждая точка в ряду
данных pchg отражает изменение цены между ценами закрытия текуще-
го и предшествующего дней. Изменения цены затем нормализуются пу-
тем деления их на средний истинный интервал и «обрезаются» для сни-
жения влияния экстремальных перепадов цены (статистических выбро-
сов). Нормализация необходима, поскольку волатильность рынков меня-
ется со временем иногда очень сильно. Например, сейчас индекс S&P 500
в 5 и более раз дороже, чем 15 лет назад. Очевидно, что и средняя дневная
волатильность изменилась соответствующим образом. Если бы измене-
ния цены не подвергались нормализации и не представлялись в единицах
текущей волатильности, сравнение сезонных явлений за разные годы
было бы искаженным. Годы, когда волатильность была выше, давали бы
больший вклад, чем годы с низкой волатильностью. В случае S&P 500 пос-
ледние годы полностью доминировали бы при проведении усреднения, а
при нормализованном представлении каждый год вносит почти одинако-
вый вклад. Срезание выбросов проводится на уровне — 2 и + 2 средних
истинных интервала, чтобы удалять случайные и аномальные значения,
не искажая общую оценку.
Опция выбора modeltype определяет, какие операции проводятся да-
лее. Значение 1 выбирает основную импульсную модель. Сезонные пока-
затели рассчитываются для обрезанных и нормализованных изменений
цен, причем в пределах выборки используется метод «складного ножа», а
вне пределов выборки — метод «всех прошедших лет». Эти операции обес-
печиваются вызовом функции SeasonalAvg. Временной ряд сезонных по-
казателей затем сглаживается скользящим средним (вид среднего уста-
навливается параметром matype, а длина— параметром avglen). Затем
рассчитывается временной ряд средних абсолютных отклонений сезон-
ных импульсов. Этот ряд представляет собой простое скользящее сред-
нее с периодом 100 дней от ряда абсолютных значений сезонных импуль-
сов, которое затем используется в дальнейших расчетах уровней поро-
гов. Значения modeltype 2, 3 и 4 представляют собой вариации моделей,
основанных на пересечении. Сезонные показатели рассчитываются, и
показатель изменения цены для каждого дня интегрируется (вычисляет-
ся «бегущая сумма»), в результате образуется новый ряд, ведущий себя
подобно ценовому ряду. Эта синтезированная серия отображает движе-
ние цен на основе типичного поведения рынка в предшествующие и, воз-
ИССЛЕДОВАНИЕ входов в РЫНОК
190 ЧАСТЬ II



можно, в будущие годы. Затем рассчитываются два скользящих средних:
та! (скользящее среднее интегрированного сезонного ряда типа matype
с периодом avglen) и та2 (сигнальная линия для определения момента
пересечения, представляет собой скользящее среднее ma1 с теми же па-
раметрами matype и avglen). Если же выбран modeltype 3 или 4, то прово-
дятся дополнительные расчеты для моделей с подтверждением и/или ин-
версией; в данном случае рассчитывается значение Быстрого %К с перио-
дом 9 дней, которое затем сохраняется в векторе stoch.
Следующий блок кода включает цикл, последовательно перебираю-
щий все торговые дни в ряду данных, — такой же цикл, как и во всех пре-
дыдущих главах, посвященных стратегиям входа. Первые его строки обес-
печивают обновление симулятора, рассчитывают количество контрактов
в сделке и пропускают дни с ограниченной торговлей. Следующие стро-
ки генерируют сигналы входа для моделей, основанных на сезонных фак-
торах. В зависимости от значения параметра modeltype используется один
из четырех подходов.
Modeltype 1 представляет базовую модель, основанную на пороге це-
нового импульса. Порог рассчитывается как произведение множителя, оп-
ределяющего относительную величину порога (thresh) на среднее абсолют-
ное отклонение сезонного импульса за прошлые 100 дней. Сигнал к по-
купке генерируется, если сумма сезонного импульса (savg) и параметра
смещения (disp) поднимается выше уровня порога. Если данная сумма опус-
кается ниже величины, равной значению порога со знаком минус, подает-
ся сигнал на продажу. Иными словами, если для данного дня плюс-минус
несколько дней (disp) предсказывается достаточно сильный сезонный им-
пульс цен, то торговля ведется в направлении ожидаемого движения.
Modeltype 2 представляет базовую модель пересечения и использует
скользящие средние интегрированных сезонных показателей текущего
дня плюс фактор смещения. Если первое скользящее среднее поднимает-
ся выше второго, генерируется сигнал к покупке. В противоположном
случае генерируется сигнал к продаже. Фактор смещения позволяет мо-
дели искать моменты пересечения, которые произойдут в будущем через
несколько дней. Таким образом, преодолевается запаздывание, свойствен-
ное скользящим средним. Поскольку сезонные средние основываются на
исторических данных, отстоящих от текущей даты не менее чем на один
год, вполне приемлемо прогнозировать на несколько дней вперед.
Modeltype 3 представляет собой ту же модель на основе пересечения,
но с добавлением подтверждения. Подтверждение обеспечивается про-
веркой стохастического осциллятора ценового ряда, определяющей, со-
впадает ли его динамика с ожидаемым поведением на основе сезонных
факторов.
Modeltype 4 использует модель, основанную на пересечении с добав-
лением подтверждения и инверсии. При использовании modeltype 4 сиг-
нал к покупке подается, если первое скользящее среднее пересекает вто-
СЕЗОННОСТЬ 191
ГЛАВА 8




рое снизу вверх. При этом значение стохастического осциллятора долж-
но быть не менее 25. Если же при верхнем пересечении стохастический
показатель превышает уровень 75, то модель подает сигнал к продаже
исходя из предположения, что произошла инверсия. Если первое сколь-
зящее среднее ниже второго, и нормальная сезонная модель подтвержда-
ется значением стохастического осциллятора, превышающим уровень 75,
генерируется сигнал к продаже. Если в этом случае показатель составит
менее 25, предполагается инверсия и отдается сигнал к покупке.
В свою очередь цена лимитного приказа (limprice) устанавливается на
уровне середины ценового диапазона текущего дня. Цена входного стоп-
приказа (stpprice) устанавливается на уровне закрытия текущего дня плюс
(для покупки) или минус (для продажи) половина среднего истинного ди-
апазона последних 50 дней. Остальные блоки кода идентичны приводив-
шимся в предыдущих главах: они обеспечивают размещение приказов
указанного вида (ordertype) и стандартные выходы.


РЕЗУЛЬТАТЫ ТЕСТОВ
Проводились тесты двух основанных на сезонных явлениях моделей вхо-
да: модели на пересечении (с подтверждением и инверсией и без них) и
модели, основанной на ценовом импульсе. Каждая модель исследовалась
с тремя видами обычных входных приказов: вход по цене открытия, по
лимитному и стоп-приказу.
В табл. 8-1 и 8-2 показаны результаты тестирования этих моделей по
отдельным рынкам в пределах выборки (табл. 8-1) и вне пределов выбор-
ки (табл. 8-2). В первом столбце указаны обозначения рынка. Последняя
колонка показывает, сколько прибыльных тестов было получено для дан-
ного рынка. Цифры в верхней строке указывают номер теста, последняя
строка — на скольких рынках данная модель была прибыльной. Эти дан-
ные достаточно подробно показывают степень прибыльности системы:
один минус ( — ) означает умеренные средние убытки в сделке ($2000 —
4000), два минуса ( ) — крупные убытки (более $4000). Один плюс (+)
означает умеренную прибыль ($1000 — 2000), два плюса (+ +) означают
крупную прибыль — более $2000 в сделке. Пустая ячейка обозначает при-
быль до $ 1000 или убыток до $ 1999. (Названия рынков и их символы соот-
ветствуют обозначениям табл. II-1; часть II, введение.)


Тесты базовой модели, основанной на пересечении
Интегрированный временной ряд ценоподобных сезонных показателей
сглаживался с помощью простого скользящего среднего ma1 с периодом
avglen. На его основе строилось второе среднее та2. Сигнал к покупке
ЧАСТЬ И ИССЛЕДОВАНИЕ входов в РЫНОК
192



генерировался, когда та! пересекала снизу вверх та2. Сигнал к продаже
генерировался, когда ma 1 пересекала сверху вниз та2. В целом это та же
модель, основанная на пересечении скользящих средних, но в ней исполь-
зуются не собственно цены, а прогнозируемые сезонные временные ряды.
Вход обеспечивается рыночным приказом по цене открытия (тест 1), ли-
митным приказом (тест 2) или стоп-приказом (тест 3).
Оптимизация в этих тестах состояла в прогонке параметра периода
скользящего среднего avglen от 5 до 20 с шагом 5 и также в прогонке пара-
метра смещения (disp) от 0 до 20 с шагом 1. С использованием входа по цене
открытия по показателю соотношения риска/прибыли в пределах выбор-
ки оптимальными были значения периода скользящего среднего 20 и сме-
щения 5. При входе по лимитному приказу оптимален был период 20 и сме-
щение 8, при входе по остановке период 20 и смещение 6. Модель, видимо,
лучше работала с длинными скользящими средними (с сильным сглажива-
нием) , и для входов по лимитному приказу требовались немного более ран-
ние сигналы по сравнению с входами по рыночному и стоп-приказу.
В пределах выборки не было получено ни одного положительного ре-
зультата при использовании и длинных, и коротких позиций, хотя сред-
ний убыток в сделке был гораздо меньше, чем во многих тестах из преды-
дущих глав. Лучше всего работали стоп-приказы, немного хуже — лимит-
ные приказы, а хуже всего — рыночные приказы по цене открытия. Для
стоп-приказов и лимитных приказов при ограничении только длинными
позициями торговля была выгодной. Во всех случаях наилучший период
скользящих средних составлял 20 дней, а оптимальное значение смеще-
ния изменялось для разных типов приказов. При использовании входа по
цене открытия оптимальное смещение равнялось 5 дням, при входе по
лимитному приказу — 8 дням, а по стоп-приказу — 6 дням. Это вполне
осмысленно, поскольку лимитные приказы отдаются раньше, чем рыноч-
ные приказы по открытию (так как для выполнения лимитного приказа
требуется некоторое время).
Вне пределов выборки результаты показали подобное же распределе-
ние относительной эффективности по показателям средней прибыли со
сделки ($СДЕЛ); использование приказов по остановке давало прибыль в
$576 со сделки, что соответствует доходности 8,3% годовых. Это немного,
но, тем не менее, это реальный положительный результат на недавних
данных вне пределов выборки. При использовании входов по стоп-при-
казу торговля, ограниченная только длинными позициями, была выгод-
ной и в пределах, и вне пределов выборки, а торговля короткими позици-
ями была убыточной в обоих случаях. Это соответствует результатам мно-
гих ранее проводившихся тестов. Для всех видов приказов и всех выбо-
рок процент прибыльных сделок составлял от 40 до 43%.
Интересно отметить, что даже в убыточных вариантах потери капита-
ла были значительно меньше, чем встречавшиеся в разнообразных пре-
дыдущих тестах.
ГЛАВА 8 СЕЗОННОСТЬ 193



Таблица 8—1. Эффективность в пределах выборки на различных рынках
и в различных тестах




При использовании рыночного входа по цене открытия капитал сни-
жался до ноября 1988 г. До июля 1989 г. было восстановлено около 50%
потерь, образуя U-образную модель со вторым пиком в районе ноября
1990 г. Затем наблюдалось довольно быстрое снижение до ноября 1992 г.,
после чего — более медленное падение капитала на протяжении всего
остатка выборки и первой трети периода вне выборки. Это снижение за-
кончилось в апреле 1996 г., и с тех пор до конца периода вне выборки ка-
питал возрастал.
194 ИССЛЕДОВАНИЕ входов в РЫНОК
ЧАСТЬ II




Таблица 8—2. Эффективность вне пределов выборки на различных рынках
и в различных тестах




При использовании входа по лимитному приказу капитал почти не из-
менился до января 1987 г., очень резко вырос до пика в мае 1987 г. и затем
падал до ноября 1992 г. С этого времени до июля 1994 г. наблюдался рез-

<< Пред. стр.

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

ОГЛАВЛЕНИЕ

След. стр. >>