Jump to content

Recommended Posts

Postado

Em meio a um devaneio, solicitei a IA que tentasse analisar os ativos que representassem 50% da carteira de um ETF para obter a media ponderada de alguns dados de valuation, como são muitos ativos ela bugou, mas me forneceu o código em Python que permitiria fazer a análise, testei e deu certo, os dados obtidos realmente batem com os contidos no site. 

Os dados solicitados foram: 

  • ROE 
  • ROIC 
  • ROA 
  • DIV LIQ/EBITDA 
  • P/EBIT
  • P/EBITDA
  • LIQUIDEZ CORRENTE 
  • LIQUIDEZ SECA 
  • LIQUIDEZ IMEDIATA
  • PAS/ATIV

Caso alguém tenha interesse aqui vai o passo a passo

  1. Baixar as planilhas das holdings do ETF no site do gestor, abrir o arquivo no excel e deixar apenas as colunas de ticker e Weight, salvar o arquivo como no formato CSV
  2. Acessar o colab.research.google.com
  3. Abrir um novo notebook
  4. Digitar na caixa de texto do código "!pip install yfinance pandas" e apertar o play do lado esquerdo 
  5. Nos ícones a esquerda o penúltimo item (ícone com formato de pasta) faça o upload do arquivo CSV
  6. Clique na caixa do primero comando e logo acima dela ele te dará a opção "+código"clique nela e insira esse prompt"

    import yfinance as yf
    import pandas as pd
    import numpy as np

    df_top_50 = pd.read_csv('Nome do arquivo upado.csv', sep=';')
    print("Colunas do DataFrame após leitura do CSV:")
    print(df_top_50.columns)
    # Rename the 'Weight' column to 'Peso' to match expectations
    df_top_50 = df_top_50.rename(columns={'Weight': 'Peso'}) # Corrected from 'Weight (%)' to 'Weight'

    # Clean and convert 'Peso' column to numeric, handling problematic characters like '-'
    df_top_50['Peso'] = df_top_50['Peso'].str.replace(',', '.').replace('-', np.nan).astype(float)

    # Filter out invalid or problematic tickers that cause yfinance errors
    df_top_50 = df_top_50[df_top_50['Ticker'].notna()].copy() # Remove rows with NaN Ticker
    df_top_50 = df_top_50[df_top_50['Ticker'].str.strip() != ''].copy() # Remove empty or whitespace-only Tickers
    df_top_50 = df_top_50[df_top_50['Ticker'] != '-'].copy() # Remove single hyphen Tickers
    # Explicitly filter out currency symbols and other known non-stock tickers
    problematic_symbols = ['_CURRENCYEUR', '_CURRENCYGBP', '_CURRENCYCHF', '_CURRENCYDKK', '_CURRENCYUSD', '_CURRENCYNOK', '_CURRENCYSEK', '___ADI2VD0K2', '2330', '5930', '700', '660', '9988'] # Added common problematic entries from EIMI, if they appear as tickers
    df_top_50 = df_top_50[~df_top_50['Ticker'].isin(problematic_symbols)].copy()

    dados_empresas = []

    print("Extraindo os dados financeiros atuais... Isso será bem mais rápido.\n")

    for index, row in df_top_50.iterrows():
        ticker = row['Ticker']
        peso = row['Peso'] # This line was the error. We needed the correct column name.

        try:
            acao = yf.Ticker(ticker)
            info = acao.info

            # Check if info is empty, which indicates a problematic ticker for yfinance
            if not info or len(info) <= 1: # len(info) <= 1 often means only 'trailingPegRatio' or similar, indicating no real data
                print(f"Aviso: Não foi possível obter dados para o ticker {ticker}. Pulando este ativo.")
                continue

            bs = acao.balance_sheet
            inc = acao.financials

            def dado_recente(df, nome_linha):
                try: return df.loc[nome_linha].iloc[0]
                except (KeyError, IndexError): return np.nan

            roe = info.get('returnOnEquity', np.nan)
            roa = info.get('returnOnAssets', np.nan)
            liquidez_corrente = info.get('currentRatio', np.nan)
            liquidez_seca = info.get('quickRatio', np.nan)
            ebitda = info.get('ebitda', np.nan)
            market_cap = info.get('marketCap', np.nan)
            caixa_total = info.get('totalCash', np.nan)
            divida_total = info.get('totalDebt', np.nan)
            ebit = dado_recente(inc, 'EBIT')
            capital_investido = dado_recente(bs, 'Invested Capital')
            ativos_totais = dado_recente(bs, 'Total Assets')
            passivos_totais = dado_recente(bs, 'Total Liabilities Net Minority Interest')
            passivo_circulante = dado_recente(bs, 'Current Liabilities')

            roic = (ebit / capital_investido) if (pd.notna(ebit) and pd.notna(capital_investido) and capital_investido != 0) else np.nan
            divida_liq_ebitda = ((divida_total - caixa_total) / ebitda) if (pd.notna(divida_total) and pd.notna(caixa_total) and pd.notna(ebitda) and ebitda != 0) else np.nan
            p_ebit = (market_cap / ebit) if (pd.notna(market_cap) and pd.notna(ebit) and ebit != 0) else np.nan
            p_ebitda = (market_cap / ebitda) if (pd.notna(market_cap) and pd.notna(ebitda) and ebitda != 0) else np.nan
            passivos_ativos = (passivos_totais / ativos_totais) if (pd.notna(passivos_totais) and pd.notna(ativos_totais) and ativos_totais != 0) else np.nan
            liquidez_imediata = (caixa_total / passivo_circulante) if (pd.notna(caixa_total) and pd.notna(passivo_circulante) and passivo_circulante != 0) else np.nan

            dados = {
                'Ticker': ticker,
                'Peso': peso,
                'ROE Atual (%)': roe * 100 if pd.notna(roe) else np.nan,
                'ROA Atual (%)': roa * 100 if pd.notna(roa) else np.nan,
                'ROIC Atual (%)': roic * 100 if pd.notna(roic) else np.nan,
                'Dívida Líq/EBITDA': divida_liq_ebitda,
                'P/EBIT': p_ebit,
                'P/EBITDA': p_ebitda,
                'Liquidez Corrente': liquidez_corrente,
                'Liquidez Seca': liquidez_seca,
                'Liquidez Imediata': liquidez_imediata,
                'Passivos/Ativos (%)': passivos_ativos * 100 if pd.notna(passivos_ativos) else np.nan
            }

            dados_empresas.append(dados)

        except Exception as e:
            print(f"Aviso: Erro ao processar o ticker {ticker}: {e}. Pulando este ativo.")
            continue

    # Ensure df_resultados is created even if dados_empresas is empty
    df_resultados = pd.DataFrame(dados_empresas)

    print("--- Dados Extraídos por Empresa ---")
    print(df_resultados.round(2).to_string(index=False))
    print("\n" + "-"*80 + "\n")
    def media_ponderada(valores, pesos):
        mascara = valores.notna() & pesos.notna()
        if not mascara.any(): return np.nan
        return np.average(valores[mascara], weights=pesos[mascara])

    print("---" * 10 + "\nMÉDIA PONDERADA ATUAL DO FUNDO\n" + "---" * 10)
    colunas_para_media = [c for c in df_resultados.columns if c not in ['Ticker', 'Peso']]

    if not df_resultados.empty:
        for coluna in colunas_para_media:
            resultado = media_ponderada(df_resultados[coluna], df_resultados['Peso'])
            if "(%)" in coluna:
                print(f"{coluna}: {resultado:.2f}%")
            else:
                print(f"{coluna}: {resultado:.2f}x")
    else:
        print("Nenhum dado financeiro foi extraído após a filtragem de tickers.")

  7. pedir para rodar o código, nesse passo alguns erros podem surgir e o próprio gemini oferece soluções, peça para as executar e ele tentar rodar novamente

  8. Após isso ele ira buscar os dados, ignorar o que não encontrou no site e te dar as medias

