Блог им. AlekseyManin

Купил и держи. Сравнение.

В продолжение предыдущей публикации, сделал графики на которых можно сравнить доходы по разным бумагам.

Интерпретацию результатов описал в предыдущей публикации. 

Особенность получающегося графика — это коряво выглядит ось Х(годы начала инвестирования), пришлось отказаться от строкового формата, ради смещения новых столбиков.

SPY, BRK-B, IJH, QQQ AAPL, BRK-B, IJH, QQQ AAPL, MSFT, NVDA, GOOGL

Кому нужен код:

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()
Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
819 | ★1
6 комментариев
Вот поверни лейблы тиков по x:

plt.setp(
    ax.xaxis.get_majorticklabels(),
    ha=«right»,
    rotation=45,
    rotation_mode=«anchor»);


avatar
Ëжик, спасибо!
И что вам показывает этот анализ? Как вы поймете, что в 96-м нужно было вкладывать в appl, в 2006 переложиться в NVDA, а в 2017 переложиться наверное в TSLA??
Во что переложиться в 2022 году, чтобы оказаться в лучшем столбце?
avatar
NeHonduras, я бы в таком ключе не рассматривал этот анализ. Как говориться: «Не клади все яйца в одну корзину».

Читайте на SMART-LAB:
Фото
14 августа раскроем финансовые итоги Хэдхантера за второй квартал и первое полугодие 2026 года
Финансовые результаты компании, ключевые цифры и инфографику опубликуем в этом канале. Подробный отчёт и презентацию разместим на нашем...
Фото
Хэдхантер входит в ТОП-5 мировых джоб-бордов по размеру выручки
Что помогает компании сохранять устойчивость и расти при любых условиях: • Рост аудитории основного продукта. Крупнейший в СНГ джоб-борд hh․ru...
Фото
Итоги первичных размещений ВДО и некоторых розничных выпусков на 5 августа 2026 г.
Следите за нашими новостями в удобном формате: Telegram , Youtube , RuTube, Smart-lab , ВКонтакте , Сайт
Фото
Хэдхантер. Ситуация на рынке труда в июле. Есть признаки улучшения
Вышла статистика рынка труда за июль 2026 года (за июнь можно почитать здесь ), которую Хедхантер публикует ежемесячно, что же там...

теги блога Алексей Манин

....все тэги



UPDONW
Новый дизайн