При проектировании торговых систем очень важно не только создать рабочую стратегию, приносящую прибыль, но и избежать ошибок в коде, потому что именно эти ошибки могут привести к так называемой «граальной» ловушке.
1 ловушка – подглядывание в будущее при входе в позицию
Впервые с такой ловушкой я столкнулся при разработке трендовой системы на основе индикаторов ADX+CCI. Найти эту ошибку мне помог Игорь Чечет, за что ему большое спасибо.
Кратко рассмотрим
данную торговую систему.
Вход в лонг осуществляется при росте индикатора ADX, который показывает наличие тренда, и пересечении индикатором CCI значения +100, который показывает момент входа в позицию. В шорт соответственно наоборот.
Приведу часть кода, которая была изначально:
//Сравниваем значение ADX на текущем баре и предыдущем
if (ADX.Series(Bars,ADXperiod)[bar] > ADX.Series(Bars,ADXperiod)[bar — 1]) {
if (CCI.Series(Bars,CCIperiod)[bar] > 100) { //Открытие позиции в Long
BuyAtMarket(bar);
}
else if (CCI.Series(Bars,CCIperiod)[bar] < -100) //Открытие позиции в Short
{
ShortAtMarket(bar);
}
}
В результате выполнения данного кода получилась очень красивая кривая доходности:
Ошибка здесь заключается в следующем. Вход в позицию осуществляется по рыночной цене на свече bar — BuyAtMarket(bar). Но если посмотреть правило, по которому осуществляется этот вход то становиться очевидно, что допущена ошибка – так называемое подглядывание в будущее. А именно, сравнивается значение индикатора ADX на текущей свече и предыдущей:
if (ADX.Series(Bars,ADXperiod)[bar] > ADX.Series(Bars,ADXperiod)[bar — 1])
Но дело в том что пока свеча не закрылась, мы не права имеем обращаться к значению индикатора на текущей свече. Соответственно, не имеем права входить в позицию на текущей свече. Таким образом, необходимо входить строго на следующей свече, по правилу BuyAtMarket(bar+1). В результате получим следующую кривую доходности:
2 ловушка – подглядывание в будущее при выходе из позиции
Подглядывание в будущее, на мой взгляд, одна из самых часто встречающихся ошибок, и при недостаточном анализе кода после построения торговой системы, увидеть ошибку бывает довольно тяжело. Так случилось с моей недавней системой на основе пробоя максимума/минимума за N свечей. Ситуация входа в позицию ошибки не содержала, но код выходы из позиции как раз подглядывал в будущее:
Рис 3. Кривая доходности для системы с ошибкой в коде при выходе из позиции
Изначально я думал, что ошибка в коде у меня всё же есть, но найти у меня её не получалось.
Скептически относясь к таким сумасшедшим результатам, я обратился за помощью к Дмитрию Власову, который указал на мою ошибку в коде. Дословная цитата —
Подробнее
3 ловушка – синтаксическая ошибка в коде
Программирую не только торговые системы очень часто встречаются ошибки синтаксиса в коде. Так, например в Си-подобных языках программирования (C++, C#, Java), есть два оператора «=» (равно) и «==» (сравнение), которые выполняют совершенно разные функции. Оператор «=» (равно) используется для присвоения переменной некоторого значения, а оператор «==» (сравнение) сравнивает две переменные.
Приведу
пример кода с ошибкой:
if ( Close[bar] = Close[bar-1] )
{
…
}
Такой код, безусловно, выполнится, и в результате в массиве Close, элементу с номером bar (т.е. Close[bar]) будет присвоено значение элемента c номеров bar-1. Поэтому для исправления этой ошибки нужно использовать оператор сравнение «==».
Эта ошибка довольно часто встречается, когда разработчик может просто опечататься.
4 ловушка – ошибка типов данных в коде
Довольно очевидная, на первый взгляд ошибка, но не всегда заметная при тестировании торговой стратегии, ошибка вычисления при использовании определенного типа данных.
Например, пусть в системе есть такой параметр как стоп-лосс, который составляет 0,3% риска на сделку и рассчитывается по формуле:
double stopLoss = price / 100 * 97;
Однако в данной строчке допущена ошибка, а именно результат деления — price / 100 – даст целое положительное число, а нам требуется вещественное (т.е. дробное), поэтому правильным вариантом будет использование оператора приведения типов:
double stopLoss = (double) price / 100 * 97;
5 ловушка – открытие/закрытие позиции на первой внутридневной свече
Часто при проектировании торговых систем вход осуществляется внутри дня, а позиция удерживается в течение нескольких дней, пока не сработает правило для выхода из позиции или стоп-лосс. Как мы все знаем, рынок, в большинстве случаев открывается гепом в одну или другую сторону, соответственно на первой свече (допустим минутной) происходим очень большое количество заявок, в том числе может сработать и стоп-заявка торговой системы. Однако, при тестировании торговой системы программы подобные
Wealth Lab не учитывают скорость движения цены на такой свече, и вполне вероятно, что тестер стратегии закроют позицию по стоп-лосу именно по цене стоп-приказа. Понятно, что это будет не совсем верно, т.к. большое проскальзывание в реале не даст закрыть позицию.
5 ловушка – порядок выполнения приказов в торговой системе
Для пессимистичного сценария результатов торговой системы, рекомендуется выполнять код обработки сигнала выхода из позиции перед приказом входа
//Если позиция открыта
if (IsLastPositionActive)
{
//Правила для выхода
}
else //Если позиция закрыта
{
//Правила для входа
}
Причем если используются одновременно в системе сигналы выхода из позиции по стоп-лосу и тейк-профиту, необходимо исполнять стоп-лосс именно перед тейк-профитом, т.к. данные сигналы могут возникнуть на одной свече.
6 ловушка – проскальзывание и комиссия
Перейдем к типичным ошибкам, которые из прибыльной торговой системы могут сделать убыточную. Это ситуации, в которых разработчик не учитывает проскальзывание и комиссию.
Рассмотрим следующую торговую систему.
Если цена пробивает максимум внутри дня, то входим в лонг, если минимум то сходим в шорт. Т.е. простая стратегия пробоя внутридневного экстремума. Приведу результат тестирования системы без учета комиссии и проскальзывания на фьючерсе на индекс РТС:
Подробнее
7 ловушка – некорректные данные для анализа
Одной из причин неудовлетворительного тестирования торговой системы, могут служить некорректные данные по какому-либо инструменту для тестирования. Это могут быть либо неверные свечи, либо аномально
длинные тени свечей, которые в рабочей стратегии могут давать убыточные результаты при срабатывании стоп-лоссов.
8 ловушка – переоптимизация торговой системы
Приведу в пример систему, которую я разрабатывал одной из первых. В системе использовались такие индикаторы как CCI, ADX и набор SMA. В результате получилась система с очень большим количеством параметров. Путем оптимизации я добился
прибыльной торговой системы на истории
В качестве вывода данной статьи, я хотел бы сказать, что ошибки в коде при построении торговых систем, могут появляться даже у опытных программистов и разработчиков, поэтому очень хорошо, если в вашем круге окружения есть люди, которые могут посмотреть на вашу систему со стороны. Не бойтесь рассказывать о своих ошибках и неудачах, ведь, как говорится, на ошибках учатся.
Посмотреть полный оригинал статьи
даже не используя робота
все равно допускаем ряд ошибок, подмеченных автром
При анализе торговых систем (когда глаз «замылен» и уже не видишь своих багов), часто помогают другие разработчики в поиске таких ошибок.
со стороны чужие ошибки виднее
Пример простой: Вы берете 4 средних, расчет 1- по open, 2- high, 3- low, 4- close и анализируете. Поведение первых трех будут изменяться внутри свечи только в одном направлении… это поможет убить ложную прибыль системе при тесте и большее соответствие с реалом… Удачи