Obtenção e manipulação de dados históricos do mercado financeiro
Lista de Conteúdos
Introdução
A análise de dados históricos do mercado financeiro pode ser prática para diversos fins, como estudos acadêmicos, gerenciamento de portfólio, criação de conteúdo e outros.
Boa parte dos materiais por aí são baseados naqueles famosos aplicativos de planilha, nada contra, mas eu gosto mesmo de resolver os problemas propostos usando Python. Para isso, vamos usar dois pacotes:
yfinance oferece uma alternativa em Python para baixar dados históricos do mercado financeiro a partir do Yahoo! finanças;
mplfinance é uma utilidade construída sobre Matplotlib, que oferece visualização e análise para dados financeiros.
O primeiro passo é instalar os pacotes que usaremos, e isso pode ser feito no ambiente Jupyter (como esse post) com o seguinte comando mágico:
!pip install -q yfinance mplfinance
E então importamos ambos para a nossa aplicação:
import yfinance as yf
import mplfinance as mpf
Obtenção e manipulação dos dados
O módulo Ticker
nos permite o acesso a diversos dados de maneira integrada ao Python, e apenas para exemplificar, usaremos a Microsoft, código de negociação MSFT
:
msft = yf.Ticker("MSFT")
Informações completas da companhia são obtidos com o método info
, como segue:
msft.info
{'zip': '98052-6399',
'sector': 'Technology',
'fullTimeEmployees': 163000,
'longBusinessSummary': 'Microsoft Corporation develops, licenses, and supports software, services, devices, and solutions worldwide. Its 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); Skype, Outlook.com, and OneDrive; LinkedIn that includes Talent, Learning, Sales, and Marketing solutions, as well as premium 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. Its 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 offers 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. Its More Personal Computing segment provides Windows original equipment manufacturer (OEM) licensing and other non-volume licensing of the Windows operating system; Windows Commercial, such as 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 offers Surface, PC accessories, PCs, tablets, gaming and entertainment consoles, and other intelligent devices; Gaming, including Xbox hardware, and Xbox content and services; video games and third-party video game royalties; and Search, including Bing and Microsoft advertising. It sells its products through OEMs, distributors, and resellers; and directly through digital marketplaces, online stores, and retail stores. 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',
'industry': 'Software—Infrastructure',
'previousClose': 219.66,
'regularMarketOpen': 220.15,
'twoHundredDayAverage': 196.80064,
'trailingAnnualDividendYield': 0.00928708,
'payoutRatio': 0.3455,
'volume24Hr': None,
'regularMarketDayHigh': 222.29,
'navPrice': None,
'averageDailyVolume10Day': 27025187,
'totalAssets': None,
'regularMarketPreviousClose': 219.66,
'fiftyDayAverage': 212.05457,
'trailingAnnualDividendRate': 2.04,
'open': 220.15,
'toCurrency': None,
'averageVolume10days': 27025187,
'expireDate': None,
'yield': None,
'algorithm': None,
'dividendRate': 2.24,
'exDividendDate': 1605657600,
'beta': 0.923331,
'circulatingSupply': None,
'startDate': None,
'regularMarketDayLow': 219.33,
'priceHint': 2,
'currency': 'USD',
'trailingPE': 38.135414,
'regularMarketVolume': 25074770,
'lastMarket': None,
'maxSupply': None,
'openInterest': None,
'marketCap': 1662310023168,
'volumeAllCurrencies': None,
'strikePrice': None,
'averageVolume': 33866804,
'priceToSalesTrailing12Months': 11.623326,
'dayLow': 219.33,
'ask': 219,
'ytdReturn': None,
'askSize': 1000,
'volume': 25074770,
'fiftyTwoWeekHigh': 232.86,
'forwardPE': 29.967258,
'fromCurrency': None,
'fiveYearAvgDividendYield': 1.8,
'fiftyTwoWeekLow': 132.52,
'bid': 219,
'tradeable': False,
'dividendYield': 0.010199999,
'bidSize': 1300,
'dayHigh': 222.29,
'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': 11.243,
'beta3Year': None,
'profitMargins': 0.30962,
'enterpriseToEbitda': 24.639,
'52WeekChange': 0.59857357,
'morningStarRiskRating': None,
'forwardEps': 7.33,
'revenueQuarterlyGrowth': None,
'sharesOutstanding': 7567649792,
'fundInceptionDate': None,
'annualReportExpenseRatio': None,
'bookValue': 15.626,
'sharesShort': 39634230,
'sharesPercentSharesOut': 0.0052,
'fundFamily': None,
'lastFiscalYearEnd': 1593475200,
'heldPercentInstitutions': 0.74093,
'netIncomeToCommon': 44280999936,
'trailingEps': 5.76,
'lastDividendValue': 0.51,
'SandP52WeekChange': 0.16647923,
'priceToBook': 14.057341,
'heldPercentInsiders': 0.014249999,
'nextFiscalYearEnd': 1656547200,
'mostRecentQuarter': 1593475200,
'shortRatio': 1.09,
'sharesShortPreviousMonthDate': 1598832000,
'floatShares': 7455727348,
'enterpriseValue': 1607928643584,
'threeYearAverageReturn': None,
'lastSplitDate': 1045526400,
'lastSplitFactor': '2:1',
'legalType': None,
'lastDividendDate': 1597795200,
'morningStarOverallRating': None,
'earningsQuarterlyGrowth': -0.151,
'dateShortInterest': 1601424000,
'pegRatio': 2.29,
'lastCapGain': None,
'shortPercentOfFloat': 0.0053,
'sharesShortPriorMonth': 36458662,
'category': None,
'fiveYearAverageReturn': None,
'regularMarketPrice': 220.15,
'logo_url': 'https://logo.clearbit.com/microsoft.com'}
Pode-se obter informações sobre os principais acionistas:
msft.major_holders
0 | 1 | |
---|---|---|
0 | 1.42% | % of Shares Held by All Insider |
1 | 74.09% | % of Shares Held by Institutions |
2 | 75.16% | % of Float Held by Institutions |
3 | 4630 | Number of Institutions Holding Shares |
msft.institutional_holders
Holder | Shares | Date Reported | % Out | Value | |
---|---|---|---|---|---|
0 | Vanguard Group, Inc. (The) | 632013255 | 2020-06-29 | 0.0835 | 128621017525 |
1 | Blackrock Inc. | 521841633 | 2020-06-29 | 0.0690 | 106199990731 |
2 | State Street Corporation | 314554694 | 2020-06-29 | 0.0416 | 64015025775 |
3 | FMR, LLC | 236873992 | 2020-06-29 | 0.0313 | 48206226111 |
4 | Price (T.Rowe) Associates Inc | 183090016 | 2020-06-29 | 0.0242 | 37260649156 |
5 | Capital World Investors | 122923512 | 2020-06-29 | 0.0162 | 25016163927 |
6 | Geode Capital Management, LLC | 116688974 | 2020-06-29 | 0.0154 | 23747373098 |
7 | Capital International Investors | 98209725 | 2020-06-29 | 0.0130 | 19986661134 |
8 | Capital Research Global Investors | 94081197 | 2020-06-29 | 0.0124 | 19146464401 |
9 | Northern Trust Corporation | 93331898 | 2020-06-29 | 0.0123 | 18993974561 |
Os dados históricos são obtidos com o método history()
, que aceita como argumentos o período desejado, ou datas de início e fim, e retorna um Pandas DataFrame
que contém os preços de abertura e fechamento do mercado, além de máximas e mínimas, o volume de negociação, informações sobre dividendos pagos e desdobramentos.
data = msft.history(period="max")
E assim, temos a disposição todos os métodos inerentes do Pandas, como head()
, que nos mostra a parte superior da tabela de dados:
data.head()
Open | High | Low | Close | Volume | Dividends | Stock Splits | |
---|---|---|---|---|---|---|---|
Date | |||||||
1986-03-13 | 0.06 | 0.06 | 0.06 | 0.06 | 1031788800 | 0.0 | 0.0 |
1986-03-14 | 0.06 | 0.07 | 0.06 | 0.06 | 308160000 | 0.0 | 0.0 |
1986-03-17 | 0.06 | 0.07 | 0.06 | 0.07 | 133171200 | 0.0 | 0.0 |
1986-03-18 | 0.07 | 0.07 | 0.06 | 0.06 | 67766400 | 0.0 | 0.0 |
1986-03-19 | 0.06 | 0.06 | 0.06 | 0.06 | 47894400 | 0.0 | 0.0 |
Ou tail()
, que mostra a parte inferior:
data.tail()
Open | High | Low | Close | Volume | Dividends | Stock Splits | |
---|---|---|---|---|---|---|---|
Date | |||||||
2020-10-12 | 218.79 | 223.86 | 216.81 | 221.40 | 40461400 | 0.0 | 0.0 |
2020-10-13 | 222.72 | 225.21 | 220.43 | 222.86 | 28950800 | 0.0 | 0.0 |
2020-10-14 | 223.00 | 224.22 | 219.13 | 220.86 | 23451700 | 0.0 | 0.0 |
2020-10-15 | 217.10 | 220.36 | 216.01 | 219.66 | 22718400 | 0.0 | 0.0 |
2020-10-16 | 220.15 | 222.29 | 219.33 | 219.66 | 25074770 | 0.0 | 0.0 |
Podemos facilmente produzir um gráfico com o método plot()
, conforme segue:
data.plot();
Essa figura ficou meio poluída visualmente, vamos nos concentrar apenas no preço de fechamento, e acrescentar algumas opções extras:
# Acessamos apenas o preço de fechamento, plotamos com log no eixo y,
# porque é mais representativo, adicionamos um título à figura
data.Close.plot(logy=True, title=msft.info['symbol'])
# Aqui adicionamos médias móveis, porque não?
# mav vem do inglês para moving average
for mav in [500, 1000, 2000]:
data.Close.rolling(mav).mean().plot(label=f'mav {mav}')
plt.legend();
Podemos também calcular e graficar a variação percentual diária do preço como:
data['Var [%]'] = 100. * (data.Close - data.Open) / data.Open
data['Var [%]'].plot();
Que pode ser exibida como um histograma de frequências:
data['Var [%]'].plot.hist(bins=100);
Temos ainda o método actions()
que retorna dados históricos sobre dividendos e desdobramento das ações, e perceba que ele pode ser encadeado com o método plot()
, para múltiplas operações em uma única linha de código:
msft.actions.plot();
O método describe()
é particularmente útil para ter uma rápida representação de uma grande quantidade de dados, fornecendo a contagem, média, desvio padrão, valor mínimo, máximo e outros.
data.describe()
Open | High | Low | Close | Volume | Dividends | Stock Splits | Var [%] | |
---|---|---|---|---|---|---|---|---|
count | 8722.000000 | 8722.000000 | 8722.000000 | 8722.000000 | 8.722000e+03 | 8722.000000 | 8722.000000 | 8722.000000 |
mean | 26.930644 | 27.217296 | 26.637444 | 26.937902 | 6.000501e+07 | 0.002196 | 0.001949 | 0.067909 |
std | 37.001413 | 37.388700 | 36.589514 | 37.016185 | 3.867451e+07 | 0.040982 | 0.061015 | 2.052796 |
min | 0.060000 | 0.060000 | 0.060000 | 0.060000 | 2.304000e+06 | 0.000000 | 0.000000 | -25.925926 |
25% | 2.360000 | 2.380000 | 2.330000 | 2.362500 | 3.617535e+07 | 0.000000 | 0.000000 | -0.781170 |
50% | 18.595000 | 18.805000 | 18.360000 | 18.590000 | 5.316930e+07 | 0.000000 | 0.000000 | 0.000000 |
75% | 26.267500 | 26.487500 | 25.925000 | 26.225000 | 7.371192e+07 | 0.000000 | 0.000000 | 0.889940 |
max | 229.270000 | 232.860000 | 227.350000 | 231.650000 | 1.031789e+09 | 3.080000 | 2.000000 | 16.666667 |
Esse foi nosso exemplo, informações complementares podem ser encontradas no post do autor original do pacote yfinance
. Experimente executar os exemplos propostos para outros códigos de negociação, por exemplo com o índice S&P 500 com o ticker ^GSPC
, o índice Ibovespa com o ticker ^BVSP
, ou empresas brasileiras, como o ticker ITUB3.SA
, e muitos outros.
Visualização
A representação gráfica de dados financeiros é mais usual pelo método Candlestick, onde exibe-se os preços de abertura, fechamento, máximo e mínimo de maneira mais compreensiva.
Vamos mudar os dados empregados apenas para ter um segundo exemplo da utilização do yfinance
, agora especificando uma data de início e fim para a série histórica, e agrupando os resultados no período de uma semana.
data = yf.Ticker('^BVSP').history(start='2019-01-01', end='2019-12-31', interval='1wk')
E agora com mplfinance
e apenas uma linha de código, temos a nossa figura:
mpf.plot(data, type='candle',
mav=(5,10), volume=True,
show_nontrading=True, style='yahoo',
title='Ibovespa, 2019');
Bem mais limpa visualmente do que a nossa primeira tentativa, não é mesmo? Perceba que o método aceita diferentes tipos de gráfico, a inclusão de médias móveis (mav
), o volume de negociações (pode mostrar, ou não), os dias em que não houveram pregão, e pode-se escolher o estilo do gráfico. Informações completas sobre o pacote mplfinance
estão disponíveis no link.