Skip to main content

Python access to structure stock market information

Project description

invest

Python access to structure stock market information

To install: pip install invest

Table of contents generated with markdown-toc

Quick Start

from invest import Tickers

Get a default list of tickers

tickers = Tickers()

tickers is a dict-like container of tickers. So you can do dict-like things with it, like...

  • ask for it's length
len(tickers)
4039
  • list the keys
list(tickers)[:5]
['EGLE', 'KMPH', 'LONG', 'CYBR', 'PTC']
  • check for containment of a key
'GOOG' in tickers
True

The values of this dict-like object are Ticker instances.

ticker = tickers['GOOG']
ticker
Ticker('GOOG')

This ticker object is also dict-like. Let's see how many keys there are:

len(ticker)
40

What are these keys?

list(ticker)
['balancesheet',
 'dividends',
 'get_sustainability',
 'get_info',
 'get_institutional_holders',
 'sustainability',
 'quarterly_balance_sheet',
 'get_balance_sheet',
 'info',
 'quarterly_earnings',
 'isin',
 'earnings',
 'history',
 'get_balancesheet',
 'get_financials',
 'balance_sheet',
 'get_earnings',
 'options',
 'splits',
 'get_recommendations',
 'get_major_holders',
 'get_dividends',
 'actions',
 'recommendations',
 'cashflow',
 'get_cashflow',
 'get_splits',
 'major_holders',
 'institutional_holders',
 'option_chain',
 'get_actions',
 'quarterly_financials',
 'get_calendar',
 'quarterly_cashflow',
 'calendar',
 'financials',
 'quarterly_balancesheet',
 'get_mutualfund_holders',
 'get_isin',
 'mutualfund_holders']

Let's look at one of these, 'info', which contains a dict with a bunch of information about the ticker...

info = ticker['info']
print(*info, sep=', ')
zip, sector, fullTimeEmployees, longBusinessSummary, city, phone, state, country, companyOfficers, website, maxAge, address1, industry, previousClose, regularMarketOpen, twoHundredDayAverage, trailingAnnualDividendYield, payoutRatio, volume24Hr, regularMarketDayHigh, navPrice, averageDailyVolume10Day, totalAssets, regularMarketPreviousClose, fiftyDayAverage, trailingAnnualDividendRate, open, toCurrency, averageVolume10days, expireDate, yield, algorithm, dividendRate, exDividendDate, beta, circulatingSupply, startDate, regularMarketDayLow, priceHint, currency, trailingPE, regularMarketVolume, lastMarket, maxSupply, openInterest, marketCap, volumeAllCurrencies, strikePrice, averageVolume, priceToSalesTrailing12Months, dayLow, ask, ytdReturn, askSize, volume, fiftyTwoWeekHigh, forwardPE, fromCurrency, fiveYearAvgDividendYield, fiftyTwoWeekLow, bid, tradeable, dividendYield, bidSize, dayHigh, exchange, shortName, longName, exchangeTimezoneName, exchangeTimezoneShortName, isEsgPopulated, gmtOffSetMilliseconds, quoteType, symbol, messageBoardId, market, annualHoldingsTurnover, enterpriseToRevenue, beta3Year, profitMargins, enterpriseToEbitda, 52WeekChange, morningStarRiskRating, forwardEps, revenueQuarterlyGrowth, sharesOutstanding, fundInceptionDate, annualReportExpenseRatio, bookValue, sharesShort, sharesPercentSharesOut, fundFamily, lastFiscalYearEnd, heldPercentInstitutions, netIncomeToCommon, trailingEps, lastDividendValue, SandP52WeekChange, priceToBook, heldPercentInsiders, nextFiscalYearEnd, mostRecentQuarter, shortRatio, sharesShortPreviousMonthDate, floatShares, enterpriseValue, threeYearAverageReturn, lastSplitDate, lastSplitFactor, legalType, lastDividendDate, morningStarOverallRating, earningsQuarterlyGrowth, dateShortInterest, pegRatio, lastCapGain, shortPercentOfFloat, sharesShortPriorMonth, category, fiveYearAverageReturn, regularMarketPrice, logo_url
info['shortName']
'Alphabet Inc.'
info['sector']
'Communication Services'
df = ticker['history']
df
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
Open High Low Close Volume Dividends Stock Splits
Date
2020-10-28 1559.739990 1561.349976 1514.619995 1516.619995 1834000 0 0
2020-10-29 1522.359985 1593.709961 1522.239990 1567.239990 2003100 0 0
2020-10-30 1672.109985 1687.000000 1604.459961 1621.010010 4329100 0 0
2020-11-02 1628.160034 1660.770020 1616.030029 1626.030029 2535400 0 0
2020-11-03 1631.780029 1661.699951 1616.619995 1650.209961 1661700 0 0
2020-11-04 1710.280029 1771.364990 1706.030029 1749.130005 3570900 0 0
2020-11-05 1781.000000 1793.640015 1750.510010 1763.369995 2065800 0 0
2020-11-06 1753.949951 1772.430054 1740.349976 1761.750000 1660900 0 0
2020-11-09 1790.900024 1818.060059 1760.020020 1763.000000 2268300 0 0
2020-11-10 1731.089966 1763.000000 1717.300049 1740.390015 2636100 0 0
2020-11-11 1750.000000 1764.219971 1747.364990 1752.709961 1264000 0 0
2020-11-12 1747.630005 1768.270020 1745.599976 1749.839966 1247500 0 0
2020-11-13 1757.630005 1781.040039 1744.550049 1777.020020 1499900 0 0
2020-11-16 1771.699951 1799.069946 1767.689941 1781.380005 1246800 0 0
2020-11-17 1776.939941 1785.000000 1767.000000 1770.150024 1147100 0 0
2020-11-18 1765.229980 1773.469971 1746.140015 1746.780029 1173500 0 0
2020-11-19 1738.380005 1769.589966 1737.005005 1763.920044 1249900 0 0
2020-11-20 1765.209961 1774.000000 1741.859985 1742.189941 2313500 0 0
2020-11-23 1749.599976 1753.900024 1717.719971 1734.859985 2161600 0 0
2020-11-24 1730.500000 1771.599976 1727.689941 1768.880005 1578000 0 0
2020-11-25 1772.890015 1778.540039 1756.540039 1771.430054 1045800 0 0
2020-11-27 1773.089966 1804.000000 1772.439941 1793.189941 884900 0 0
from mplfinance import plot as candlestick_plot  # pip install mplfinance if you don't have it already

