Para continuar o
artigo sobre os perigos da diversificação excessiva, criaremos ferramentas úteis de seleção de ações. Depois disso, faremos um reequilíbrio simples e adicionaremos as condições exclusivas dos indicadores técnicos, que costumam faltar nos serviços populares. E então compare os retornos sobre ativos individuais e portfólios diferentes.
Em tudo isso, usamos Pandas e minimizamos o número de ciclos. Agrupe a série temporal e desenhe os gráficos. Vamos nos familiarizar com vários índices e seu comportamento. E tudo isso no Jupyter no Python 3.6.
Se você quiser fazer algo bem, faça você mesmo.
Ferdinand Porsche
A ferramenta descrita permitirá selecionar os ativos ideais para o portfólio e excluir as ferramentas impostas pelos consultores. Mas veremos apenas o quadro geral - sem levar em conta a liquidez, o tempo para o recrutamento de posições, as comissões dos corretores e o custo de uma ação. Em geral, com um reequilíbrio mensal ou anual de grandes corretores, haverá custos insignificantes. No entanto, antes de aplicar, a estratégia escolhida ainda deve ser verificada no backtester orientado a eventos, por exemplo, Quantopian (QP), a fim de eliminar possíveis erros.
Por que não imediatamente no QP? Hora. Lá, o teste mais simples dura cerca de 5 minutos. E a solução atual permitirá verificar centenas de estratégias diferentes com condições únicas em um minuto.
Carregamento de dados brutos
Para carregar os dados, siga o método descrito neste
artigo . Eu uso o PostgreSQL para armazenar preços diários, mas agora está cheio de fontes gratuitas a partir das quais você pode criar o DataFrame necessário.
O código para baixar o histórico de preços do banco de dados está disponível no repositório. O link estará no final do artigo.
Estrutura DataFrame
Ao trabalhar com histórico de preços, para um agrupamento conveniente e acesso a todos os dados, a melhor solução é usar um índice múltiplo (MultiIndex) com data e tickers.
df = df.set_index(['dt', 'symbol'], drop=False).sort_index() df.tail(len(df.index.levels[1]) * 2)

Usando um índice múltiplo, podemos acessar facilmente todo o histórico de preços de todos os ativos e agrupar a matriz separadamente por data e ativo. Também podemos obter histórico de preços para um ativo.
Aqui está um exemplo de como você pode agrupar facilmente o histórico por semana, mês e ano. E para mostrar tudo isso nos gráficos das forças do Pandas:

Para exibir corretamente a área com a legenda do gráfico, transferimos o nível do índice com tickers para o segundo nível acima das colunas usando o comando Series (). Unstack (1). Com o DataFrame (), esse número não funcionará, mas a solução está abaixo.
Ao agrupar por períodos padrão, o Pandas usa a data do calendário mais recente do grupo no índice, que geralmente difere das datas reais. Para corrigir isso, atualize o índice.
monthly = df.groupby([pd.Grouper(freq='M', level=0), level_values(1)]).agg(agg_rules) \ .set_index(['dt', 'symbol'], drop=False)
Um exemplo de como obter o histórico de preços de um ativo específico (usamos todas as datas, QQQ ticker e todas as colunas):
monthly.loc[(slice(None), ['QQQ']), :]
Volatilidade mensal de ativos
Agora, podemos observar em algumas linhas no gráfico a variação do preço de cada ativo para o período de interesse para nós. Para fazer isso, obtemos a porcentagem de alterações de preço agrupando o quadro de dados por nível de vários índices com um ticker de ativos.
monthly = df.groupby([pd.Grouper(freq='M', level=0), level_values(1)]).agg( agg_rules).set_index(['dt', 'symbol'], drop=False)

Comparar retornos de ativos
Agora, usaremos o método da janela Series (). Rolling () e exibiremos o retorno dos ativos por um determinado período:
Código Python rolling_prod = lambda x: x.rolling(len(x), min_periods=1).apply(np.prod)

