Акции: расчет накопленной доходности для переменного размера портфеля, даты формирования, периода удержания и предыдущих месяцев формирования

Этот код предназначен для расчета накопленной доходности бразильских акций с использованием стратегии импульса для сравнения с SP500, IBOVESPA INDEX, BRL / USD. Для этого я изменю параметры функции возврата и проанализирую результаты, чтобы выбрать лучшие параметры настройки.

Стратегия состоит в том, чтобы покупать худшие и самые прибыльные акции предыдущего месяца и удерживать их в течение нескольких месяцев.

Переменными являются размер портфеля (таманхо), дата формирования (формирование), период удержания (удержание) и предыдущие месяцы, наблюдаемые до формирования (темп). Накопленная доходность рассчитывается «реторно». Чтобы варьировать все возможные параметры, я создал 4 вложенных цикла по формации, таманхо, удержанию и темпу.

Чтобы сравнить результаты с рыночными, я использовал функцию «bencretorno» в качестве эталонной доходности.

Этот код основан на канале YouTube AlgoVibes. https://youtu.be/xpP048vfNrg

Расчет занимает около 20 минут. Набор данных составляет 159 строк × 135 столбцов.

Я прошу совета, чтобы сократить время вычисления всех возможных результатов.

Я думаю, что мне не нужно хранить все результаты, только 100 лучших. И для оптимизации вычислений я должен использовать самое длительное время удержания для выбора второстепенных удержаний вместо того, чтобы снова выполнять расчет. Это избавит от многих вычислений.

# -*- coding: utf-8 -*-
"""AlgoVibes MOMEMTUM - 6,12 .ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1uu93oiclG2XDSKAA5xNSCovBazqTpoPw
"""

!pip install yfinance

import yfinance as yf
import pandas as pd
import datetime as dt
from pandas.tseries.offsets import MonthEnd

tickers = ['ABEV3.SA','AGRO3.SA','ALPA4.SA','ALSO3.SA','ALUP11.SA','AMAR3.SA','ANIM3.SA','ARZZ3.SA','AZUL4.SA','B3SA3.SA','BBAS3.SA',
           'BBDC4.SA','BBRK3.SA','BBSE3.SA','BEEF3.SA','BPAC11.SA','BRAP4.SA','BRDT3.SA','BRFS3.SA','BRKM5.SA','BRML3.SA','BRPR3.SA',
           'BTOW3.SA','CARD3.SA','CCRO3.SA','CESP6.SA','CGAS5.SA','CIEL3.SA','CMIG4.SA','COGN3.SA','CPLE6.SA','CPFE3.SA','CRFB3.SA',
           'CSAN3.SA','CSMG3.SA','CSNA3.SA','CVCB3.SA','CYRE3.SA','DIRR3.SA','DTEX3.SA','ECOR3.SA','EGIE3.SA','ELET3.SA','EMBR3.SA',
           'ENAT3.SA','ENBR3.SA','ENEV3.SA','ENGI11.SA','EQTL3.SA','EVEN3.SA','EZTC3.SA','FESA4.SA','FHER3.SA','FIBR3.SA','FLRY3.SA',
           'GFSA3.SA','GGBR4.SA','GNDI3.SA','GOAU4.SA','GOLL4.SA','GRND3.SA','GUAR3.SA','HAPV3.SA','HBOR3.SA','HGTX3.SA','HYPE3.SA',
           'IGTA3.SA','ITSA4.SA','ITUB4.SA','JBSS3.SA','JHSF3.SA','JSLG3.SA','KLBN11.SA','LAME4.SA','LCAM3.SA','LEVE3.SA','LINX3.SA',
           'LPSB3.SA','LREN3.SA','MDIA3.SA','MEAL3.SA','MGLU3.SA','MILS3.SA','MOVI3.SA','MRFG3.SA','MRVE3.SA','MULT3.SA','MYPK3.SA',
           'NTCO3.SA','ODPV3.SA','OIBR4.SA','PCAR3.SA','PETR4.SA','POMO4.SA','PRIO3.SA','PSSA3.SA','PTBL3.SA','QUAL3.SA','RADL3.SA',
           'RAIL3.SA','RAPT4.SA','RENT3.SA','RLOG3.SA','ROMI3.SA','RSID3.SA','SANB11.SA','SAPR4.SA','SBSP3.SA','SEER3.SA','SHOW3.SA',
           'SLCE3.SA','SMLS3.SA','SMTO3.SA','STBP3.SA','SULA11.SA','SUZB3.SA','TAEE11.SA','TCSA3.SA','TEND3.SA','TGMA3.SA','TIMS3.SA',
           'TOTS3.SA','TPIS3.SA','TRPL4.SA','TUPY3.SA','UGPA3.SA','UNIP6.SA','USIM5.SA','VALE3.SA','VIVT3.SA','VLID3.SA','VVAR3.SA',
           'WEGE3.SA','WIZS3.SA','YDUQ3.SA']

