Tutorial de ingestão de dados simples com a API do Yahoo Finance e Python

Os dados estão em toda parte; muitas empresas contam com os dados para tomar todos os tipos de decisões, prever o mercado, planejar o futuro, entender as necessidades dos clientes, redirecionar os esforços e muito mais. Muitas vezes, quando analisamos várias arquiteturas para trabalhar usando dados, sempre existe a parte da ingestão de dados.

Vamos entender o que ela é e criar uma!

Uma das opções para ingerir dados para o sistema é ‘extraindo’. A extração de dados é frequentemente usada quando queremos enriquecer os dados existentes. Fazemos isso extraindo dados em horários predeterminados e conhecidos.

O que significa extrair dados?

Extrair dados significa levar/solicitar dados de um recurso em um horário agendado ou quando disparado.
Para um exemplo de dados de pull agendado, podemos decidir consultar o Twitter a cada 10 segundos. Para um exemplo de gatilho, podemos pensar em outros processos em nosso sistema que chama nosso processo de dados de pull e o ativa com uma solicitação para extrair dados novos/atualizados. Esse termo pode ser mais uma filosofia. A ideia principal é que não há nenhum servidor sempre online que aguarda solicitações.
Esse serviço gera solicitações e extrai os dados necessários. No nosso caso, chamamos uma API para efetuar pull de informações financeiras.

O que usaremos?

Yahoo Finance com ‘Python’:

Hoje, VOCÊ aprende a ler as informações financeiras usando a API do Yahoo Finance (yFinance) e as grava em EventHubs.
Estes são os motivos pelos quais escolhi a API do yFinance:

  • É gratuita
  • É considerada um padrão ouro para as APIs do mercado de ações
  • Fornece acesso a cinco anos de histórico diário de dados de preços de ações do OHLC (Gráfico de Abertura-Alta-Baixa)

Uso o EventHubs do Azure para armazenar os dados porque é um serviço de publicação-assinatura altamente escalonável que pode ingerir milhões de eventos por segundo e transmiti-los para vários consumidores. Ele dá suporte a processamento em lote e em tempo real.
O EventHubs Capture nos permite capturar os dados no EventHubs e em outros armazenamentos disponíveis na nuvem.


Tempo para analisar nosso tutorial:

Pré-requisitos:

  1. Python instalado
  2. Anaconda
  3. Conhecimento básico de Python

Quer aprender a usar o Python? Veja um curso gratuito online para você!

Opcional (se você quiser trabalhar com o Azure):

  1. Conta gratuita do Azure
  2. CLI do Azure instalada
  3. Opcional – se você quiser trabalhar com Hubs de Eventos, precisará criá-lo primeiro. Veja como.
  4. Obtenha a cadeia de conexão do EventHubs – veja como
  5. Key Vault – para armazenar chaves, segredo e certificados (usados para armazenar a cadeia de conexão secreta de Hubs de Eventos)

Deseja aprender os conceitos básicos da nuvem do Azure? Veja um curso gratuito online para você!

Defina seu ambiente com conda:

    conda create -n yahoofinance python=3.6 anaconda
    
    conda activate yahoofinance

Baixe e instale as bibliotecas:

# Install azure-eventhub:
    pip install azure-eventhub
    
    # Install azure:
    pip install azure
    
    # Install yfinance:
    pip install yfinance

SIM! Você concluiu a configuração do ambiente.
Em relação ao editor do código, gosto de trabalhar com VS-Code, mas você pode trabalhar com sua ferramenta favorita.


Você está pronto para escrever código?


O código em si é curto, mas contém muitos conceitos importantes para conhecer e entender. Acompanhe com atenção.

Aqui está o código completo. Adicionei isso no início, portanto é mais fácil copiá-lo para o editor de texto e alterá-lo enquanto você acompanha o tutorial.

