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, 15:44
        tsla_history['position'].shift(1)*tsla_history['log_return']

        tsla_history['log_return'] — а здесь почем сдвига нет?

  • Дмитрий К
    06 апреля 2021, 12:50
    Офигеть,  я настолько тупой, что даже не понял, что тут считается. 
    Это как то помогает заработать?
    А локальные минимумы и максимумы можно предсказать?  Хотя бы по одному ближайшему?
    • websan
      06 апреля 2021, 13:03
      Дмитрий К, обычная стратегия на скользящих средних, на такой не заработаешь много. 
      • Дмитрий К
        06 апреля 2021, 13:11
        websan, я просто не понял, что тут считается.
        То, что если использовать индикаторы на базе скользящих средних,  и по сигналам совершать сделки,  с помощью питона можно рассчитать сколько бы заработал/потерял?
        Если так, то я просто не понимаю, зачем изобретать велосипед?
        Капец хобби.
        Лучше бы робота какого написал, который статьи в Телеграм сам пишет, чтоб время себе сэкономить.
        Таких встроенных средств навалом  есть, в терминале альфадирект точно есть, в метатрейдере по моему есть.
        Ладно бы чувак, анализируя данные,  придумал находить точки входа, которые статистически,  давали бы вероятность точного прогноза хотя бы процентов 60
        • websan
          06 апреля 2021, 13:32
          Дмитрий К, здесь код просто делает бэк тест, но мне кажется он немного некорректен, т.к. не ясно когда открывать позиции, а когда закрывать. Проблемы средних скользящих это постоянные пробои ценой туда сюда, что создаёт кучу сделок ложных 
      • NikGood
        06 апреля 2021, 14:50
        websan, точнее сольешь и очень хорошр)
      • Дмитрий К
        07 апреля 2021, 12:42
        zenoftrading, хм,  Вы знаете,  как с помощью пандаса, загрузив тиковые данные,  найти все экстермумы, затем отфильтровать их по заданной дельте,  оставив только соответствующие, (например найти только экстремумы, разница между которыми 500 пунктов, отбросив все промежуточные с меньшей разницей), затем сделать анализ зависимости, по разным параметрам,  например через сколько в среднем времени, или после какого объёма, после одного экстермума цена доходит до следующего, или сколько было в промежутке между экстремумами сделок купли и продажи с каким объёмом,  и наконец сделать визуализацию в виде графиков, диаграмм,  гистограмм и прочего,  чтобы можно было статистически наконец понять, что любые исторически найденные неэффективности на одних участках и инструментах анализируемых данных, не работают на других.?

        Вот я занимался этой муйней — анализом рыночных данных с помощью пандаса некоторое время,  и я точно знаю как.

        Ещё раз повторю свой вопрос,  что Вы считаете? Можете сформулировать,  раз пост запилили? Уточню также, что самое важно не как,  и не что,  а зачем.

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

        Дак вот, для тех, кому это интересно,  все это проще, нагляднее, быстрее сделать в каком нибудь Microsoft power by например, если самому охота повозиться. Или есть ещё масса инструментов для анализа, причём встроенные в терминалы некоторые.
  • A3hedge
    06 апреля 2021, 13:43
    Может быть использовать ТС Лаб? В нем все есть уже.
    Тестировать можно бесплатно
  • Андрей Алферов
    06 апреля 2021, 14:01
    На меньшем не выйдет, яхуфинанс тоьтко дневки даёт, тоже делал такие штуки, боьлше в академических целях, так как практичнее в тслаб загнать, такую стратегию прогнать минуты 3 с учётом времени на оптимизацию
  • Павлуша Лодырев
    06 апреля 2021, 15:25
    Парсер по ключевым словам на форумах будет куда эффективнее, да и разве что дивергенция цены к всему подряд. Остальное эффекта на рынках не даст.
    Рынки — недетерминированные структуры. Формулы — не дадут ничего, уже проверено.     
  • Tenant
    06 апреля 2021, 15:30
    Ваши логарифмические доходности показались мне слишком маленькими (в абсолютных величинах) и я решил их подсчитать самостоятельно. Вместо ряда 0.021, -0.010, -0.003… я получил: 0.0481, -0.022, -0.0067… Не пойму, где у меня ошибка. Как эти доходности Вы считали в Python?
      • Tenant
        06 апреля 2021, 15:51
        zenoftrading, нет, видимо, я про это: log return = ln(P[t]/P[t-1]) 
        ln(98.43/93.81)=0.0481, а не 0.021.
  • Владимир Дымшаков
    16 апреля 2021, 11:12
    Вообще-то, библиотека для работы с матрицами — это numpy. А pandas оперирует объектами более сложной структуры — Series и DataFrame. И там могут быть не только числа. А работает pandas быстро именно с числами, потому как под капотом у нее numpy.

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

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