Избранное трейдера Тихий омут
pip install backtraderэто установит фреймворк, а потом
Как оценивать систему? То есть предположим, что уже есть система, на тестере. Есть важные показатели стратегии, есть не очень. Прибыльность, максимальный дродаун, максимальный период просадки – это всем понятно. Менее очевидно, но важны: средняя прибыль на сделку и профит-фактор. Если тестер показал меньше определенных значений, торговая система не работает. И неважно, какая там прибыль. Вообще неважно, хоть 500% годовых.
Средняя прибыль на сделку важна, потому что это показатель хрупкости системы.
Если у вас на стадии теста средняя прибыль вышла 0.02% на сделку, это, весьма вероятно, приговор. В конкретных цифрах это, например, средняя прибыль в 10 единиц с контракта ценой 50000 единиц. Такая прибыль висит на соплях. Если чуть подует ветерок – повысятся комиссии, спреды, чуть изменится рынок – она опрокинется. При этом тестер может нарисовать вам любую прибыль, но вы должны быть умнее его. Начиная от 0.1% уже терпимо для гиперликвидов (на Московской бирже последние десять лет это были фьючерсные контракты на доллар и индекс РТС, сейчас еще брент). Проверял – терпимо, работает. На менее ликвидных инструментах показатель должен быть сильно больше.
Последние что мы сделаем с нашими ценами. Зададим лимиты по волатильности. Я постараюсь сделать график РИ, дневной, с настоящими характеристиками. После чего мы сможем проверить на нем различные стратегии.
Мы используем хорошо забытую методику имени Орнштейна-Уленбека. В общем, это основа, из которой все понемногу брали и почетные имена забыли. Качаем файл и смотрим формулу:
https://cloud.mail.ru/public/2TTp/33yg8KSna
Это дифур и его решение. Где х(t) это наша искомая волатильность на следующий день. При этом мы получаем три члена. Альфа «а», которая отвечает за среднее значение и уровень притяжения. Битта «б», отвечает за скорость этого «притяжения» и сигма за границы «коридор». Если вы, когда ни будь, слышали такое название «компрессор лимитер», то это оттуда. На листе «ОУ» видны свойства этой формулы. У нас есть некий ряд со средним 5,6. Мы можем задать альфу 5,6 и битту 0,5. Мы получим ряд со средним 5,6, но более «сплоченную» вокруг среднего значения. Чем больше у нас битта, тем ближе мы к среднему значению. Можете поменять цифры в зеленой зоне и посмотреть, кто за что отвечает.
Говоря о торговле на бирже как о профессии, я не могу найти в ней романтики. Даже фильмы про трейдеров снять не получается. Потому что трейдинг это статистика. Если бы в наше время писали сценарий «Служебный роман», то место действия, было бы выбрано, в каком ни будь ПИФе. Ни каких переживаний, ни какого азарта, ни каких драм. Очень скучно. Тем более интересно, что находятся люди, которые на голом месте, могут потрепать себе нервы.
Поэтому снова и снова мы возвращаемся к статистике. В продолжении предыдущих топиков. Так как я не смогу осветить все в детальном объеме, ответы вы найдете в этом разделе естествознания.
Мы остановились на том, что к нам приходит событие, и мы можем измерить его волатильность. В общем, наше отклонение за день является кусочком дисперсии. И если оно 2%, то для нас оно среднее, и мы можем сказать, что СКО у нас 2% и это СКО нашего нормального распределения за этот день. Тогда мы можем сделать предположение, что следующее СКО у нас будет, тоже 2%.
Наверное, если кто сможет сгенерировать реальную волу, а значит, в обратную сторону, получить формулу ее расчета, тот получит следующую Нобелевскую премию. А я и не претендую (зачем мне она, «Мы делаем деньги на бирже»). Для начала давайте обсудим и согласуем свойства волатильности. Скачиваем файл.
https://cloud.mail.ru/public/k69C/4k8khnUhR
Что мы обычно делаем. Берем приращения логарифмов, потому что мы знаем, что цена растет по экспоненте. И из этих приращений делаем распределение. И мы допустим, что это распределение может быть нормальным от Гауса. Поэтому мы сразу нагенерим такую последовательность, которую нам выдавала в формуле sigma*W. И которую мы извлекаем из БА.
Сгенерируем нормальное распределение. В прошлый раз мы брали просто случайные числа для волатильности. Для того что бы сделать их числами нормального распределения надо вставить в функцию из эксела, «нормальное обращение» и задать волатильность нормальности и среднее. Смотрите формулу на листе «Нормальное распределение». Среднее мы оставим 0 волу 0,2. Если еще, кто ни будь не видел, то вот оно, о чем тут такие жаркие споры. При каждом пересчете выдаются параметры этого распределения. СКО и оно соответствует заданному 0,2. Эксцесс около 0 и Скос около 0. То есть выдерживаются все параметры Гауса. Ниже график дисперсии. Наши «дельта индикатор» и график волатильности со средней 20, который ходит вокруг 20. Вы можете пересчитывать лист. Распределение посчитано за 200 периодов, так что оно немного гуляет. И это нормально. У нас не так много значений в анализе.
V=R/(SL*C),
где V — объем позиции в лотах;
R — величина риска на сделку;
SL — размер ордера стоп-лосс в тиках;
C — цена тика в валюте депозита.
Settings= { Name = "Zigzag2", -- название индикатора delta=2, -- параметр индикатора line= { { Name = "zigzagline2", Type =TYPE_LINE, Width = 2, Color = RGB(120,90, 140) } } } function Init() vMin = 0 vMax = 0 vMinindex = 0 vMaxindex = 0 voldMinindex = 0 voldMaxindex = 0 return 1 end function OnCalculate(index) local printz = 0 if index == 1 then vMin = C(index) vMax = C(index) vMinindex = index vMaxindex = index voldMinindex = index voldMaxindex = index ve = C(index) else if voldMaxindex >= voldMinindex then if C(index) > (1 + Settings.delta/100)*vMin then vMin = C(index) vMax = C(index) vMaxindex = index voldMinindex = vMinindex vFrom = voldMaxindex vTo = vMinindex printz = 1 else if vMin > C(index) then vMin = C(index) vMinindex = index vFrom = voldMaxindex vTo = index printz = 0 else vFrom = vMinindex vTo = index printz = 0 end end else if voldMaxindex <= voldMinindex then if C(index) < (1 - Settings.delta/100)*vMax then vMax = C(index) vMin = C(index) vMinindex = index voldMaxindex = vMaxindex vFrom = voldMinindex vTo = vMaxindex printz = 1 else if vMax < C(index) then vMax = C(index) vMaxindex = index vFrom = voldMinindex vTo = index printz = 0 else vFrom = vMaxindex vTo = index printz = 0 end end end end if (printz == 1) or (Size() == index) then for i = vFrom, vTo do k = (C(vTo)- C(vFrom))/(vTo- vFrom); v = i*k + C(vTo) - vTo*k SetValue(i, 1, v) ve = v end if (Size() == index) then ve = C(index) if voldMaxindex >= voldMinindex then vFrom = voldMaxindex vTo = vMinindex end if voldMaxindex <= voldMinindex then vFrom = voldMinindex vTo = vMaxindex end for i = vFrom, vTo do k = (C(vTo)- C(vFrom))/(vTo- vFrom); v = i*k + C(vTo) - vTo*k SetValue(i, 1, v) end end end end return ve end