df = yf.download(tickers,start="2008-01-01")

prices = df['Adj Close']

prices.index = pd.to_datetime(prices.index)

mtl_ret = prices.pct_change().resample('M').agg(lambda x: (x+1).prod() -1 )

"""Parametros da Formação da carteira"""

formation = dt.datetime(2019,2,28)
tamanho = [5,6,7,8,9,10,11,12,13,14,15,16] #numero de ativos a serem selecionados 6,7,8,9,10,11,12,13,14,15,
hold = [1,2,3,4,6,12,18,24] #numero de meses que o ativo permanece na carteira 2,3,4,6,12,18,
tempo = [1,2,3,4,6,12,18,24] #numero de meses anteriores a formacao da carteira

def retorno(formation, tamanho, hold,tempo):
    selecao = mtl_ret.loc[formation - MonthEnd(tempo+1)]
    selecao.name="mtl_ret"
    selecao = pd.DataFrame(selecao)
    losers = selecao.mtl_ret.nsmallest(tamanho).index
    loserret = ((mtl_ret.loc[formation + MonthEnd(1): formation + MonthEnd(hold), mtl_ret.columns.isin(losers)]+1).cumprod().mean(axis=1)[-1])
    winners = selecao.mtl_ret.nlargest(tamanho).index
    winnerret = ((mtl_ret.loc[formation + MonthEnd(1): formation + MonthEnd(hold), mtl_ret.columns.isin(winners)]+1).cumprod().mean(axis=1)[-1])

    return loserret, winnerret

def bencretorno(formation,hold):
    selecao = bench_ret.loc[formation - MonthEnd(1)]
    selecao.name="mtl_ret"
    selecao = pd.DataFrame(selecao)
    ret = ((bench_ret.loc[formation + MonthEnd(1): formation + MonthEnd(hold)]+1).cumprod()).iloc[-1]

    return ret

df2 = yf.download(tickers=['^BVSP', '^GSPC', 'BRL=X'],start="2008-01-01")['Adj Close']

bench_ret = df2.pct_change().resample('M').agg(lambda x: (x+1).prod() -1)
bench_ret.index = pd.to_datetime(bench_ret.index)

bench_ret.columns = ['DOLAR', 'IBOV', 'SP500']

retwinn = []
retlos = []
dates = []
tam = []
hol = []
tem = []

dolret = []
ibovret = []
spret = []

for i in mtl_ret.index[max(tempo)+1:-1]: 

    for j in hold:     
                    
        for k in tamanho:
        
            for l in tempo:
               
                dates.append(i)
                hol.append(j)
                tam.append(k)
                tem.append(l)
                retlos.append(retorno(i,k,j,l)[0])
                retwinn.append(retorno(i,k,j,l)[1])
                
                dolret.append(bencretorno(i,j)[0])
                ibovret.append(bencretorno(i,j)[1])                        
                spret.append(bencretorno(i,j)[2])

frame = pd.DataFrame({'dates':dates, 'numero_de_ativos':tam, 'tempo_hold':hol, 'tempo_formacao':tem, 'Vencedores':retwinn, 'Perdedores':retlos, 'Dolar':dolret, 'Ibov':ibovret, 'SP500':spret})

frame = frame.set_index('dates')

frame

frame.describe()

f = frame.groupby(['dates','tempo_hold','numero_de_ativos']).mean()

f = round(f,3)
f = f.drop(columns="tempo_formacao")

#f.to_excel('backtest.xlsx')

f

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *