Методология тестирования


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

Во всех нижеследующих тестах использован стандартный портфель. Количество контрактов при покупке или продаже при входе на любом рынке в любое время подбиралось так, чтобы приблизительно соответствовать долларовой волатильности двух контрактов S&P 500 на конец 1998 г.

Использованы стандартные выходы. Все тесты проведены с использованием C- Trader toolkit. Для того чтобы была возможность сравнить результаты, использованы портфели, стратегии выхода и платформа тестирования, идентичные использованным ранее. Тесты разделены на следующие за трендом и идущие против тренда. Они проводились на основе скрипта, содержащего инструкции для установки параметров, проведения оптимизации и генерации результатов для каждого сочетания видов скользящих средних, моделей и входных приказов.

Приведенный ниже код более сложен, чем код для пробоев; вместо разных последовательностей для комбинаций скользящих средних, правил входа и приказов использован один цикл, в котором параметры управляют выбором элементов системы. Этот метод необходим при генетическом развитии систем. Хотя здесь, собственно, нет генетических алгоритмов, подобные методы будут использованы в следующих главах. Этот код содержит параметры для управления элементами модели, упрощая обработку всех возможных комбинаций в систематическом виде.

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 = xlOmodOl.c

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

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

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

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

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

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

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

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

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


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

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

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

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

static int rc, cb, ncontracts, maxhold, fastmalen,slowmalen;

static int modeltype, ordertype, avgtype, signal;

static float mmstp, ptlim, stpprice, limprice, tmp;

static float exitatr[MAXBAR+1] ;

static float fastma[MAXBAR+1] , slowma[MAXBAR+1] ;

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

fastmalen = parms[1]; // период для быстрой скользящей средней

slowmalen = parms[2]; // период для медленной скользящей средней

modeltype - parms[5]; // тип модели входа

avgtype = parms[6]; // тип скользящего среднего

ordertype = parms[7]; // тип входного приказа

maxhold = 10; // максимальный период удержания позиции

ptlim = 4; // целевая прибыль в единицах волатильности

mmstp = 1; // защитная остановка в единицах волатильности

// пропускать неверные комбинации параметров

if(fastmalen >= slowmalen) {

set_vector(eqcls, 1, nb, 0.0);

return;

}

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

AvgTrueRangeS(exitatr, hi, lo, cls, 50, nb); // средний истинный

// диапазон для выхода

switch(avgtype) { // выбираем тип скользящей средней

case 1: // простые скользящие средние

Averages{fastma, cls, fastmalen, nb);

Averages(slowma, cls, slowmalen, nb);

break;

case 2: // экспоненциальные скользящие средние

XAverageS(fastma, cls, fastmalen, nb);

XAverageS(slowma, cls, slowmalen, nb);

break;

case 3: // треугольные скользящие средние с передним взвешиванием

FWTAverageS(fastma, cls, fastmalen, nb};

FWTAverageS(slowma, cls, slowmalen, nb);

break;

case 4: // VIDYA- адаптивные скользящие средние

VIAverageS(fastma, cls, fastmalen, 10, nb) ;

VIAverageS(slowma, cls, slowmalen, 10, nb) ;

break;

default: nrerror("Invalid moving average selected");

} ;

// проходим через дни, чтобы смоделировать реальную торговлю

for(cb =1; cb < = nb; cb++) {

//не входим в сделки до начала периода выборки

// ...так же, как установка MaxBarsBack в Trade Station

if (dt[cb] < IS_DATE} { eqcls [cb] = 0.0; continue;)

// выполняем все ожидающие приказы и подсчитываем капитал по закрытым

// сделкам

гс = ts.update (opn [cb] , hi [cb] , lo [cb] , cls [cb] , cb) ;

if (rc = 0) nrerror("Trade buffer overflow");

eqcls[cb] = ts.currentequity(EQ_C1OSETOTAL);

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

/ / ... мы хотим торговать эквивалентом долларовой волатильности

// ... 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;

// генерировать входные сигналы, цены стоп- и лимитных приказов,

// используя модель входа определенной скользящей средней

#define CrossesAbove(a,b, с) {а[с]>=b[с] && a [c- 1]<b[c- 1])

#define CrossesBelow(a,b,c) {a[c]<b[c] && a [c- 1]>=b[c- 1])

#define TurnsUp(a,c) {a [c]>=a[c- l] && a [c- 1]<a[c- 2])

#define TurnsDn(a,c) {a[c]<a[c- l] && a [c- 1]>=a[c- 2] )

signal=0;

switch(modeltype) {

case 1: // классическая следующая за трендом модель, основанная на

// пересечении

if (CrossesAbove(fastma, slowma, cb)) signal = 1;

else if (CrossesBelow(fastma, slowma, cb)) signal = - 1;

limprice = 0.5 * (hi [cb] + lo [cb]);

stpprice = cls [cb] +0.5 * signal * exitatr[cb] ;

break;

case 2: // следующая за трендом модель, основанная на наклоне

if (TurnsUp(fastma, cb)) signal = 1;

else if(TurnsDn{fastma, cb)) signal = - 1;

limprice = 0.5 * (hi[cb] + lo [cb]};

stpprice = cls[cb] +0.5 * signal * exitatr[cb];

break;

case 3: // противотрендовая модель

if(CrossesAbove(fastma, slowma, cb)) signal = - 1 ;

else if(CrossesBelow(fastma, slowma, cb)) signal = 1;

limprice = 0.5* (hi[cb] + lo[cb]);

stpprice = cls[cb] + 0.5 * signal * exitatr[cb];

break;

case 4: // противотрендовая модель, основанная на поддержке

// и сопротивлении

if(slowma[cb] > slowma[cb- 1]

&& CrossesBelow(fastma, slowma, cb) ) signal = 1;

else if(slowma[cb] < slowma[cb- 1]

&& CrossesAbove(fastma, slowma, cb)) signal = - 1;

limprice = 0.5 * (hi[cb] + lo[cb]);

stpprice = cls[cb] +0.5 * signal * exitatr[cb];

break;

default: nrerror("Invalid model selected"};

}

#undef CrossesAbove

#undef CrossesBelow

#undef TurnsUp

#tundef TurnsDn

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

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.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);

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

}

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