ТЕСТИРОВАНИЕ МОДЕЛИ С ФИКСИРОВАННОЙ ЗАЩИТНОЙ ОСТАНОВКОЙ И ЦЕЛЕВОЙ ПРИБЫЛЬЮ
В стратегии МССВ величины защитной остановки и целевой прибыли были фиксированы на достаточно произвольном и, возможно, неоптимальном уровне. Что произойдет, если протестировать ряд значений этих параметров в поисках оптимального сочетания?
В данном тесте положение защитной установки управления капиталом прогоняется от 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') ; } } } // обрабатываем следующий день
)
Назад