Я уже давно использую для бектестов 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 />
Вы покупаете вначале дня а информацию о сигнале получаете в конце этого-же дня.
Это как то помогает заработать?
А локальные минимумы и максимумы можно предсказать? Хотя бы по одному ближайшему?
Тестировать можно бесплатно