Код позволяет проводить повторный вход в рынок при возникновении новых максимумов или минимумов.
// Выполнение тестирования модели
// parms - набор [1..MAXPRM] параметров
// dt — набор [1..nb] дат в формате ГГММДД
// орn — набор [1..nb] цен открытия
// hi — набор [l..nb] максимальных цен
// 1о — набор [1..nb] минимальных цен
// cls — набор [l..nb] цен закрытия
// vol — набор [l..nb] значений объема
// oi — набор [l..nb] значений открытого интереса
// dlrv — набор [1..nb] средних долларовой волатильности
// nb — количество дней в наборе данных
// ts — ссылка на класс торгового симулятора
// eqcls — набор [l..nb] уровней капитала при закрытых позициях
//объявляем локальные переменные static int cb, n, neontracts, maxhold; static float mmstp, ptlim, atr;
// копируем параметры в локальные переменные для удобного обращения
n = parms [1]; // параметр ширины канала
maxhold = 10; // период максимального удержания позиции
ptlim = 4.О; // целевая прибыль в единицах волатильности
mmstp = 1.0; // защитная остановка в единицах волатильности
// file - x09mod01.c
// только для этого теста выставляем транзакционные издержки равными нулю ts.commission(0.0); ts.slippage (0.0);
// проходим через бары (дни}, чтобы смоделировать реальную торговлю for(cb = 1; cb <= nb- 1; cb++) [
//не открываем позиций до начала выборки
//... то же самое, что установка MaxBarsBack в TradeStation if(dt[cb] < IS_DATE) { eqcls[cb] = 0.0; continue; }
// выполняем ожидающие приказы и считаем кумулятивный капитал ts.update(opn[cb] , hi[cb], lo [cb] , cls [cb], cb) ; eqcls [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+1] == lo[cb+1]} continue;
// file = x09mod01.c
// пробой канала но основе цены закрытия с входом на завтрашнем открытии if (cls [cb]>Highest(cls,n,cb- l) && ts.position {) < = 0) { ts.buyopen('1' , ncontracts) ;}
else if (cls [cb]<Lowest(cls,n,cb- l) && ts.position{)>=0) {ts . sellopen ('2 ', ncontracts) ;}
// симулятор использует стандартную стратегию выхода atr = AvgTrueRange(hi, lo, cls, 50, cb} ; ts.stdexitcls('X', ptlim*atr, mmstp*atr, maxhold);
] // обрабатываем следующий день
Этот код был скомпилирован и связан с оболочкой и библиотеками для разработчика; в TradeStation это называется верификацией системы. При помощи команд оболочки проводилась оптимизация параметра n с лобовым подходом. Лучшее по показателями риска/прибыли решение проверялось на данных, взятых вне пределов выборки. Оптимизация состояла в прогонке параметра n через значения от 5 до 100 с шагом в 5. Параметр защитной остановки mmstp был установлен на уровне 1 (т.е. одной единицы волатильности или среднего истинного диапазона), параметр целевой прибыли ptlim — на уровне 4 (4 единицы), а максимальный период удержания позиции maxdays был равен 10 дням. Эти значения использовались для стандартных параметров выхода во всех тестах методик входа, если не указано иначе. Чтобы осознать масштаб целевой прибыли и защитных остановок, укажем, что фьючерсы S&P 500 на конец 1998 г. имели средний истинный диапазон 17,83 пункта, или около $4457 за один новый контракт. Для первого теста комиссия и проскальзывание приняты равными нулю.
Для такой простой системы результаты были неожиданно хороши: годовая прибыль составила 76%. Все параметры n были прибыльными, в отношении риска/прибыли оптимальное значение составило 80 дней. Т- тест дневной прибыли (по соотношению риска/прибыли) показывает, что вероятность случайной эффективности составляет менее одной тысячной, а после коррекций на оптимизацию — менее одной сотой. Как и следовало ожидать по таким показателям, в тесте вне пределов выборки система также была прибыльной. Длинные позиции (покупки) принесли больше прибыли, чем короткие (продажи), возможно, в связи с ложными сигналами с короткой стороны, вызванными постоянным снижением цены при приближении срока истечения контрактов. Другое объяснение состоит в том, что цены на товары обычно более подвержены влиянию кризисов и дефицита, чем избытка. Как и при использовании других систем, основанных на пробое, процент прибыльных сделок был невелик (43%), причем крупные прибыли от редких удачных сделок компенсировали частые мелкие убытки. Хотя некоторым психологически трудно воспринимать систему, которая терпит убыток за убытком в ожидании большой прибыли, ожидание того стоит.
Капиталпортфеля при использовании оптимального для выборки параметра n стабильно рос как в пределах выборки данных, так и вне его; избыточная оптимизация здесь не представляла проблемы. График изменения капитала показывает некоторое снижение эффективности системы со временем. Впрочем, система, основанная на простом пробое канала, все еще может извлекать из рынка неплохую прибыль. Или нет? Учтите, что тест 1 проводился без учета расходов на сделки. В следующем тесте учтены комиссионные и проскальзывание.
Эрчрыю