Deixei abaixo o resultado que consegui para o SPYL versão irlandesa do SPY

Captura de Tela 2026-03-25 às 15.01.05.png

Captura de Tela 2026-03-25 às 15.00.47.png

Postado
15 minutes ago, Rodolfo Cruz Losqui disse:

Em meio a um devaneio, solicitei a IA que tentasse analisar os ativos que representassem 50% da carteira de um ETF para obter a media ponderada de alguns dados de valuation, como são muitos ativos ela bugou, mas me forneceu o código em Python que permitiria fazer a análise, testei e deu certo, os dados obtidos realmente batem com os contidos no site. 

Os dados solicitados foram: 

  • ROE 
  • ROIC 
  • ROA 
  • DIV LIQ/EBITDA 
  • P/EBIT
  • P/EBITDA
  • LIQUIDEZ CORRENTE 
  • LIQUIDEZ SECA 
  • LIQUIDEZ IMEDIATA
  • PAS/ATIV

Caso alguém tenha interesse aqui vai o passo a passo

  1. Baixar as planilhas das holdings do ETF no site do gestor, abrir o arquivo no excel e deixar apenas as colunas de ticker e Weight, salvar o arquivo como no formato CSV
  2. Acessar o colab.research.google.com
  3. Abrir um novo notebook
  4. Digitar na caixa de texto do código "!pip install yfinance pandas" e apertar o play do lado esquerdo 
  5. Nos ícones a esquerda o penúltimo item (ícone com formato de pasta) faça o upload do arquivo CSV
  6. Clique na caixa do primero comando e logo acima dela ele te dará a opção "+código"clique nela e insira esse prompt"

    import yfinance as yf
    import pandas as pd
    import numpy as np

    df_top_50 = pd.read_csv('Nome do arquivo upado.csv', sep=';')
    print("Colunas do DataFrame após leitura do CSV:")
    print(df_top_50.columns)
    # Rename the 'Weight' column to 'Peso' to match expectations
    df_top_50 = df_top_50.rename(columns={'Weight': 'Peso'}) # Corrected from 'Weight (%)' to 'Weight'

    # Clean and convert 'Peso' column to numeric, handling problematic characters like '-'
    df_top_50['Peso'] = df_top_50['Peso'].str.replace(',', '.').replace('-', np.nan).astype(float)

    # Filter out invalid or problematic tickers that cause yfinance errors
    df_top_50 = df_top_50[df_top_50['Ticker'].notna()].copy() # Remove rows with NaN Ticker
    df_top_50 = df_top_50[df_top_50['Ticker'].str.strip() != ''].copy() # Remove empty or whitespace-only Tickers
    df_top_50 = df_top_50[df_top_50['Ticker'] != '-'].copy() # Remove single hyphen Tickers
    # Explicitly filter out currency symbols and other known non-stock tickers
    problematic_symbols = ['_CURRENCYEUR', '_CURRENCYGBP', '_CURRENCYCHF', '_CURRENCYDKK', '_CURRENCYUSD', '_CURRENCYNOK', '_CURRENCYSEK', '___ADI2VD0K2', '2330', '5930', '700', '660', '9988'] # Added common problematic entries from EIMI, if they appear as tickers
    df_top_50 = df_top_50[~df_top_50['Ticker'].isin(problematic_symbols)].copy()

    dados_empresas = []

    print("Extraindo os dados financeiros atuais... Isso será bem mais rápido.\n")

    for index, row in df_top_50.iterrows():
        ticker = row['Ticker']
        peso = row['Peso'] # This line was the error. We needed the correct column name.

        try:
            acao = yf.Ticker(ticker)
            info = acao.info

            # Check if info is empty, which indicates a problematic ticker for yfinance
            if not info or len(info) <= 1: # len(info) <= 1 often means only 'trailingPegRatio' or similar, indicating no real data
                print(f"Aviso: Não foi possível obter dados para o ticker {ticker}. Pulando este ativo.")
                continue

            bs = acao.balance_sheet
            inc = acao.financials

            def dado_recente(df, nome_linha):
                try: return df.loc[nome_linha].iloc[0]
                except (KeyError, IndexError): return np.nan

            roe = info.get('returnOnEquity', np.nan)
            roa = info.get('returnOnAssets', np.nan)
            liquidez_corrente = info.get('currentRatio', np.nan)
            liquidez_seca = info.get('quickRatio', np.nan)
            ebitda = info.get('ebitda', np.nan)
            market_cap = info.get('marketCap', np.nan)
            caixa_total = info.get('totalCash', np.nan)
            divida_total = info.get('totalDebt', np.nan)
            ebit = dado_recente(inc, 'EBIT')
            capital_investido = dado_recente(bs, 'Invested Capital')
            ativos_totais = dado_recente(bs, 'Total Assets')
            passivos_totais = dado_recente(bs, 'Total Liabilities Net Minority Interest')
            passivo_circulante = dado_recente(bs, 'Current Liabilities')

            roic = (ebit / capital_investido) if (pd.notna(ebit) and pd.notna(capital_investido) and capital_investido != 0) else np.nan
            divida_liq_ebitda = ((divida_total - caixa_total) / ebitda) if (pd.notna(divida_total) and pd.notna(caixa_total) and pd.notna(ebitda) and ebitda != 0) else np.nan
            p_ebit = (market_cap / ebit) if (pd.notna(market_cap) and pd.notna(ebit) and ebit != 0) else np.nan
            p_ebitda = (market_cap / ebitda) if (pd.notna(market_cap) and pd.notna(ebitda) and ebitda != 0) else np.nan
            passivos_ativos = (passivos_totais / ativos_totais) if (pd.notna(passivos_totais) and pd.notna(ativos_totais) and ativos_totais != 0) else np.nan
            liquidez_imediata = (caixa_total / passivo_circulante) if (pd.notna(caixa_total) and pd.notna(passivo_circulante) and passivo_circulante != 0) else np.nan

            dados = {
                'Ticker': ticker,
                'Peso': peso,
                'ROE Atual (%)': roe * 100 if pd.notna(roe) else np.nan,
                'ROA Atual (%)': roa * 100 if pd.notna(roa) else np.nan,
                'ROIC Atual (%)': roic * 100 if pd.notna(roic) else np.nan,
                'Dívida Líq/EBITDA': divida_liq_ebitda,
                'P/EBIT': p_ebit,
                'P/EBITDA': p_ebitda,
                'Liquidez Corrente': liquidez_corrente,
                'Liquidez Seca': liquidez_seca,
                'Liquidez Imediata': liquidez_imediata,
                'Passivos/Ativos (%)': passivos_ativos * 100 if pd.notna(passivos_ativos) else np.nan
            }

            dados_empresas.append(dados)

        except Exception as e:
            print(f"Aviso: Erro ao processar o ticker {ticker}: {e}. Pulando este ativo.")
            continue

    # Ensure df_resultados is created even if dados_empresas is empty
    df_resultados = pd.DataFrame(dados_empresas)

    print("--- Dados Extraídos por Empresa ---")
    print(df_resultados.round(2).to_string(index=False))
    print("\n" + "-"*80 + "\n")
    def media_ponderada(valores, pesos):
        mascara = valores.notna() & pesos.notna()
        if not mascara.any(): return np.nan
        return np.average(valores[mascara], weights=pesos[mascara])

    print("---" * 10 + "\nMÉDIA PONDERADA ATUAL DO FUNDO\n" + "---" * 10)
    colunas_para_media = [c for c in df_resultados.columns if c not in ['Ticker', 'Peso']]

    if not df_resultados.empty:
        for coluna in colunas_para_media:
            resultado = media_ponderada(df_resultados[coluna], df_resultados['Peso'])
            if "(%)" in coluna:
                print(f"{coluna}: {resultado:.2f}%")
            else:
                print(f"{coluna}: {resultado:.2f}x")
    else:
        print("Nenhum dado financeiro foi extraído após a filtragem de tickers.")

  7. pedir para rodar o código, nesse passo alguns erros podem surgir e o próprio gemini oferece soluções, peça para as executar e ele tentar rodar novamente

  8. Após isso ele ira buscar os dados, ignorar o que não encontrou no site e te dar as medias

Deixei abaixo o resultado que consegui para o SPYL versão irlandesa do SPY

Captura de Tela 2026-03-25 às 15.01.05.png

Captura de Tela 2026-03-25 às 15.00.47.png

Meu brother, parabens, mas com todo respeito, Github serve pra isso KKKKKKK

Tu meteu um monte de código em txt aqui po kkkkkkkkkkk

  • Sad 1
Postado (edited)
6 horas atrás, Rodolfo Cruz Losqui disse:

kkkkk Perdão, eu não entendo nada de programação, máximo que programei foi o despertador do celular, não sabia dessa possibilidade e nem como usar😢

É facinho, 1 dia tu aprende, pesquisa ai, Git e Github

A IA tbm faz todos os processos muito bem, é bem documentado e há tutoriais em todo lugar

Se tu quer mexer com código de qualquer natureza, vai te ajudar

Parabens pela curiosidade!

Explicação breve: o Git é uma ferramenta que serve como uma máquina do tempo para o programador, nós conseguimos progredir com o código e ir fazendo "commits" que salvam o estado atual do código, e eu posso voltar para quer commit que eu fiz no passado. Isso permite possibilidades infinitas, e a programação como conhecemos hoje não existira sem essa ferramenta.

O Github é uma das plataformas que você pode guardar e ter acesso aos seus repositórios de código de qualquer lugar do mundo, assim como baixar o código em qualquer dispositivo com internet

