Блог им. AlekseyManin
В продолжение предыдущей публикации, сделал графики на которых можно сравнить доходы по разным бумагам.
Интерпретацию результатов описал в предыдущей публикации.
Особенность получающегося графика — это коряво выглядит ось Х(годы начала инвестирования), пришлось отказаться от строкового формата, ради смещения новых столбиков.
Кому нужен код:
from datetime import date<br /><br />import numpy as np<br />import pandas as pd<br />import yfinance as yf<br />import matplotlib.pyplot as plt<br /><br /><br />class Bar:<br /> def __init__(self):<br /> self.year = 0<br /> self.month = 0<br /> self.day = 0<br /> self.open = 0<br /> self.high = 0<br /> self.low = 0<br /> self.close = 0<br /><br /><br />def run(df, start_date, end_date, increment, date_increment, fees):<br /> """ Основная функция """<br /> df = df[start_date:end_date]<br /> cur_bar = Bar()<br /> prev_bar = Bar()<br /> increment_is_completed = False # Приращение депо в этом месяце (False-не было, True-было)<br /> depo = 0 # Брокерский счет в валюте<br /> sum_depo = 0 # Общая сумма инвестирования (переведено на брокерский счет)<br /> portfolio = 0 # Количество бумаг<br /><br /> # Перебор строк DF, как приход нового бара<br /> for row in df.itertuples(): # Перебор строк DF<br /> cur_bar.day = date.timetuple(row[0])[2]<br /> cur_bar.month = date.timetuple(row[0])[1]<br /> cur_bar.year = date.timetuple(row[0])[0]<br /> cur_bar.open = row[1]<br /> cur_bar.high = row[2]<br /> cur_bar.low = row[3]<br /> cur_bar.close = row[4]<br /><br /> if cur_bar.month != prev_bar.month: # Если месяц предыдущего бара не равен месяцу текущего бара<br /> increment_is_completed = False<br /> elif cur_bar.month == prev_bar.month and not increment_is_completed and cur_bar.day >= date_increment:<br /> depo += increment<br /> sum_depo += increment<br /> increment_is_completed = True<br /><br /> while cur_bar.open + cur_bar.open * fees < depo:<br /> depo -= cur_bar.open + cur_bar.open * fees<br /> portfolio += 1<br /><br /> prev_bar.day = cur_bar.day<br /> prev_bar.month = cur_bar.month<br /> prev_bar.year = cur_bar.year<br /> prev_bar.open = cur_bar.open<br /> prev_bar.high = cur_bar.high<br /> prev_bar.low = cur_bar.low<br /> prev_bar.close = cur_bar.close<br /><br /> return sum_depo, portfolio * cur_bar.close, depo, portfolio, cur_bar.close<br /><br /><br />if __name__ == '__main__':<br /> # BRK-B IJH SPY AAPL<br /> df_rez = pd.DataFrame()<br /> # ticker_lst = ['AAPL', 'SPY', 'BRK-B', 'IJH'] # Тикер финансовых инструментов как он отображается на Yahoo Finance<br /> # ticker_lst = ['AAPL', 'BRK-B', 'IJH', 'QQQ'] # Тикер финансовых инструментов как он отображается на Yahoo Finance<br /> ticker_lst = ['AAPL', 'MSFT', 'NVDA', 'GOOGL'] # Тикер финансовых инструментов как он отображается на Yahoo Finance<br /> increment: int = 100 # Сумма ежемесячного инвестирования<br /> date_increment: int = 15 # Дата пополнения(число месяца)<br /> year_invest: int = 10 # Количество лет инвестирования<br /> fees = 0.0006 # 0.05% комиссия брокера ВТБ + 0.01% комиссия биржи<br /> for ticker in ticker_lst:<br /> df_ticker = yf.download(ticker) # Загрузка данных с Yahoo Finance<br /> df_ticker = df_ticker.drop(columns=['Adj Close', 'Volume']) # Удаляем ненужные колонки<br /><br /> df_rez_ticker = pd.DataFrame()<br /><br /> for year in range(1993, 2022):<br /> start_date: date = date(year, 1, 1) # Дата старта инвестирования(год, месяц, число)<br /> end_date = date(start_date.year + year_invest, start_date.month, start_date.day)<br /><br /> rez = run(df_ticker, start_date, end_date, increment, date_increment, fees)<br /><br /> dohod = round(rez[1] - rez[0] + rez[2], 2)<br /><br /> new_row = {'Год начала': int(year), f'Доход {ticker}': dohod}<br /> df_rez_ticker = df_rez_ticker.append(new_row, ignore_index=True)<br /><br /> if len(df_rez) == 0:<br /> df_rez = df_rez_ticker<br /> else:<br /> df_rez = pd.merge(df_rez, df_rez_ticker)<br /><br /> df_change_type = df_rez.astype({'Год начала': np.int64}) # Изменение типа, для печати без дробной части<br /> print(df_change_type) # Печать результирующей таблицы<br /><br /> index = df_rez['Год начала']<br /> values0 = df_rez[f'Доход {ticker_lst[0]}']<br /> values1 = df_rez[f'Доход {ticker_lst[1]}']<br /> values2 = df_rez[f'Доход {ticker_lst[2]}']<br /> values3 = df_rez[f'Доход {ticker_lst[3]}']<br /> bw = 0.2<br /> plt.title(f'Доход за {year_invest} лет ежемесячного инвестирования по ${increment}')<br /> plt.bar(index - 0.4, values0, bw, label=f'Доход {ticker_lst[0]}')<br /> plt.bar(index - 0.2, values1, bw, label=f'Доход {ticker_lst[1]}')<br /> plt.bar(index, values2, bw, label=f'Доход {ticker_lst[2]}')<br /> plt.bar(index + 0.2, values3, bw, label=f'Доход {ticker_lst[3]}')<br /> plt.xticks(index, df_rez['Год начала'].apply(int), rotation=45) # Подписи к оси Х переведены в int и повернуты<br /> plt.xlabel("Год начала инвестирования")<br /> plt.ylabel("Доход в $")<br /> plt.legend(loc=2)<br /> plt.show()
plt.setp(
ax.xaxis.get_majorticklabels(),
ha=«right»,
rotation=45,
rotation_mode=«anchor»);
Во что переложиться в 2022 году, чтобы оказаться в лучшем столбце?