candlestick_plot(df)

png

But these are daily metrics and only for the recent (yes, I'm doing this on a Thanksgiving week-end!) past.

How do I get something different? Like a longer history, and/or at a finer time-granularity?

See the next Configuring Ticker objects section on how to do that.

ticker_symbols argument

The first argument of Tickers is the ticker_symbols argument.

One can specify a collection (list, set, tuple, etc.) of ticker symbol strings, or a path to a file containing a pickle of such a collection.

The default is the string 'local_list' which has the effect of using a default list (currently of about 4000 tickers), but it's contents can change in the future.

Note that this ticker_symbols will have an effect on such affairs as list(tickers), len(tickers), or s in tickers, when it's relevant to use these.

But any Tickers object will allow access to any ticker symbol, regardless if it's in the ticker_symbols collection or not.

tickers = Tickers(ticker_symbols=('GOOG', 'AAPL', 'AMZN'))
assert list(tickers) == ['GOOG', 'AAPL', 'AMZN']
assert len(tickers) == 3
assert 'AAPL' in tickers
assert 'NFLX' not in tickers
# and yet we have access to NFLX info
assert tickers['NFLX']['info']['shortName'] == 'Netflix, Inc.'

Notes

  • Both Tickers and Ticker instances have tab-triggered auto-suggestion enabled when you get an item. Example: tickers['AA<now press the TAB button...>.
  • The specification of

Configuring Ticker objects

Configure a Ticker instance

You can instantiate a Ticker instance directly, from any valid ticker symbol. The Tickers class is just a way to make a collection of tickers to work with.

from invest import Tickers, Ticker

ticker = Ticker('GOOG')
ticker
Ticker('GOOG')

But you'll notice that Ticker (and Tickers) have more than one argument.

from inspect import signature
print(signature(Tickers))
print(signature(Ticker))
(ticker_symbols='local_list', **kwargs_for_method_keys)
(ticker_symbol: str, **kwargs_for_method_keys)

What's this kwargs_for_method_keys?

Well, at the time of writing this, Ticker object is just a convenient dict-like interface to the attributes of the Ticker of the yfinance package which is itself a convenient python interface to the yahoo finance API.

When you do list(ticker), you're just getting a list of attributes of yfinance.Ticker: Both properties and methods that don't require any arguments. Though these methods don't require any arguments -- meaning all their arguments have defaults -- you can still specify if you want to use different defaults.

That's where kwargs_for_method_keys comes in. It specifies what arg=val pairs that should be used for particular methods of yfinance.Ticker.

If you want to know more about what you can do with the Ticker object, you might want to check out yfinance's and yahoo finance API's documentation.

For the basics though, invest provides the help_me_with function (as a standalone function or as a method in Tickers and Ticker) for quick access to essentials.

Ticker.help_me_with('history')
history
wraps <function TickerBase.history at 0x11a064940>, whose signature is:
(self, period='1mo', interval='1d', start=None, end=None, prepost=False, actions=True, auto_adjust=True, back_adjust=False, proxy=None, rounding=False, tz=None, **kwargs)

        :Parameters:
            period : str
                Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
                Either Use period parameter or use start and end
            interval : str
                Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
                Intraday data cannot extend last 60 days
            start: str
                Download start date string (YYYY-MM-DD) or _datetime.
                Default is 1900-01-01
            end: str
                Download end date string (YYYY-MM-DD) or _datetime.
                Default is now
            prepost : bool
                Include Pre and Post market data in results?
                Default is False
            auto_adjust: bool
                Adjust all OHLC automatically? Default is True
            back_adjust: bool
                Back-adjusted data to mimic true historical prices
            proxy: str
                Optional. Proxy server URL scheme. Default is None
            rounding: bool
                Round values to 2 decimal places?
                Optional. Default is False = precision suggested by Yahoo!
            tz: str
                Optional timezone locale for dates.
                (default data is returned as non-localized dates)
            **kwargs: dict
                debug: bool
                    Optional. If passed as False, will suppress
                    error message printing to console.

Example

Here's you can get history to give you something different.

Say, get data for the last day, with a granularity of 15 minutes.

ticker = Ticker('GOOG', history=dict(period='1d', interval='15m'))
ticker
Ticker('GOOG', history={'period': '1d', 'interval': '15m'})

Your ticker is almost identical to the previous one we made, or the one we got from Tickers, except for the fact that asking for ticker['history'] is going to give you something different.

df = ticker['history']
df
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
Open High Low Close Volume Dividends Stock Splits
Datetime
2020-11-27 09:30:00-05:00 1773.089966 1789.890015 1772.439941 1785.000000 119289 0 0
2020-11-27 09:45:00-05:00 1785.380005 1786.979980 1780.229980 1785.089966 50660 0 0
2020-11-27 10:00:00-05:00 1785.489990 1786.989990 1780.959961 1785.800049 50797 0 0
2020-11-27 10:15:00-05:00 1785.319946 1795.925049 1785.319946 1791.589966 72146 0 0
2020-11-27 10:30:00-05:00 1792.060059 1798.999878 1792.060059 1796.699951 48097 0 0
2020-11-27 10:45:00-05:00 1796.800049 1800.199951 1795.060059 1799.959961 56292 0 0
2020-11-27 11:00:00-05:00 1800.359985 1800.449951 1797.130005 1797.660034 41882 0 0
2020-11-27 11:15:00-05:00 1797.819946 1802.599976 1796.949951 1802.579956 60333 0 0
2020-11-27 11:30:00-05:00 1802.579956 1804.000000 1797.550049 1798.185059 45667 0 0
2020-11-27 11:45:00-05:00 1798.099976 1798.603027 1788.000000 1788.739990 47900 0 0
2020-11-27 12:00:00-05:00 1789.000000 1791.599976 1787.329956 1787.500000 36459 0 0
2020-11-27 12:15:00-05:00 1787.347534 1788.530029 1782.574951 1787.952759 46400 0 0
2020-11-27 12:30:00-05:00 1787.260010 1788.920044 1785.640015 1785.640015 45660 0 0
2020-11-27 12:45:00-05:00 1785.829956 1793.420044 1785.219971 1792.520020 97273 0 0
2020-11-27 13:00:00-05:00 1793.189941 1793.189941 1793.189941 1793.189941 46982 0 0
from mplfinance import plot as candlestick_plot  # pip install mplfinance if you don't have it already

candlestick_plt(df)

png

Configure a Tickers instance

Let's say we wanted all ticker instances that Tickers gives us to have their history be over a specific interval of time in the past (say, during the 2020 pandemic), at 5 day intervals...

tickers = Tickers(ticker_symbols={'NFLX', 'AMZN', 'DAL'},  # demoing the fact that we can specify an explicit collection of ticker symbols
                  history=dict(start='2020-03-01', end='2020-10-31', interval='5d'))
list(tickers)
['DAL', 'AMZN', 'NFLX']

See that indeed, all tickers given by tickers are configured according to our wishes.

tickers['NFLX']
Ticker('NFLX', history={'start': '2020-03-01', 'end': '2020-10-31', 'interval': '5d'})
from mplfinance import plot as candlestick_plot  # pip install mplfinance if you don't have it already

candlestick_plot(tickers['NFLX']['history'])

png

candlestick_plot(tickers['AMZN']['history'])

png

So Netflix and Amazon did well.

Delta, less so:

candlestick_plot(tickers['DAL']['history'])

png

Getting (only) specific information about tickers

Tickers and Ticker are convenient if you want to analyze several aspects of a ticker since you can poke around the various keys (e.g. info, history, etc.).

But if a particular analysis only needs one of these, it's more convenient to use TickersWithSpecificInfo, which gives you the same interface as Tickers (in fact, it's a subclass if Tickers), but fixes the key.

Example: Historical data

For example, if you're only interested in the historical data (a.k.a. the 'history' key), you might do this:

from invest import TickersWithSpecificInfo

tickers = TickersWithSpecificInfo(specific_key='history', start='2008-01-01', end='2009-01-01', interval='1mo')  # 2008 historical data, month granularity
tickers
TickersWithSpecificInfo(ticker_symbols=<local_list>, specific_key=history, start=2008-01-01, end=2009-01-01, interval=1mo)
candlestick_plot(tickers['GOOG'])

png

candlestick_plot(tickers['NFLX'])

png

candlestick_plot(tickers['AMZN'])

png

candlestick_plot(tickers['AAPL'])

png

Example: Specific 'info' fields

from invest import TickersWithSpecificInfo

the_info_that_i_want = ['shortName', 'sector', 'earningsQuarterlyGrowth', 'sharesShortPriorMonth']
tickers = TickersWithSpecificInfo(specific_key='info', val_trans=lambda d: {k: d[k] for k in the_info_that_i_want}) 
tickers
TickersWithSpecificInfo(ticker_symbols=<local_list>, specific_key=info, val_trans=<function <lambda> at 0x11c2374c0>)

Now, you won't get the overwhelming amount of information you usually get with info:

tickers['AAPL']
{'shortName': 'Apple Inc.',
 'sector': 'Technology',
 'earningsQuarterlyGrowth': -0.074,
 'sharesShortPriorMonth': 83252522}
faang_tickers = ('FB', 'AMZN', 'AAPL', 'NFLX', 'GOOG')
the_info_that_i_want = ['shortName', 'sector', 'earningsQuarterlyGrowth', 'sharesShortPriorMonth']
tickers = TickersWithSpecificInfo(faang_tickers, specific_key='info', val_trans=lambda d: {k: d[k] for k in the_info_that_i_want}) 
tickers
TickersWithSpecificInfo(ticker_symbols=('FB', 'AMZN', 'AAPL', 'NFLX', 'GOOG'), specific_key=info, val_trans=<function <lambda> at 0x11c237a60>)
info_df = pd.DataFrame(list(tickers.values()))
info_df
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
shortName sector earningsQuarterlyGrowth sharesShortPriorMonth
0 Facebook, Inc. Communication Services 0.288 21187652
1 Amazon.com, Inc. Consumer Cyclical 1.967 2509939
2 Apple Inc. Technology -0.074 83252522
3 Netflix, Inc. Communication Services 0.187 9416477
4 Alphabet Inc. Communication Services 0.591 2381334

Notes

  • Though Tickers allows you to deal with a collection of tickers, it does so (for time being) by calling yahoo's API for each individual ticker. The API does, on the other hand, contain some bulk tickers routes which we intend to integrate.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

invest-0.0.2.tar.gz (21.0 kB view hashes)

Uploaded Source

Built Distribution

invest-0.0.2-py3-none-any.whl (11.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page