Тесты исходной ССВ





Для проверки исходной ССВ используется метод случайного входа (описанный во введении к части III). В качестве выходов используются обычные стандартные выходы (только по цене закрытия). ССВ содержит следующие правила: Если на закрытии рынок находится ниже цены входа на величину, равную произведению некоторого множителя (параметр защитной остановки) на размер среднего истинного диапазона последних 50 дней, тогда срабатывает защитная остановка. Если цена закрытия больше цены входа на величину, равную произведению некоторого множителя (параметр целевой прибыли) на размер среднего истинного диапазона, тогда срабатывает лимитный приказ, фиксирующий целевую прибыль.
Эти правила сформулированы для длинных позиций с выходом по цене закрытия. Для коротких позиций пороги размещаются наоборот, т.е. защитная остановка помещается выше цены входа, а лимитный приказ — ниже. Если после 10 дней не достигнута ни защитная остановка, ни целевая прибыль, то сделку останавливают рыночным приказом по цене закрытия. Приведенный ниже код выполняет данные правила выхода и случайные входы. Тестируются три типа входных приказов (по цене открытия, по лимитному и стоп- приказу). Используется стандартный портфель и стандартная тестовая программная платформа.

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 = xl9mod01.c
// parms — набор [1..MAXPRM] параметров
// dt - набор [l..nb] дат в формате ГГММДД
// орn — набор [1. .nbl цен открытия
// hi — набор [1..nb] максимальных цен
// 1о - набор [1. .nb] минимальных цен
// cls - набор [l..nb] цен закрытия
// vol — набор [1..nb] значений объема
// oi - набор [l..nb] значений открытого интереса
// dlrv — набор [1..nb] значений среднего долларовой волатильности
/ / nb — количество дней в наборе данных
// ts — ссылка на класс торгового симулятора
// eqcls — набор [1..nb] уровней капитала по ценам закрытия
//объявляем локальные переменные
static int rc, cb, neontracts, maxhold, ordertype, signal;
static float mmstp, ptlim, stpprice, limprice, tmp;
static float exitatr[MAXBAR+1], rnum;
static int ranseed;
static long iseed;
// копируем параметры в локальные переменные для более удобного обращения
ranseed = parms[8]; // инициируем генератор случайных чисел
ordertype = parms[9]; // вход: 1=по цене открытия, 2=по лимитному
// приказу, 3 =по стоп - приказу
maxhold = 10; // максимальный период удержания позиции
ptlim = 4; // целевая прибыль в единицах волатильности
mmstp = 1; // защитная остановка в единицах волатильности
// делаем вычисления по всем данным
AvgTrueRangeS{exitatr,hi,lo,cls,50,nb); // средний истинный диапазон для
// выхода
// запускаем генератор случайных чисел
// ... отдельный запуск для каждого инструмента
iseed = - {ranseed + 10 * ts.model());
rnum = ran2 (&iseed) ;
// проходим через дни, чтобы смоделировать реальную торговлю
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);
// подсчитываем количество контрактов для сделки
// ... мы хотим торговать эквивалентом долларовой волатильности
// ... 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;
// генерировать входные сигналы, цены стоп- и лимитных приказов
signal = 0;
rnum = ran2(&iseed); // случайное число 0...1
if(rnum < 0.025) signal = - 1; // случайный короткий вход
else if(rnum > 0.975) 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, ncont}racts); 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) ;
} // обрабатывать следующий день
}