Ir para o conteúdo
  • FORMAS DE POUPAR

  • Programação e análise dos mercados financeiros


    Recommended Posts

    Post 1.2 - For Loop (opcional para iniciados)

    Entretanto saquei os dados do IQQ0 do investing.com. Podem saca-los vocês ou ir buscar à pasta partilhada! 

    Este post é opcional para iniciados porque são temas um pouco mais avançados e/ou que podem não interessar no curto prazo. Mas aconselho a voltarem aqui quando tiverem oportunidade e aprender a fazer o for loop, que é na minha opinião das coisas mais importantes em programação para automatizarem uma tarefa.

    Os ficheiros devem estar todos na pasta onde estão a programar e devem ter o nome do estilo "ticker.csv"

    image.png.e88505069fe18effb3cb5f0d999f7839.png

    image.png.f8ac7ac31aec30be651fa5cc84ac16bc.png

    image.png.db563b2fd2363eda1cb18eb9b3cf6866.png

    image.png.4e8ef530784c51d8b43e0117c3f5b402.png

    image.png.e365c75a38ca6528abb86ad79c14a6d4.png

    Podem ver o ficheiro completo aqui: Link

    Código limpo:

    # Import libraries
    import pandas as pd
    import cufflinks as cf
    
    import PortfolioAnalyser as pa
    
    # Set cufflinks offline
    cf.go_offline()
    
    tickers = ['IWDA', 'IS3Q', 'IQQ0']
    
    ETFs = pd.DataFrame()
    
    # Para cada valor na variável tickers
    for ticker in tickers:
        # Ler o ficheiro .csv correspondente, ler as datas e seleccionar só a coluna de preços
        ETF = pd.read_csv(ticker + '.csv', index_col='Date', parse_dates=True)[['Price']]
        # Dar o nome do ticker à coluna para depois podermos distinguir na DataFrame
        ETF.columns = [ticker]
        # Usar a função merge_time_series usando a opção outer (quando são muitos ETFs aconselho
        # sempre a função outer para não ir "perdendo" demasiadas cotações simplesmente poque há
        # um ETF sem cotação nesse dia). Por outro lado a função dropna() força a começarem e 
        # acabarem no mesmo dia (para serem efectivamente comparáveis)
        ETFs = pa.merge_time_series(ETFs, ETF, how='outer').dropna()
    
    # Ordenar as datas para que sejam ascendentes
    ETFs = ETFs.sort_index(ascending=True)
    
    # Fazer o growth index
    ETFs_gi = pa.compute_growth_index(ETFs)
        
    ETFs_gi
    
    ### Devem usar nova célula ###
    ETFs_gi.iplot(dimensions=pa.dimensions)
      
    ### Devem usar nova célula ###
    pa.compute_performance_table(ETFs_gi)

     

     

    Editado por Virtua
    Link para a publicação
    Partilhar noutros sites
    Rick Lusitano
    há 21 horas, CDCD disse:

    - cortar datas, usando "a" para a variável da dataframe e "Date" para a coluna da data:

    a[a["Date"] >= "2000-01-01"] # desde...

    a[a["Date"] <= "2010-01-01"] # até

    a[ (a["Date"]>="2000-01-01") & (a["Date"]<= "2010-01-01") ] # entre

    ler de xls:

    - usa pd.read_excel() em vez de pd.read_csv(), mas requer uma nova biblioteca para ler excel, e.g. pip install xlrd

     

    Obrigado pelas dicas.

    Consegue-se ler ficheiros XLS/XLSX sem instalar essa library. Usei o pandas.

    Link para a publicação
    Partilhar noutros sites
    Rick Lusitano
    há 12 minutos, Virtua disse:

    Já deve vir no anaconda. O anaconda trás uma centena de libraries para aí...

    Há alguma forma de ver quais as libraries instaladas, através do Jupyter Notebook?

    Link para a publicação
    Partilhar noutros sites

    Post 1.3 - Função (opcional para iniciados)

    Outro post opcional para iniciados mas como fiz a função agora optei por mostrar como se fazem funções. Quem não perceber tudo, não faz mal. Mas seria bom ficarem com a ideia por detrás. Podem e devem usar a função criada para ler ficheiros do investing.com sem compreenderem o que está por detrás. Está já na biblioteca e quem quiser usar não tem de copiar nenhum código. Apenas escrever pa.read_csv_investing(tickers), sendo os tickers os ficheiros que desejam importar dentro de uma lista (ver exemplo no fim do post).

    image.png.d5422267d6de5366cbaeb50d7725249a.png

    image.png.6288f1ed2fa10f21961acef94ead5b47.png

    image.png.e27bc7354c382bb0a5158e754e9ebdbb.png

    image.png.9da682b070e940b5f8236a29324a3d08.png

    image.png.b74cddd11078bf60185ef909bc878a5c.png

    image.png.e35e87b0d0c8c1072e69d223d27d1e6f.png

    image.png.d107fb52dcf9b9fcc4658c160d1db8d2.png

    image.png.72b717022bf649ad3cd5ad08edb766b1.png

    image.png.4dec7db902e5af79031b9a15cd89e402.png

    image.png.ccfbddd339307a4a3034b972ebb5e9dc.png

    image.png.1fcbe08cf0005293e299cfb0d7435099.png

    image.png.3d2e28e87c21ed7d6379a6b7fe67fb14.png

    image.png.e0be7cb666527fc4af29789e857eb198.png

    image.png.97669b31b5f2e764e0530d7ab2da71df.png

    image.png.953b08de2abc326f1bf1ffc0e186c016.png

    Ficheiro completo aqui: Link

    Código limpo:

    # Import libraries
    import pandas as pd
    import cufflinks as cf
    
    import PortfolioAnalyser as pa
    
    # Set cufflinks offline
    cf.go_offline()
    
    # Criação da função para ler múltiplos ficheiros do investing.com. Inclui opção de começo e fim da análise.
    def read_csv_investing(tickers, start='1900-01-01', stop='2100-01-01'):
        ETFs = pd.DataFrame()
    
        # Para cada valor na variável tickers
        for ticker in tickers:
            # Ler o ficheiro .csv correspondente, ler as datas e seleccionar só a coluna de preços
            ETF = pd.read_csv(ticker + '.csv', index_col='Date', parse_dates=True)[['Price']]
            # Dar o nome do ticker à coluna para depois podermos distinguir na DataFrame
            ETF.columns = [ticker]
            # Usar a função merge_time_series usando a opção outer (quando são muitos ETFs aconselho
            # sempre a função outer para não ir "perdendo" demasiadas cotações simplesmente porque há
            # um ETF sem cotação nesse dia). Por outro lado a função dropna() força a começarem e 
            # acabarem no mesmo dia (para serem efectivamente comparáveis)
            ETFs = pa.merge_time_series(ETFs, ETF, how='outer').dropna()
    
        # Ordenar as datas para que sejam ascendentes
        ETFs = ETFs.sort_index(ascending=True)
        
        # Acrescentar função de "cortar" a série temporal que por defeito está desde 1900 até 2100, 
        # o que basicamente é um "atalho" para dizer que não pretendo cortar pois esse periodo deverão
        # apanhar quaisquer datas para as quais há ETFs do investing
        ETFs = ETFs[start:stop]
    
        # Fazer o growth index
        ETFs_gi = pa.compute_growth_index(ETFs)
    
        return ETFs_gi
          
    # Gráfico comparativo com start e stop (primeiro trimestre de 2020)
    ETFs_2020Q1 = read_csv_investing(tickers=['IWDA', 'IS3Q', 'IQQ0'], start='2019-12-30', stop='2020-03-31')
    ETFs_2020Q1.iplot(dimensions=pa.dimensions)

    E com isto acabo as análises aos ETFs alternativos ao MSCI World/IWDA.

    A seguir devemos fazer uma comparação entre índices MSCI. Os ficheiros têm com dados mensais (o que é bom para aprender a usar dados com outras frequências). Iremos fazer uma comparação rápida, um rácio entre os activos para melhor ver as alturas de under ou overperformance e finalmente um gráfico de correlação rolante (que me foi pedido).

     

    Editado por Virtua
    Link para a publicação
    Partilhar noutros sites

    O primeiro post sofreu um mega update ao índice com um roadmap do que pretendo fazer. Podem ir dar uma espreitadela. Estejam à vontade para sugerir dicas e coisas que gostariam de ver feitas (esta pergunta NÃO se estende ao @Rick Lusitano senão só saio daqui em 2030 ?)

    Editado por Virtua
    • Gosto 1
    Link para a publicação
    Partilhar noutros sites
    Rick Lusitano
    há 11 minutos, Virtua disse:

    O primeiro post sofreu um mega update ao índice com um roadmap do que pretendo fazer. Podem ir dar uma espreitadela. Estejam à vontade para sugerir dicas e coisas que gostariam de ver feitas (esta pergunta NÃO se estende ao @Rick Lusitano senão só saio daqui em 2030 ?)

    :D

    Link para a publicação
    Partilhar noutros sites

    Post 2.0 - Análise rápida comparativa a índices MSCI (Dados mensais/Growth Index/Drawdowns/Performance Table)

    AVISO: A biblioteca PortfolioAnalyser agora chama-se PortfolioLab. Já há muito tempo que queria fazer esta alteração e suponho que mais vale fazer a alteração cedo para que não tenha depois de alterar o código de 50 posts. A PortfolioAnalyser ainda se encontra na pasta partilhada e funciona normalmente. Só depois de alterar o código é que a vou substitui completamente. Mas daqui para a frente usamos a Portfolio Lab.

      image.thumb.png.738da646c9c431b2d53e969e5515aefe.png

    image.png.75a2cc4dd28dfbccfcfe4d0c5e263b30.png

    image.png.c63bebf1c654bc700dffbea96506a6ea.png

    image.png.5c1e6954bc3928bf65377b2583a95826.png

    image.png.6c5e034821462f946676d23909266bc1.png

    Código Limpo:

    # Import libraries
    import PortfolioLab as pl
    import cufflinks as cf
    import pandas as pd
    
    # Set cufflinks offline
    cf.go_offline()
    
    ### Nova célula ###
    MSCIs = pl.read_xlsl_MSCI(tickers=['MSCI_World_EUR', 'MSCI_EM_EUR'], 
                              nomes=['World €', 'EM €'])
    
    ### Nova célula ###
    MSCIs.iplot(dimensions=pl.dimensions,
                title= 'MSCI World € vs MSCI EM €',
                yTitle='Valorização por cada 100 €uros investidos')
    
    ### Nova célula ###
    DD = pl.compute_drawdowns(MSCIs)
    DD.iplot(dimensions=pl.dimensions)
    
    ### Nova célula ###
    # Compute Performance table
    pl.compute_performance_table(MSCIs, freq='months')

     

    Editado por Virtua
    Link para a publicação
    Partilhar noutros sites

    Olha VG, o meu sonho húmido (Dados de AF, AF com previsões, modelos): (checka o vídeo)

    https://finbox.com/

    É um serviço Freemium. Dá para Stocks, ETFs, ...

    Podes espreitar as funcionalidades aqui:

    https://finbox.com/ideas

     

    Editado por Rick Lusitano
    Link para a publicação
    Partilhar noutros sites
    há 2 horas, Rick Lusitano disse:

    Olha VG, o meu sonho húmido (Dados de AF, AF com previsões, modelos): (checka o vídeo)

    https://finbox.com/

    É um serviço Freemium. Dá para Stocks, ETFs, ...

    Podes espreitar as funcionalidades aqui:

    https://finbox.com/ideas

    Finalmente vejo algo de jeito e bonito. Até está em conta tendo em consideração a quantidade e qualidade da informação.

    Relativamente simples de fazer. Diria que dada a info fazias isso fácil via programação. Mas até é mais barato fazer por eles. O que me dá trabalho de obter é a info. Tudo o resto se faz simples ? (incluindo os dashboards deles, sem tirar crédito a ,como disse, das poucas coisas que vi realmente bonitas. Os dashboards estão muito bons mesmo!!)

    Editado por Virtua
    Link para a publicação
    Partilhar noutros sites

    Post 2.1

    Tabela de performance anual (anos civis)

    image.png.c81b8612378de7e6a84f76fccf3d2bcf.png

    image.png.5acb06340c42f447735b89eaefd09298.png

    image.png.acc73a2269af85fee19dee09aacfbbe8.png

    image.png.f66008729b23d133a0992f277d731b55.png

    image.png.8a5421f7f7cc8c2249b101d112b178c0.png

    Código completo:

    # Import libraries
    import PortfolioLab as pl
    import cufflinks as cf
    import pandas as pd
    
    # Set cufflinks offline
    cf.go_offline()
    
    ### Nova célula ###
    MSCIs = pl.read_xlsl_MSCI(tickers=['MSCI_World_EUR', 'MSCI_EM_EUR'], 
                              nomes=['World €', 'EM €'])
    
    ### Nova célula ###
    MSCIs.iplot(dimensions=pl.dimensions,
                title= 'MSCI World € vs MSCI EM €',
                yTitle='Valorização por cada 100 €uros investidos')
    
    ### Nova célula ###
    DD = pl.compute_drawdowns(MSCIs)
    DD.iplot(dimensions=pl.dimensions)
    
    ### Nova célula ###
    # Compute Performance table
    pl.compute_performance_table(MSCIs, freq='months')
    
    ### Nova célula ###
    # Tabela de performance por ano civil (até 2008)
    returns_until_2008 = pl.compute_yearly_returns(MSCIs, end='2008', title='Yearly Returns from 1998 to 2008')
    returns_until_2008
    
    ### Nova célula ###
    # Tabela de performance por ano civil (desde 2009)
    returns_after_2008 = pl.compute_yearly_returns(MSCIs, start='2009', title='Yearly Returns since 2009')
    returns_after_2008
    
    ### Nova célula ###
    # Heatmap de performance por ano civil (até 2008)
    returns_until_2008 = pl.compute_yearly_returns(MSCIs, style='chart', end='2008', title='Yearly Returns from 1998 to 2008')
    returns_until_2008;
    
    ### Nova célula ###
    # Heatmap de performance por ano civil (desde 2009)
    returns_after_2008 = pl.compute_yearly_returns(MSCIs, style='chart', start='2009', title='Yearly Returns since 2009')
    returns_after_2008;
    
    ### Nova célula ###
    # Tabela de performance colorida (até 2008)
    pl.compute_yearly_returns(MSCIs, end='2008', title='Yearly Returns from 1998 to 2008', color=True)
    
    ### Nova célula ###
    # Tabela de performance colorida (desde 2009)
    returns_after_2008 = pl.compute_yearly_returns(MSCIs, start='2009', title='Yearly Returns since 2009', color=True)
    returns_after_2008
    
    ### Nova célula ###
    # Opção String para fazer um ficheiro .CSV com o simbolo de % já embutido
    returns_after_2008 = pl.compute_yearly_returns(MSCIs, start='2009', style='string')
    returns_after_2008

     

    Editado por Virtua
    Link para a publicação
    Partilhar noutros sites

    image.png.34d9520f523b47ba3ada2275452b1546.png

    image.png.07ef1b573639c7707eef644f01f73f83.png

    image.png.11f9200f42e298c8defb0db1fb59326e.png

    image.png.60a6250a400ae14091ff4c7486732065.png

    image.png.0566f586b0cc1b21b170cd192bcba86d.png

    image.png.6aa87e6e2545310fb9f963eff2d32525.png

    image.png.ed109fd81e5a33afaa60c0aa5a90c47f.png

    image.png.af09f4bc6bdb76a34733062bf5a2b503.png

    Código completo:

    # Import libraries
    import pandas as pd
    import cufflinks as cf
    
    import PortfolioLab as pl
    
    # Set cufflinks offline
    cf.go_offline()
    
    # Pesquisa dos ETFs por ticker
    pl.search_investing_etf(tickers=['IWDA', 'IS3Q'], visual='jupyter')
    
    # Pesquisa dos ETFs por isin
    pl.search_investing_etf(isins=['IE00B4L5Y983', 'IE00BP3QZ601'], visual='jupyter')
    
    # Fazer o download das cotações
    names = ['iShares Core MSCI World UCITS', 'iShares MSCI World Quality Factor UCITS']
    countries = ['netherlands', 'germany']
    colnames = ['IWDA', 'IS3Q']
    
    etfs = pl.get_quotes_investing_etf(names=names, countries=countries, colnames=colnames)
    
    # Fazer o download das cotações com growth index
    names = ['iShares Core MSCI World UCITS', 'iShares MSCI World Quality Factor UCITS']
    countries = ['netherlands', 'germany']
    colnames = ['IWDA', 'IS3Q']
    
    
    etfs = pl.get_quotes_investing_etf(names=names, countries=countries, colnames=colnames,
                                      begin='1990-01-01', end='2025-01-01',
                                      growth_index=True)
    
    # Fazer o download das cotações sem qualquer tratamento de dados
    etfs = pl.get_quotes_investing_etf(names=names, countries=countries, colnames=colnames,
                                      begin='1990-01-01', end='2025-01-01',
                                      merge='outer')
    
    etfs
    
    # Gravar em excel
    etfs.to_excel('etfs.xlsx')
    etfs.iplot(dimensions=pl.dimensions)

    NOTAS IMPORTANTES:

    1. O Investing usa apenas dados de cotação, não ajusta a distribuições. Por isso só podem comparar ETFs que são ACC. Os ETFs americanos são de distribuição e por isso não é recomendável que usem o Investing para análises. Mais para a frente vamos aprender a usar o API da yahoo finance e podemos ir buscar os ETFs americanos à Yahoo e os Europeus ao Investing, fundir e comparar.

    2. Agora para actualizar a análise é apenas necessário correr o notebook em Run > Run All Cells e ele vai automaticamente buscar as cotações mais recentes ao investing.com

    Editado por Virtua
    • Gosto 1
    Link para a publicação
    Partilhar noutros sites
    • 1 year later...

    Join the conversation

    You are posting as a guest. If you have an account, sign in now to post with your account.
    Note: Your post will require moderator approval before it will be visible.

    Visitante
    Responder a este tópico

    ×   Colou conteúdo com formatação.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Foi criada uma pré-visualização automática a partir da ligação que colocou.   Mostrar apenas como ligação

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    ×
    ×
    • Criar Novo...