Я уже давно использую для бектестов python и pandas. pandas это библиотека для работы с матрицами и её прелесть в том, что она оперирует векторами и работает ГОРАЗДО быстрее, чем обычные циклы. Для того, чтобы сохранить это достоинство при бектестах я использую логарифмическую доходность (log-return на английском). Не ручаюсь за русские термины, так как узнал про них из англоязычных статей. Написанное ниже не истина в первой инстанции, а моя попытка разобраться как это всё работает чтобы применять на практике. Если я не прав, напишите. Я хоть и защищал кандидатскую диссертацию, но не по математике или экономике.
Немного теории
Логарифмическая доходность — разница стоимости актива в разные промежутки времени в процентах. Рассчитываеся по такой формуле:
Формула для расчёта логарифмической доходности, логарифм натуральный
Теперь на примере акций теслы. Цена по дням:
Цена теслы по дням
Логарифмическая доходность:
Логарифмическая доходность
На самом деле есть хитрость, если считать всё последовательно, то можно посчитать разницу между первой и последней ценой, так как остальные взаимно уничтожатся.
При расчёте нескольких дней подряд, можно посчитать разницу только между первой и последней ценой
Но это если считать всё руками. Дальше будем считать всё подряд, так удобнее.
Предположим, мы купили акции теслы в начале периода и продали в конце. Чтобы посчитать прибыль такой сделки, нужно посчитать сумму логарифмов накоплением (cumulative sum) и посчитать экспоненту.
Прибыль сделки:
Как меняется доходность с изменением цены (последний столбец). Это цифра в разах, чтобы получить привычные проценты нужно умножить на 100%
Пример расчёта стратегии на python
Есть акции теслы c января 2020 года. Дневной таймфрейм. Считаем две сользящие средние за 3 дня и 10 дней. Стратегия очень простая: если трёхдневная средняя выше десятидневной, то покупаем, если ниже, то продаём.
Импортируем котировки из yahoo finance и получаем вот такой dataframe:
Тесла с января 2020 года на дневном таймфрейме
Считаем две скользящие средние:
tsla_history['ma_3'] = tsla_history['Close'].rolling(window=3).mean()
tsla_history['ma_10'] = tsla_history['Close'].rolling(window=10).mean()
Скользящие средние и цена закрытия
Считаем позицию. 1 покупка, -1 продажа:
tsla_history['position'] = (tsla_history['ma_3']-tsla_history['ma_10']).apply(np.sign)
Считаем логарифмическую доходность:
tsla_history['log_return'] = tsla_history['Close'].apply(np.log).diff(1)
Считаем логарифмическую доходность с учётом позиции:
tsla_history['my_log_return'] = tsla_history['position'].shift(1)*tsla_history['log_return']
Считаем прибыль стратегии:
tsla_history['return'] = tsla_history['my_log_return'].cumsum().apply(np.exp)
Прибыль стратегии
Можно добавить ещё расчёт комиссий. Возьмём 0,3% как у некоторых брокеров.
transaction_costs = 0.003
tsla_history['delta'] = tsla_history['position'].diff(1).abs()
tsla_history['tcs'] = tsla_history['delta']*transaction_costs
tsla_history['my_log_return_tcs'] = tsla_history['position'].shift(1)*tsla_history['log_return'] - tsla_history['tcs']
tsla_history['performance_tcs'] = tsla_history['my_log_return_tcs'].cumsum().apply(np.exp)
Сравнение стратегии с комиссей и без
И чё?
Весь бектестер занимает пару десятков строк кода и работает очень быстро. Можно мгновенно посчитать эту стратегию на меньшем таймфрейме, на большем диапазоне дат, на любое количество активов.
Полный код в jupyter notebook можно найти у меня в телеграм канале
t.me/zenoftrading
<br />tsla_history['position'] = (tsla_history['ma_3']-tsla_history['ma_10']).apply(np.sign)<br /><br />
tsla_history['log_return'] = tsla_history['Close'].apply(np.log).diff(1)
<br />покупка идет и считается последний день<br />
<br />это заглядывание в историю.<br /><br />
Вы покупаете вначале дня а информацию о сигнале получаете в конце этого-же дня.
tsla_history['my_log_return'] = tsla_history['position'].shift(1)*tsla_history['log_return']
tsla_history['log_return'] — а здесь почем сдвига нет?
Это как то помогает заработать?
А локальные минимумы и максимумы можно предсказать? Хотя бы по одному ближайшему?
То, что если использовать индикаторы на базе скользящих средних, и по сигналам совершать сделки, с помощью питона можно рассчитать сколько бы заработал/потерял?
Если так, то я просто не понимаю, зачем изобретать велосипед?
Капец хобби.
Лучше бы робота какого написал, который статьи в Телеграм сам пишет, чтоб время себе сэкономить.
Таких встроенных средств навалом есть, в терминале альфадирект точно есть, в метатрейдере по моему есть.
Ладно бы чувак, анализируя данные, придумал находить точки входа, которые статистически, давали бы вероятность точного прогноза хотя бы процентов 60
Вот я занимался этой муйней — анализом рыночных данных с помощью пандаса некоторое время, и я точно знаю как.
Ещё раз повторю свой вопрос, что Вы считаете? Можете сформулировать, раз пост запилили? Уточню также, что самое важно не как, и не что, а зачем.
Неужели Вы не слышали такой мем, что, тот кто не может простыми словами сформулировать, что он делает и зачем делает, по факту сам не понимает, чем занимается.
Дак вот, для тех, кому это интересно, все это проще, нагляднее, быстрее сделать в каком нибудь Microsoft power by например, если самому охота повозиться. Или есть ещё масса инструментов для анализа, причём встроенные в терминалы некоторые.
Тестировать можно бесплатно
valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo (https://pypi.org/project/yfinance/)
Рынки — недетерминированные структуры. Формулы — не дадут ничего, уже проверено.
ln(98.43/93.81)=0.0481, а не 0.021.
Любой расчет должен имитировать не только схему принятия решения и её влияние на результат, но также транзакционные издержки и правило управления капиталом. Расчет в логарифмах позволяет очень легко учесть транзакционные издержки и близко к действительности — самофинансируемую стратегию. Для одного лота надо действовать иначе.