É simples, é muito rápido, parece magia. Obrigado ao Criador Linus Torvalds, que é um dos programadores mais impactantes da história da computação. O Git não é nem o principal software que ele fez, já que ele acabou criando também o Sistema Operacional Linux, que permite que toda a infraestrutura de software que temos hoje, seja viável.

Editado por Filipe Andrade Nascimento
Postado
8 minutes ago, Filipe Andrade Nascimento disse:

É facinho, 1 dia tu aprende, pesquisa ai, Git e Github

A IA tbm faz todos os processos muito bem, é bem documentado e há tutoriais em todo lugar

Se tu quer mexer com código de qualquer natureza, vai te ajudar

Parabens pela curiosidade!

Explicação breve: o Git é uma ferramenta que serve como uma máquina do tempo para o programador, nós conseguimos progredir com o código e ir fazendo "commits" que salvam o estado atual do código, e eu posso voltar para quer commit que eu fiz no passado. Isso permite possibilidades infinitas, e a programação como conhecemos hoje não existira sem essa ferramenta.

O Github é uma das plataformas que você pode guardar e ter acesso aos seus repositórios de código de qualquer lugar do mundo, assim como baixar o código em qualquer dispositivo com internet

É simples, é muito rápido, parece magia. Obrigado ao Criador Linus Torvalds, que é um dos programadores mais impactantes da história da computação. O Git não é nem o principal software que ele fez, já que ele acabou criando também o Sistema Operacional Linux, que permite que toda a infraestrutura de software que temos hoje, seja viável.

Dito isso, você me lembrou do dia que um COLEGA DE FACULDADE meu (eu faço CIÊNCIA DA COMPUTAÇÃO) me mandou um código através do DOCS do GOOGLE

Eu tive uma crise de riso lendo a mensagem

  • HAHAHAHA 1
Postado

@Filipe Andrade Nascimento

kkkkkkk Ai não bicho, eu sou da área da saúde, é aceitável não conhecer tanto. 
Mas valeu por ter explicado, acho que consegui usar: https://gist.github.com/RodolfoCL04/c699c1e6b367957a2890b2e6671693c8

Mudei algumas coisas do código tirando cálculos que se baseariam no preço das ações e deixei só os dados operacionais das empresas, agilizou o calculo e me dá as medias dos dados operacionais das empresas que compõe o ETF.

Talvez seja maluquice minha e esteja até fazendo besteira, mas ter essa noção me dá mais segurança pra escolher 

  • Brabo 1

Crie uma conta ou entre para comentar

You need to be a member in order to leave a comment

Crie sua conta

Matricule-se na AUVP e faça parte da maior comunidade de influenciadores do Brasil.

Matricule-se na AUVP

Sign in

Already have an account? Sign in here.

Login
×
×
  • Criar novo...