import asyncio
    from azure.eventhub.aio import EventHubProducerClient
    from azure.eventhub import EventData
    import yfinance as yf
    
    from azure.keyvault.secrets import SecretClient
    from azure.identity import DefaultAzureCredential
    from datetime import datetime
    
    
    asyncdefrun(stocksCodesList):
        print('Start Batch for stocks: n',stocksCodesList)
        # Get connection string from vault
    
        credential = DefaultAzureCredential()
        keyVaultName = "{your key vault name}"
        keyName = "{your key name}"
        KVUri = "https://" + keyVaultName + ".vault.azure.net"# Create a producer client to send messages to the event hub.
        producer = EventHubProducerClient.from_connection_string(conn_str_value)
    
        asyncwith producer:
            # Create a batch.
            event_data_batch =  await producer.create_batch()
            for stockCode in stocksCodesList:
                #Get stock info
                stockInfo = yf.Ticker(stockCode).info
                # Add events to the batch.
                event_data_batch.add(EventData(stockInfo))
    
            # Send the batch of events to the event hub.await producer.send_batch(event_data_batch)
            printSentMessage()
    
    
    defprintSentMessage():
        now = datetime.now()
        current_time = now.strftime("%H:%M:%S")
        print('Batch sent - Current Time =', current_time)
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(["MSFT"]))
    loop.close()

Agora, vamos dividi-lo em partes e desmistificar:

import asyncio
    
    asyncdefrun(stocksCodesList):# Get stock information and write them to Event Hubs
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(["MSFT"]))
    loop.close()

Este é um código python assíncrono. Para isso, usamos a biblioteca ‘asyncio’:
loop = asyncio.get_event_loop() – criar ou pegar um loop existente.
loop.run_until_complete(run(["MSFT"])) – dar ao “event-loop” a função de execução com a lista de ações que gostaríamos de consultar – isso criará um objeto Future e aguardará até que seja concluído.
loop.close() – fechar o loop.
async def run(stocksCodesList): async e await são duas palavras-chave python usadas para definir corrotinas (mais sobre isso em breve)

Para saber mais sobre o event_loop, leia aqui.

Aqui está como chamamos a API do yFinance para obter informações de ações:

import asyncio
    import yfinance as yf
    
    asyncdefrun(stocksCodesList):for stockCode in stocksCodesList:
                #Get stock info
                stockInfo = yf.Ticker(stockCode).info
                print(stockInfo)
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(["MSFT"]))
    loop.close()

Esse código itera sobre a lista de cadeias de caracteres de códigos de ações que recebemos e extraímos as informações:
yf.Ticker(stockCode).info Esse comando retorna muitas informações que você pode usar para criar uma linda interface do usuário e algoritmos de previsão de mercado.

