zenoftrading
zenoftrading личный блог
06 апреля 2021, 12:27

Быстрый бектестинг стратегии на python с pandas

Я уже давно использую для бектестов python и pandas. pandas это библиотека для работы с матрицами и её прелесть в том, что она оперирует векторами и работает ГОРАЗДО быстрее, чем обычные циклы. Для того, чтобы сохранить это достоинство при бектестах я использую логарифмическую доходность (log-return на английском). Не ручаюсь за русские термины, так как узнал про них из англоязычных статей. Написанное ниже не истина в первой инстанции, а моя попытка разобраться как это всё работает чтобы применять на практике. Если я не прав, напишите. Я хоть и защищал кандидатскую диссертацию, но не по математике или экономике.

Немного теории



Логарифмическая доходность — разница стоимости актива в разные промежутки времени в процентах. Рассчитываеся по такой формуле:  
Быстрый бектестинг стратегии на python с pandas


Формула для расчёта логарифмической доходности, логарифм натуральный

Теперь на примере акций теслы. Цена по дням:  
Быстрый бектестинг стратегии на python с pandas


Цена теслы по дням

Логарифмическая доходность:  
Быстрый бектестинг стратегии на python с pandas




Логарифмическая доходность

На самом деле есть хитрость, если считать всё последовательно, то можно посчитать разницу между первой и последней ценой, так как остальные взаимно уничтожатся.  
Быстрый бектестинг стратегии на python с pandas


При расчёте нескольких дней подряд, можно посчитать разницу только между первой и последней ценой

Но это если считать всё руками. Дальше будем считать всё подряд, так удобнее.

Предположим, мы купили акции теслы в начале периода и продали в конце. Чтобы посчитать прибыль такой сделки, нужно посчитать сумму логарифмов накоплением (cumulative sum) и посчитать экспоненту.

Прибыль сделки:  
Быстрый бектестинг стратегии на python с pandas




Как меняется доходность с изменением цены (последний столбец). Это цифра в разах, чтобы получить привычные проценты нужно умножить на 100%

Пример расчёта стратегии на python



Есть акции теслы c января 2020 года. Дневной таймфрейм. Считаем две сользящие средние за 3 дня и 10 дней. Стратегия очень простая: если трёхдневная средняя выше десятидневной, то покупаем, если ниже, то продаём.

Импортируем котировки из yahoo finance и получаем вот такой dataframe:  
Быстрый бектестинг стратегии на python с pandas


Тесла с января 2020 года на дневном таймфрейме

Считаем две скользящие средние:
tsla_history['ma_3'] = tsla_history['Close'].rolling(window=3).mean()
tsla_history['ma_10'] = tsla_history['Close'].rolling(window=10).mean()


Быстрый бектестинг стратегии на python с pandas


Скользящие средние и цена закрытия

Считаем позицию. 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)
 
Быстрый бектестинг стратегии на python с pandas


Прибыль стратегии

Можно добавить ещё расчёт комиссий. Возьмём 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)
 
Быстрый бектестинг стратегии на python с pandas


Сравнение стратегии с комиссей и без

И чё?



Весь бектестер занимает пару десятков строк кода и работает очень быстро. Можно мгновенно посчитать эту стратегию на меньшем таймфрейме, на большем диапазоне дат, на любое количество активов.

Полный код в jupyter notebook можно найти у меня в телеграм канале t.me/zenoftrading
28 Комментариев
  • Антон Б
    06 апреля 2021, 12:49
    А Вы проверили что покупатете на следующий день.<br />Потому что здесь<br />
    <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 />

    Вы покупаете вначале дня а информацию о сигнале получаете в конце этого-же дня.
  • Дмитрий К
    06 апреля 2021, 12:50
    Офигеть,  я настолько тупой, что даже не понял, что тут считается. 
    Это как то помогает заработать?
    А локальные минимумы и максимумы можно предсказать?  Хотя бы по одному ближайшему?
  • A3hedge
    06 апреля 2021, 13:43
    Может быть использовать ТС Лаб? В нем все есть уже.
    Тестировать можно бесплатно
  • Андрей Алферов
    06 апреля 2021, 14:01
    На меньшем не выйдет, яхуфинанс тоьтко дневки даёт, тоже делал такие штуки, боьлше в академических целях, так как практичнее в тслаб загнать, такую стратегию прогнать минуты 3 с учётом времени на оптимизацию

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн