Тестирование модели с фиксированной защитной остановкой и целевой прибылью


Глава 1 Глава 2 Глава 3

В стратегии МССВ величины защитной остановки и целевой прибыли были фиксированы на достаточно произвольном и, возможно, неоптимальном уровне. Что произойдет, если протестировать ряд значений этих параметров в поисках оптимального сочетания?

В данном тесте положение защитной установки управления капиталом прогоняется от 0,5 до 3,5 с шагом 0,5. Целевая прибыль прогоняется от 0,5 до 5 с шагом 0,5. Под защитной остановкой и целевой прибылью понимается произведение указанного числа на средний истинный диапазон определенного количества последних торговых дней.

float *lo, float *cls, float *vol, float *oi, float *dlrv, int nb, TRDSIM &ts, float *eqcls) {

// Выполняет случайные входы с вариациями

// модифицированного стандартного выхода. Эта модель тестирует

// МСС, используя вариации в параметрах.

// File = x20mod01.c

// parms — набор [1..MAXPRM] параметров

// dt — набор [l..nb] дат в формате ГГММДД

// орn - набор [l..nb] цен открытия

// hi - набор [l..nb] максимальных цен

// 1о — набор [ 1..nb] минимальных цен

// cls - набор [l..nb] цен закрытия

// vol — набор [1..nb] значений объема

// oi — набор [1..nb] значений открытого интереса


// dlrv — набор [1..nb] средних долларовой волатильности

// nb — количество дней в наборе данных

// ts — ссылка на класс торгового симулятора

// eqcls - набор [l..nb] уровней капитала по ценам закрытия

// объявляем локальные переменные

static int rc, cb, neontracts, maxhold, signal, ranseed;

static float mmstp, ptlim, lirnprice, stpprice;

static int entryposted, entrybar;

static float exitatr[MAXBAR+1] , rnum, entryprice;

static long iseed;

// копируем параметры в локальные переменные для удобного обращения

ptlim = parms[1]; // целевая прибыль в единицах среднего истинного

// диапазона

mmstp = parms[2]; // защитная остановка в единицах среднего истинного

// диапазона

maxhold = parms[3]; // период максимального удержания позиции

ranseed = parms[8]; // используется для инициализации случайной

// последовательности

// выполняем вычисления по всему объему данных

AvgTrueRangeS(exitatr,hi,lo,cls,50,nb); // средний истинный диапазон для

// выхода

// очищаем генератор случайных чисел

// ... используем различную случайную последовательность для каждого

//инструмента

// ... ts.model() возвращает индекс рынка (SP=1, YX- 2, ...)

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+l] == lo[cb+l]) continue;

// генерировать "стандартные" случайные сигналы входа

signal = 0;

rnurn = ran2(&iseed) ;

if(rnum < 0.025) signal = - 1; // случайный короткий вход

else if (rnum > 0.975) signal = 1; // случайный длинный вход

// входим в сделки по цене открытия

entryposted = 0;

if(ts.position!) <= 0 && signal == 1) (

ts.buyopen('1' , ncontracts};

entryposted = 1;

entryprice = opn[cb+l];

entrybar = cb + 1;

}

else if(ts.position)) >= 0 && signal == - 1) {

ts.sellopen('2' , ncontracts) ;

entryposted = - 1;

entryprice = opn[cb+l];

entrybar = cb + 1

}

// выходим из сделок, используя модифицированный стандартный выход

if(entryposted > 0) {

// инициализация и выходы для длинных позиций в день входа

limprice = entryprice + ptlim * exitatr[cb];

stpprice = entryprice - mmstp * exitatr[cb];

ts.exitlonglimit{'A' , limprice);

ts.exitlongstop('B', stpprice);

}

else if(entryposted < 0) {

// инициализация и выходы для коротких позиций в день входа

limprice = entryprice - ptlim * exitatr[cb];

stpprice = entryprice + mmstp * exitatr[cb];

ts.exitshortlimit('С' , limprice);

ts.exitshortstop('D' , stpprice);

}

else {

// выходы после дня входа

if (ts- position{) > 0) { // длинные позиции

ts.exitlonglimit('F' , limprice);

ts.exitlongstop('G', stpprice);

if(cb- entrybar >= maxhold) ts.exitlongclose('E');

}

else if(ts.position() < 0) ( // короткие позиции

ts.exitshortlimit('I' , limprice);

ts.exitshortstop('J' , stpprice);

if(cb- entrybar >= maxhold) ts.exitshortclose('H') ;

}

}

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

)

Содержание раздела