Вот тут пост с описанием о чем это и зачем
Самое ценное в статье
В файле
perfomance.py лежат методы по расчету среднегодовой взвешенной по времени / деньгам доходности.
— twrr — (time-weighted return) считает среднегодовую взвешенную по времени доходность
— xirr — (х internal rate of return она же money-weighted return) считает среднегодовую взвешенную по деньгам доходность
— create_return — метод, считающий оба вида доходности и рассчитывающий среднегодовую доходность каждого типа для каждого периода в входящих данных.
Зачем это вам нужно?
— Если вдруг у вас есть датасет с cashflow ваших инвестиций и вы хотите посмотреть на годовую доходность и заодно посмотреть, как эта доходность менялась во времени, то вам может быть интересно заглянуть в этот код.
Возможно файл переедет, но все равно ищите его в этом
репозитории. Методы описаны максимально подробно, но если чего пишите.
Что такое взвешенная доходность?
Если просто, то это способ посчитать доходность инвестиций, в которых больше двух денежных потоков.
В самом простом варианте расчета доходности: вложили 100, через месяц забрали 200. Значит (200-100)/100 * 100% = 100% доходности!
Но в реальности так не бывает.
Обычно самый простой случай выглядит как: Перевел 100 рублей на брокерский счет, затем купил бумаг на 86, заплатил комиссию, в итоге получил 96. А еще там был дивиденд. И вообще бумага была в валюте, потому сначала покупал валюты, заплатив комиссию, а потом еще валютная переоценка.
В общем, идея расчета доходности через взвешивание денежных потоков говорит нам: «Запиши в столбик все моменты времени и суммы которые ты потратил, в этот же столбик запиши все даты и суммы приходов от инвестиций, сделай немного магии и получи ответ.»
Подобная магия реализована в экселе в виде функции XIRR (ЧИСТВНДОХ в русской версии), соответственно только для расчета взвешенного по деньгам годовой доходности. В сервисах, в том числе брокерских ее сразу и не найдешь. Только недавно в личном кабинете interactive brocker появился такой расчет.
Математику этих расчетов я брал из интернет статей,
например из этой
Как это было.
Как оказалось это была не тривиальная и прикольная задачка. В открытых репозитариях пакет считающий взвешенную по деньгам доходность (XIRR) появился только в сентябре 2020 года. К тому времени я уже ковырял эту задачу месяца три. Все дело в том, что xirr не считается аналитически. То есть нельзя взять одно число и разделить на другое получить ответ. xirr считается численным методом, то есть перебором.
В python есть отличная библиотека для подобного класса задач
scipy и найденное на просторах интернета решение, использующее данную библиотеку вполне себе решало эту задачу. Кроме случаев отрицательной доходности.
В scipy были методы, которые решали задачу поиска xirr для любых доходностей, но не точно и очень долго! Вот прямо долго. Например что бы обсчитать строк 30 денежных потоков, уходило секунд 15. А если например был сет данных на пару лет, то можно было забывать о каком либо приемлемом времени.
Вообще на этой задаче я впервые столкнулся с проблемой скорости выполнения. Первый вариант решения расчета взвешенной по времени доходности (twrr) был написан на циклах и работал секунд 20 на 300 строках, переписанный на библиотеке pandas стала работать за секунды, переписанный на тип данных numpy и с использованием собственных методов за доли секунды.
В итоговом варианте, даже использующий численные методы xirr, работает за 10 секунд на 4000 записей. И это без использования дополнительных мощностей, параллелизации и остальных фокусов. Просто оптимизация кода.
Собственно примерно пол года я этой оптимизацией и занимался. Понятно, что не больше 3 часов в неделю, но все же.
В итоге реализация twrr была сделана мною и моим ментором по программированию. Xirr я взял из появившейся реализации, в ней была последняя подсказка, как это надо реализовывать и гораздо оптимальнее код. От себя дописал туда возможность расчета доходностей для любых периодов. От года до секунд.
Из этого периода я вынес несколько мыслей, которые хотел бы сказать себе, начинающему этот путь:
Чему я научился:
1. Циклы только если без них никак
2. Лучше всего использовать изначальный код python, а не дополнительные библиотеки
3. Если все же нужны библиотеки, стоит хорошо погрузиться в используемые методы и самые быстрые для этих задач типы данных
Собственно, если кто то попробует попользоваться и найдет ошибки. Обязательно приходите ругаться в комменты, это сильно поможет проекту!
Не нравится бумажка — есть Ексель или его бесплатные аналоги. OpenOffice, например.
95% страждущих только подсчётом убытков и занимается.))