Consultamos o Yahoo Finance com o símbolo de ação MSFT-Microsoft e aqui está a resposta no formato JSON. Deslize para a direita para ver tudo; é LONGO!

    {'zip': '98052', 'sector': 'Technology', 'fullTimeEmployees': 144000,
     'longBusinessSummary': "Microsoft Corporation develops, licenses, and supports software, services, devices, and solutions worldwide. The company's Productivity and Business Processes segment offers Office, Exchange, SharePoint, Microsoft Teams, Office 365 Security and Compliance, and Skype for Business, as well as related Client Access Licenses (CAL); and Skype, Outlook.com, and OneDrive. It also provides LinkedIn that includes Talent and marketing solutions, and subscriptions; and Dynamics 365, a set of cloud-based and on-premises business solutions for small and medium businesses, large organizations, and divisions of enterprises. The company's Intelligent Cloud segment licenses SQL and Windows Servers, Visual Studio, System Center, and related CALs; GitHub that provides a collaboration platform and code hosting service for developers; and Azure, a cloud platform. It also provides support services and Microsoft consulting services to assist customers in developing, deploying, and managing Microsoft server and desktop solutions; and training and certification to developers and IT professionals on various Microsoft products. The company's More Personal Computing segment offers Windows OEM licensing and other non-volume licensing of the Windows operating system; Windows Commercial comprising volume licensing of the Windows operating system, Windows cloud services, and other Windows commercial offerings; patent licensing; Windows Internet of Things; and MSN advertising. It also provides Microsoft Surface, PC accessories, and other intelligent devices; Gaming, including Xbox hardware, and Xbox software and services; video games and third-party video game royalties; and Search, including Bing and Microsoft advertising. The company sells its products through distributors and resellers; and directly through digital marketplaces, online stores, and retail stores. It has strategic partnerships with Humana Inc. and Nokia. The company was founded in 1975 and is headquartered in Redmond, Washington.", 
    'city': 'Redmond', 'phone': '425-882-8080', 'state': 'WA', 'country': 'United States', 'companyOfficers': [], 'website': 
    'http://www.microsoft.com', 'maxAge': 1, 'address1': 'One Microsoft Way',
     'fax': '425-706-7329', 'industry': 'Software—Infrastructure', 'previousClose': 149.7, 'regularMarketOpen': 152.44, 
    'twoHundredDayAverage': 153.86584, 'trailingAnnualDividendYield': 0.012959252000000001, 'payoutRatio': 0.32930002, 
    'volume24Hr': None, 'regularMarketDayHigh': 158.25,
     'navPrice': None, 'averageDailyVolume10Day': 73927350,
     'totalAssets': None, 'regularMarketPreviousClose': 149.7, 'fiftyDayAverage': 162.70589, 'trailingAnnualDividendRate': 1.94,
     'open': 152.44, 'toCurrency': None, 'averageVolume10days': 73927350, 'expireDate': None, 'yield': None, 'algorithm': None, 
    'dividendRate': 2.04, 'exDividendDate': 1589932800, 
    'beta': 1.091844, 'circulatingSupply': None, 'startDate': None, 'regularMarketDayLow': 150.3, 'priceHint': 2, 'currency': 'USD', 'trailingPE': 27.509142, 'regularMarketVolume': 19627913,
     'lastMarket': None, 'maxSupply': None, 'openInterest': None, 'marketCap': 1201223368704, 'volumeAllCurrencies': None,
     'strikePrice': None, 'averageVolume': 47615782, 'priceToSalesTrailing12Months': 8.947727, 'dayLow': 150.3,
     'ask': 157.71, 'ytdReturn': None, 'askSize': 1800,
     'volume': 19627913, 'fiftyTwoWeekHigh': 190.7, 
    'forwardPE': 25.390675, 'fromCurrency': None,
     'fiveYearAvgDividendYield': 2, 'fiftyTwoWeekLow': 118.1, 'bid': 157.69, 'tradeable': True, 'dividendYield': 0.013099999000000001,
     'bidSize': 1100, 'dayHigh': 158.25, 'exchange': 'NMS',
     'shortName': 'Microsoft Corporation', 'longName': 'Microsoft Corporation', 'exchangeTimezoneName': 'America/New_York', 'exchangeTimezoneShortName': 'EDT',
     'isEsgPopulated': False, 'gmtOffSetMilliseconds': '-14400000', 'quoteType': 'EQUITY', 'symbol': 'MSFT',
     'messageBoardId': 'finmb_21835', 'market': 'us_market',
     'annualHoldingsTurnover': None, 'enterpriseToRevenue': 8.131, 'beta3Year': None, 'profitMargins': 0.33016,
     'enterpriseToEbitda': 17.817, '52WeekChange': 0.25777185, 'morningStarRiskRating': None,
     'forwardEps': 6.22, 'revenueQuarterlyGrowth': None,
     'sharesOutstanding': 7606049792, 'fundInceptionDate': None, 'annualReportExpenseRatio': None, 'bookValue': 14.467, 'sharesShort': 55155176, 'sharesPercentSharesOut': 0.0073, 'fundFamily': None, 'lastFiscalYearEnd': 1561852800,
     'heldPercentInstitutions': 0.74407, 'netIncomeToCommon': 44323000320, 'trailingEps': 5.741, 'lastDividendValue': None,
     'SandP52WeekChange': -0.11360252, 'priceToBook': 10.916568, 'heldPercentInsiders': 0.01421, 'nextFiscalYearEnd': 1625011200, 'mostRecentQuarter': 1577750400,
     'shortRatio': 0.91, 'sharesShortPreviousMonthDate': 1581638400, 'floatShares': 7495074784, 'enterpriseValue': 1091541204992,
     'threeYearAverageReturn': None, 'lastSplitDate': 1045526400, 'lastSplitFactor': '2:1', 'legalType': None,
     'morningStarOverallRating': None, 'earningsQuarterlyGrowth': 0.383, 'dateShortInterest': 1584057600, 
    'pegRatio': 1.88, 'lastCapGain': None,
     'shortPercentOfFloat': 0.0073, 'sharesShortPriorMonth': 56193866, 'category': None, 'fiveYearAverageReturn': None, 
    'regularMarketPrice': 152.44, 'logo_url': 'https://logo.clearbit.com/microsoft.com'}