Métodos de rebalanceamento de portfólio
Então chegamos ao mais delicioso. Nos exemplos, examinaremos os resultados do portfólio na alocação de capital para ações predeterminadas entre vários ativos. E também adicione condições únicas sob as quais abandonaremos alguns ativos no momento da distribuição do capital. Se não houver ativos adequados, assumimos que o broker possui capital no cache.
Para usar os métodos do Pandas para reequilibrar, precisamos armazenar os compartilhamentos de distribuição e as condições de reequilíbrio em um DataFrame com dados agrupados. Agora considere as funções de reequilíbrio que passaremos para o método DataFrame (). Apply ():
Em ordem:
- rebalance_simple é a função mais simples que distribuirá a lucratividade de cada ativo em ações.
- rebalance_sma é uma função que distribui capital entre ativos cuja média móvel é 50 dias maior que 200 dias no momento do reequilíbrio.
- rebalance_rsi - uma função que distribui capital entre ativos para os quais o valor do indicador RSI por 100 dias está acima de 50.
- rebalance_custom é a função mais lenta e universal, onde calcularemos os valores dos indicadores a partir do histórico diário de preços de ativos no momento do reequilíbrio. Aqui você pode usar quaisquer condições e dados. Faça o download sempre de fontes externas. Mas você não pode ficar sem um ciclo.
- rebaixamento - função auxiliar, mostrando o rebaixamento máximo no portfólio.
Nas funções de reequilíbrio, precisamos de uma matriz de todos os dados da data por ativos. O método DataFrame (). Apply (), pelo qual calcularemos os resultados dos portfólios, transmitirá uma matriz para nossa função, na qual as colunas se tornarão o índice de linha. E se fizermos um multi-índice, onde os tickers estarão no nível zero, um multi-índice chegará até nós. Podemos expandir esse multi-índice em uma matriz bidimensional e obter os dados do ativo correspondente em cada linha.

Rebalanceamento de portfólio
Agora basta preparar as condições necessárias e fazer um cálculo para cada portfólio do ciclo. Primeiro, calculamos os indicadores no histórico diário de preços:
Agora, agruparemos a história para o período de reequilíbrio desejado, usando os métodos descritos acima. Ao mesmo tempo, tomaremos os valores dos indicadores no início do período para excluir o futuro.
Descrevemos a estrutura das carteiras e indicamos o reequilíbrio desejado. Vamos calcular as carteiras em um ciclo, pois precisamos especificar ações e condições exclusivas:
Desta vez, precisamos fazer um truque com os índices de coluna e linha para obter o multi-índice desejado na função de reequilíbrio. Conseguiremos isso chamando os métodos DataFrame (). Stack (). Unstack ([1, 2]) em sequência. Este código transferirá as colunas para um multi-índice em minúsculas e retornará o multi-índice com tickers e colunas na ordem desejada.
Pastas prontas para gráficos
Agora resta desenhar tudo. Para fazer isso, execute o ciclo do portfólio novamente, que exibe os dados nos gráficos. No final, desenharemos o SPY como uma referência para comparação.
Código Python fig = plt.figure(figsize=(15, 4), facecolor='white') ax_perf = fig.add_subplot(121) ax_dd = fig.add_subplot(122) for p in portfolios: p['performance'].rename(p['name']).plot(ax=ax_perf, legend=True, title='Performance') p['drawdown'].rename(p['name']).plot(ax=ax_dd, legend=True, title='Max drawdown')

Conclusão
O código considerado permite selecionar várias estruturas de portfólio e condições de reequilíbrio. Com sua ajuda, você pode verificar rapidamente se, por exemplo, vale a pena manter ouro (GLD) ou mercados emergentes (EEM) em um portfólio. Tente você mesmo, adicione suas próprias condições para indicadores ou selecione os parâmetros já descritos. (Mas lembre-se do erro do sobrevivente e que o ajuste a dados passados pode não corresponder às expectativas no futuro.) E depois decida em quem você confia no seu portfólio - Python ou consultores financeiros?
Repositório:
rebalance.portfolio