13 ноября 2013 long-short.ru mehanizator
Как обычно, будем рассматривать ценовые изменения в нормированном виде, где в качестве нормы возьмем волатильность предыдущего месяца, т.е. в скользящем окне 21 торговых дней.
Если сегодня SPY упал, будем заходить в позицию, пропорциональную этому падению, нормированному на волатильность. Коэффициент пропорциональности определим из формулы для коэффициента Келли, с понижающим коэффициентом 0.33.
Смотрим что получилось, шкала логарифмическая:
Результат 40 за 11 лет это 3.6 в год в среднем, то есть +260% без реинвестирования. Просадки, конечно, будут нечеловеческими, поэтому как это обычно бывает, вряд ли кто решится торговать с "плечами по келли".
Шарп 1.03
Оборот стратегии за все время 50000, если оценить торговые издержки на SPY 0.01% в одну сторону, получается 5, т.е. где-то 8% доходности будут уходить в издержки.
В общем, как первое приближение пойдет, но для реальной жизни хорошо бы добавить еще один параметр. Напрашивается очевидный кандидат - само значение локальной волатильности. Из-за эффекта плеча можно ожидать, что стратегия будет лучше работать, когда волатильность низкая.
Код рисеча на Котлине:
http://www.long-short.ru/ (C) Источник
Не является индивидуальной инвестиционной рекомендацией | При копировании ссылка обязательна | Нашли ошибку - выделить и нажать Ctrl+Enter | Отправить жалобу
Если сегодня SPY упал, будем заходить в позицию, пропорциональную этому падению, нормированному на волатильность. Коэффициент пропорциональности определим из формулы для коэффициента Келли, с понижающим коэффициентом 0.33.
Смотрим что получилось, шкала логарифмическая:
Результат 40 за 11 лет это 3.6 в год в среднем, то есть +260% без реинвестирования. Просадки, конечно, будут нечеловеческими, поэтому как это обычно бывает, вряд ли кто решится торговать с "плечами по келли".
Шарп 1.03
Оборот стратегии за все время 50000, если оценить торговые издержки на SPY 0.01% в одну сторону, получается 5, т.е. где-то 8% доходности будут уходить в издержки.
В общем, как первое приближение пойдет, но для реальной жизни хорошо бы добавить еще один параметр. Напрашивается очевидный кандидат - само значение локальной волатильности. Из-за эффекта плеча можно ожидать, что стратегия будет лучше работать, когда волатильность низкая.
Код рисеча на Котлине:
fun main(args: Array ) {
val spy = Sec("spy", Date(103, 0, 1))
val normDays = 21
val norms = spy.getNormalization(normDays, NormalizationType.ABS)!!
val changesPast = spy.getPastLogChanges(1)!!
val changesFuture = spy.getFutureLogChanges(1)!!
// KELLY
val normalizedChangesFuture = Util.commonDates(norms, changesFuture)!!.map { date ->
date to changesFuture[date]!! / norms[date]!!
}.toSortedMap()
val variation = normalizedChangesFuture.values().fold(0.0, { v, x -> v + x * x }) / normalizedChangesFuture.size
val kelly = 0.33 / variation
// POSITIONS
val positions = Util.commonDates(norms, changesFuture, changesPast)!!.map { date ->
val normalizedPastChange = changesPast[date]!! / norms[date]!!
val position = if (normalizedPastChange
val (d, p) = e
p * changesFuture[d]!! / norms[d]!!
}.toSortedMap()
val eq = Util.cumulativeLogChanges(equityLogReturns)
val sharpe = Equity.getSharpe(equityLogReturns, 0.0)
"turnover: %7.4f, sharpe: %7.4f".f(turnover, sharpe).p()
Chart.showCharts("", eq, 2.0)
}
val spy = Sec("spy", Date(103, 0, 1))
val normDays = 21
val norms = spy.getNormalization(normDays, NormalizationType.ABS)!!
val changesPast = spy.getPastLogChanges(1)!!
val changesFuture = spy.getFutureLogChanges(1)!!
// KELLY
val normalizedChangesFuture = Util.commonDates(norms, changesFuture)!!.map { date ->
date to changesFuture[date]!! / norms[date]!!
}.toSortedMap()
val variation = normalizedChangesFuture.values().fold(0.0, { v, x -> v + x * x }) / normalizedChangesFuture.size
val kelly = 0.33 / variation
// POSITIONS
val positions = Util.commonDates(norms, changesFuture, changesPast)!!.map { date ->
val normalizedPastChange = changesPast[date]!! / norms[date]!!
val position = if (normalizedPastChange
val (d, p) = e
p * changesFuture[d]!! / norms[d]!!
}.toSortedMap()
val eq = Util.cumulativeLogChanges(equityLogReturns)
val sharpe = Equity.getSharpe(equityLogReturns, 0.0)
"turnover: %7.4f, sharpe: %7.4f".f(turnover, sharpe).p()
Chart.showCharts("", eq, 2.0)
}
http://www.long-short.ru/ (C) Источник
Не является индивидуальной инвестиционной рекомендацией | При копировании ссылка обязательна | Нашли ошибку - выделить и нажать Ctrl+Enter | Отправить жалобу