Temos os dados. Em seguida, salve-o nos Hubs de Eventos �

import asyncio
    from azure.eventhub.aio import EventHubProducerClient
    from azure.eventhub import EventData
    import yfinance as yf
    
    
    asyncdefrun(stocksCodesList):
        print('Start Batch for stocks: n',stocksCodesList)
        # Connection string 
        conn_str_value = "EVENT HUBS CONNECTION STRING - bad security practice"# Create a producer client to send messages to the event hub.
        producer = EventHubProducerClient.from_connection_string(conn_str_value)
    
        asyncwith producer:
            # Create a batch -  - notice the Await !
            event_data_batch =  await producer.create_batch()
            for stockCode in stocksCodesList:
                #Get stock info
                stockInfo = yf.Ticker(stockCode).info
                # Add events to the batch.
                event_data_batch.add(EventData(stockInfo))
    
            # Send the batch of events to the Event hubs. - notice the Await!await producer.send_batch(event_data_batch)
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(["MSFT"]))
    loop.close()

Vamos dividir isso. Vinculamos a um componente EventHubs existente e solicitamos a ele um produtor.
conn_str_value = "EVENT HUBS CONNECTION STRING" – prática de segurança inadequada!
producer = EventHubProducerClient.from_connection_string(conn_str_value)

AVISO! Fornecer links privados ou informações seguras em texto não criptografado diretamente no código é uma prática de segurança INADEQUADA. A próxima seção demonstra como fazer isso com a segurança em mente.

Em seguida, chamamos:
async with producer: essa chamada cria uma corrotina, e tudo dentro desse bloco de código ocorre em uma corrotina. Uma corrotina é uma sub-rotina para multitarefas não preemptivas. Nós a aproveitamos para criar a comunicação assíncrona, já que o produtor do EventHubs não retorna uma ação. Portanto, podemos aproveitar o fato de que não há necessidade de comunicação síncrona. A comunicação síncrona tende a tornar o sistema mais lento.

event_data_batch = await producer.create_batch() – o produtor cria um lote com a palavra-chave await. Isso significa que a sub-rotina atual espera que o lote seja criado e não continue para a próxima linha.
for stockCode in stocksCodesList: nesse loop sobre a lista de códigos de ações, extraímos as informações e as adicionamos ao lote.

await producer.send_batch(event_data_batch) – essa chamada é crucial, pois é aquela que envia o lote com todos os dados acumulados para EventHubs.

Certo! Estamos quase terminando.
A última parte é fazer o trabalho e, ao mesmo tempo, estar em SEGURANÇA.

Para fazer isso, aproveitamos o Key Vault.
Usando o Key Vault, armazenamos valores de chaves, segredo e certificados na segurança de hardware que está disponível para nós quando trabalhamos com o Azure.

