Следующий тест использует модифицированную стандартную стратегию выходов (МССВ). Системе придан больший реализм за счет того, что защитная остановка управления капиталом и лимит целевой прибыли срабатывают не только по цене закрытия, но и по внутридневным ценам.
Чтобы избежать неоднозначных ситуаций (срабатывания нескольких приказов в один торговый день), все входы будут производиться только по цене открытия. Таким образом, можно экспериментировать с широким разнообразием стратегий выхода. В остальном правила выхода идентичны использованным ранее и сводятся к следующему: после входа устанавливаются выходная защитная остановка выше (для коротких) или ниже (для длинных позиций) цены входа и выходной лимитный приказ выше (для длинных) или ниже (для коротких позиций) цены входа. Остановка смещена от цены входа на величину произведения некоторого множителя (параметр остановки по управлению капиталом) и размера среднего истинного диапазона. Лимитный приказ смещен от цены входа на величину произведения другого множителя (параметра целевой прибыли) и среднего истинного диапазона. Система производит выход по цене закрытия по истечении 10 дней, если ни защитная остановка, ни целевая прибыль не закрывают сделку ранее. Используется средний истинный диапазон с периодом 50 баров. Ниже приведен код, обеспечивающий случайные входы и модифицированные стандартные выходы.
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 = x19mod02.c
// parms — набор [1..MAXPRM] параметров
// dt — набор [l..nb] дат в формате ГГММДД
// орn — набор [1..nb] цен открытия
// hi — набор [1..nb] максимальных цен
// 1о — набор [1..nb] минимальных цен
// cls — набор [1..nb] цен закрытия
// vol — набор [1..nb] значений объема
// oi — набор [1..nb] значений открытого интереса
// dlrv — набор [1..nb] средних значений долларовой волатильности
// nb — количество баров в наборе данных
// ts — ссылка на класс торгового симулятора
// eqcls — набор [1..nb] значений капитала по ценам закрытия
// объявляем локальные переменные
static int rc, cb, ncontracts, maxhold, signal, ranseed;
static float mmstp, ptlim, limprice, stpprice;
static int entryposted, entrybar;
static float exitatr[MAXBAR+1] , rnum, entryprice;
static long iseed;
// копируем параметры в локальные переменные для удобного обращения
ranseed = parms[8] ; // используется для генерации случайной
// последовательности
maxhold = 10; // период максимального удержания позиции
ptlim =4.0; // целевая прибыль в единицах среднего истинного
// диапазона
mmstp =1.0; // защитная остановка в единицах среднего
// истинного диапазона
// выполняем вычисления для всех данных
AvgTrueRangeS(exitatr,hi,lo,cls,50,nb); // средний истинный диапазон для
// выхода
// запускаем генератор случайных чисел
// ... используем разные случайные последовательности для каждого рынка
// ... ts.model() возвращает индекс рынка (SP=1, YX=2, ...)
iseed = - (ranseed + 10 * ts.model());
rnum = ran2 (Stiseed) ;
// проходим через дни, чтобы смоделировать реальную торговлю
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.О / dlrv[cb]);
if (ncontracts < 1) ncontracts = 1;