A primeira ação é armazenar a conexão de cadeia de caracteres no Key Vault. Aqui está um tutorial rápido com imagens.

Após essa fase, você tem o nome do Key Vault e o nome da chave para identificar o segredo da chave – sua cadeia de conexão.


Depois, crie a entidade de serviço
Entidade de serviço – é usada para fornecer ao aplicativo a identidade (como um cartão de identidade) para se identificar com o Key Vault. O Key Vault (ou qualquer outro serviço usado) verifica a credencial que esse aplicativo tem e, se ele puder acessar o segredo (caso afirmativo), fornecerá ao aplicativo o segredo de maneira segura. Caso contrário, todo esse processo falhará.

COMO?
Crie uma SP (entidade de serviço) com o comando:

    az ad sp create-for-rbac --skip-assignment --name { Event Hubs Sender App SP }

Substitua { Event Hubs Sender App SP } por um nome real.

Você receberá algo conforme a seguir. Salve as informações.

    {
      "appId": "00000000-0000-0000-0000-000000000000",
      "displayName": "{given name}",
      "name": "http://{given name}",
      "password": "00000000-0000-0000-0000-000000000000",
      "tenant": "00000000-0000-0000-0000-000000000000"
    }

Na tela do Key Vault, vá para Controle de Acesso ➡️ Atribuição de Função ➡️ Adicionar ➡️ Selecionar Função em Função ➡️ Selecionar a SP. Observe o diagrama abaixo:

Para que tudo funcione, você precisa configurar o ambiente com as credenciais da SP:

    export AZURE_CLIENT_ID="http://{given name}"
    export AZURE_CLIENT_SECRET="00000000-0000-0000-0000-000000000000"
    export AZURE_TENANT_ID="00000000-0000-0000-0000-000000000000"

Lembre-se de não armazenar essas credenciais no controle de origem.

Vamos adicionar o código!

Proteja parte da codificação. Tratamos da chamada para o Key Vault e recuperamos com segurança a cadeia de conexão:

from azure.keyvault.secrets import SecretClient
    from azure.identity import DefaultAzureCredential
    
    # Get connection string from vault
    credential = DefaultAzureCredential()
    keyVaultName = "{your key vault name}"
    keyName = "{your key name}"
    KVUri = "https://" + keyVaultName + ".vault.azure.net"
    
    client = SecretClient(vault_url=KVUri, credential=credential)
    conn_str_value = client.get_secret(keyName).value

DefaultAzureCredential pesquisará uma credencial válida no computador para identificar o aplicativo e vai procurar os parâmetros que definimos anteriormente (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET…). Ele retornará um objeto que pode fornecer um token de acesso para o cofre.

client = SecretClient(vault_url=KVUri, credential=credential) – crie um cliente secreto com o qual solicitar o valor da chave criptografada.
conn_str_value = client.get_secret(keyName).value – use o cliente para recuperar o segredo. Observe que, nesse ponto, tudo é criptografado e, mesmo que você tente imprimir a chave, não verá o valor real.


FIM.

Neste tutorial, você aprendeu a chamar a API do Yahoo Finance, a definir um ambiente conda, a criar um produtor de Hubs de Eventos e a proteger as chaves no Key Vault. Você está seguro e pronto para ingerir dados para o serviço de editor/assinante!

Saiba mais �

Postagens Relacionadas

Hoje em dia não é preciso querer entrar na carreira de programação para procurar saber como aprender HTML e CSS. Afinal, com a transformação
Seja você um empreendedor que está tentando promover seu negócio, um iniciante em Marketing que quer aprender de tudo um pouco ou um profissional
Não existe uma resposta exata para quem se pergunta quanto tempo demora para aprender inglês, mas conhecer um pouco sobre como nosso cérebro funciona
Apesar de terem sido subestimadas por muito tempo, hoje as competências comportamentais têm conquistado cada vez mais a atenção de recrutadores e empresas, que