Angler API

Angler is a SEC financial data analysis tool provided by Blacktip Research. You must make an account on the Blacktip website prior to use.

Install, Import, and Initialization

You can find Angler on PyPI, and can install via the terminal using pip install blacktip. To import Angler in a file, do the following:

>>> from blacktip.angler import Angler
>>> instance = Angler(username, password)

Replace username and password with your personal login credentials.

Angler Functions

The querying object. Angler provides several querying functions to interface with the database.

Angler.queryCIK(ticker)

Get the CIK (central index key) of an inputted ticker.

Parameters:

  • ticker : string

    • the ticker for which to search the corresponding CIK

Returns:

  • tuple

    • a tuple containing (ticker, CIK) as strings

Example usage:

>>> Angler.queryCIK("AAPL")
('AAPL', '320193')

Angler.queryName(self, ticker_or_CIK)

Get the name of a company from its ticker or CIK number.

Parameters:

  • ticker_or_CIK : string or int

    • the ticker or CIK number of the company

Returns:

  • string

    • the name of the company

Example usage:

>>> instance.queryName("AAPL") 
'APPLE INC'
>>> instance.queryName(320193)
'APPLE INC'

Angler.query10K(self, ticker_or_CIK, years)

Get company 10-K reports for selected years.

Parameters:

  • ticker_or_CIK : string or int

    • the ticker or CIK number of the company

  • years : int or iterable

    • the year or years of interest

Returns:

  • Form10K

    • returns a Form10K object with the selected query

Example usage:

>>> form10K =  instance.query10K("AAPL", [2018, 2019])
>>> print(form10K)
fy                                                                 2018          2019
tag                                                uom
AccountsPayableCurrent                             USD     4.424200e+10  4.623600e+10
AccountsReceivableNetCurrent                       USD     1.787400e+10  2.292600e+10
AccruedIncomeTaxesNoncurrent                       USD     2.570000e+08  3.358900e+10
AccumulatedDepreciationDepletionAndAmortization... USD     4.129300e+10  4.909900e+10
AccumulatedOtherComprehensiveIncomeLossNetOfTax    USD    -1.500000e+08 -5.840000e+08
...                                                                 ...           ...
UnrecordedUnconditionalPurchaseObligationBalanc... USD     9.328000e+09  8.211000e+09
UnrecordedUnconditionalPurchaseObligationDueAft... USD     6.600000e+07  1.100000e+08
WeightedAverageNumberDilutedSharesOutstandingAd... shares  2.946100e+07  3.445000e+07
WeightedAverageNumberOfDilutedSharesOutstanding    shares  5.500281e+09  5.251692e+09
WeightedAverageNumberOfSharesOutstandingBasic      shares  5.470820e+09  5.217242e+09

Angler.query10Q(self, ticker_or_CIK, periods)

Get company 10-Q reports for selected periods.

Parameters:

  • ticker_or_CIK : string or int

    • the ticker or CIK number of the company

  • periods : int or iterable of ints, tuple or iterable of tuples

    • the periods of interest in (year, quarter) format

Returns:

  • Form10Q

    • returns a Form10Q object with the selected query

Example usage:

# the following commands are equivalent Angler.query10Q() calls
>>> instance.query10Q("AAPL", 2019)
>>> instance.query10Q("AAPL", [(2019, "Q1"), (2019, "Q2"), (2019, "Q3")])
fy                                                                 2019
fp                                                                   Q1            Q2            Q3
tag                                                uom
AccountsPayableCurrent                             USD     5.588800e+10  3.044300e+10  5.588800e+10
AccountsReceivableNetCurrent                       USD     2.318600e+10  1.508500e+10  2.318600e+10
AccruedIncomeTaxesNoncurrent                       USD     3.358900e+10  3.098600e+10  3.358900e+10
AccumulatedDepreciationDepletionAndAmortization... USD     4.909900e+10  5.429000e+10  4.909900e+10
AccumulatedOtherComprehensiveIncomeLossNetOfTax    USD    -3.454000e+09 -1.499000e+09 -6.390000e+08
...                                                                 ...           ...           ...
UnrecognizedTaxBenefitsThatWouldImpactEffective... USD     8.200000e+09  7.300000e+09  8.100000e+09
UnrecordedUnconditionalPurchaseObligationBalanc... USD     7.400000e+09  7.600000e+09  8.100000e+09
WeightedAverageNumberDilutedSharesOutstandingAd... shares  4.491000e+07  2.657500e+07  3.074700e+07
WeightedAverageNumberOfDilutedSharesOutstanding    shares  5.157787e+09  4.700646e+09  4.601380e+09
WeightedAverageNumberOfSharesOutstandingBasic      shares  5.112877e+09  4.704945e+09  4.660175e+09
# additionally, one can query multiple years
>>> instance.query10Q("AAPL", [2018, 2019])
fy                                                                 2018                ...          2019
fp                                                                   Q1            Q2  ...            Q2            Q3
tag                                                uom                                 ...
AccountsPayableCurrent                             USD     6.298500e+10  4.904900e+10  ...  3.044300e+10  5.588800e+10
AccountsReceivableNetCurrent                       USD     2.344000e+10  1.787400e+10  ...  1.508500e+10  2.318600e+10
AccruedIncomeTaxesNoncurrent                       USD     3.491300e+10  2.570000e+08  ...  3.098600e+10  3.358900e+10
AccruedLiabilitiesCurrent                          USD     2.574400e+10  2.574400e+10  ...           NaN           NaN
AccumulatedDepreciationDepletionAndAmortization... USD     4.129300e+10  4.129300e+10  ...  5.429000e+10  4.909900e+10
...                                                                 ...           ...  ...           ...           ...
UnrecognizedTaxBenefitsThatWouldImpactEffective... USD     7.700000e+09  8.200000e+09  ...  7.300000e+09  8.100000e+09
UnrecordedUnconditionalPurchaseObligationBalanc... USD     8.700000e+09  8.300000e+09  ...  7.600000e+09  8.100000e+09
WeightedAverageNumberDilutedSharesOutstandingAd... shares  2.933400e+07  3.589700e+07  ...  2.657500e+07  3.074700e+07
WeightedAverageNumberOfDilutedSharesOutstanding    shares  5.327995e+09  5.261688e+09  ...  4.700646e+09  4.601380e+09
WeightedAverageNumberOfSharesOutstandingBasic      shares  5.298661e+09  5.225791e+09  ...  4.704945e+09  4.660175e+09

Angler.query(self, command)

Query your own custom command on the XBRL dataset in MySQL format.

Parameters:

  • command : string

    • the command string

Returns:

  • SQLAlchemy.engine.ResultProxy

    • the query result

Example usage:

>>> _, cik = Angler.queryCIK("aapl")
>>> command = "SELECT * FROM sub WHERE cik={cik}".format(cik=cik)
>>> instance.query(command).first()
('0000320193-17-000009', Decimal('320193'), 'APPLE INC', Decimal('3571'), 'US', 'CA', 'CUPERTINO', '95014', 'ONE INFINITE LOOP', '', '(408) 996-10', 'US', 'CA', 'CUPERTINO', '95014', 'ONE INFINITE LOOP', '', 'US', 'CA', Decimal('942404110'), 'APPLE COMPUTER INC', '19970808', '1-LAF', 0, '0930', '10-Q', datetime.date(2017, 6, 30), 2017, 'Q3', datetime.date(2017, 8, 2), datetime.datetime(2017, 8, 2, 16, 31), 0, 1, 'aapl-20170701.xml', Decimal('1'), '', '2017q3')

Angler.dispose(self)

Closes the connection to the database.

Example usage:

>>> instance.dispose()

Form Functions

The (parent) data manipulation function. The Form object offers some convenient data manipulation functions that apply to all (10-K and 10-Q) SEC forms. Form10K and Form10Q objects are subclasses of Form and therefore all Form functions apply to them.

Form.form(self)

Returns the contents of the Form object.

Returns:

  • pandas.DataFrame

    • the contents of the Form as a pandas dataframs

Example usage:

>>> form = instance.query10K("AAPL", 2019)
>>> form.form() # returns a Form10K object, a subclass of Form 
fy                                                                 2019
tag                                                uom
AccountsPayableCurrent                             USD     4.623600e+10
AccountsReceivableNetCurrent                       USD     2.292600e+10
AccruedIncomeTaxesNoncurrent                       USD     2.954500e+10
AccumulatedDepreciationDepletionAndAmortization... USD     5.857900e+10
AccumulatedOtherComprehensiveIncomeLossNetOfTax    USD    -5.840000e+08
...                                                                 ...
UnrecordedUnconditionalPurchaseObligationBalanc... USD     8.211000e+09
UnrecordedUnconditionalPurchaseObligationDueAft... USD     1.100000e+08
WeightedAverageNumberDilutedSharesOutstandingAd... shares  3.107900e+07
WeightedAverageNumberOfDilutedSharesOutstanding    shares  4.648913e+09
WeightedAverageNumberOfSharesOutstandingBasic      shares  4.617834e+09

To save your form to csv, use the Form.form() function then pandas.DataFrame.to_csv():

>>> pandas_dataframe = form.form()
>>> pandas_dataframe.to_csv(filepath) # specify filepath to save to

Note, one can print and perform basic indexing directly on the Form object:

>>> print(form)
...
>>> print(form[2019])
...

Form.filter(self, regex, index=’tag’)

Filter rows of the form by a specific keyword regular expression (regex).

Parameters:

  • regex : string

    • the regular expression to filter the rows by

  • index : string

    • the index (“tag” or “uom”) to apply the filter to; defaults to “tag”

Returns:

  • pandas.DataFrame

    • a pandas dataframe with the filtered results

Example usage:

>>> form = instance.query10Q("AAPL", [2018, 2019])
>>> form.filter("^NetIncomeLoss$")
fy                         2018                                      2019
fp                           Q1            Q2            Q3            Q1            Q2            Q3
tag           uom
NetIncomeLoss USD  2.006500e+10  1.382200e+10  1.151900e+10  1.996500e+10  1.156100e+10  1.004400e+10

Form.asset_sheet(self)

Filters the form to generate an asset sheet. Wrapper around form.filter("Asset|Assets").

Returns:

  • pandas.DataFrame

    • a pandas dataframe with just values pertaining to “assets”

Example usage:

>>> form = instance.query10K("aapl", 2019)
>>> form.asset_sheet()
fy                                                              2019
tag                                                uom
Assets                                             USD  3.385160e+11
AssetsCurrent                                      USD  1.628190e+11
AssetsNoncurrent                                   USD  1.756970e+11
DeferredTaxAssetsDeferredIncome                    USD  1.372000e+09
DeferredTaxAssetsGoodwillAndIntangibleAssets       USD  1.143300e+10
DeferredTaxAssetsLiabilitiesNet                    USD  8.045000e+09
DeferredTaxAssetsNet                               USD  1.964000e+10
DeferredTaxAssetsOther                             USD  6.970000e+08
DeferredTaxAssetsPropertyPlantAndEquipment         USD  1.370000e+08
DeferredTaxAssetsTaxDeferredExpenseCompensation... USD  7.490000e+08
DeferredTaxAssetsTaxDeferredExpenseReservesAndA... USD  5.389000e+09
DeferredTaxAssetsUnrealizedLossesOnAvailablefor... USD  0.000000e+00
DerivativeAssetsReductionforMasterNettingArrang... USD  2.700000e+09
IncreaseDecreaseInOtherOperatingAssets             USD -8.730000e+08
NoncurrentAssets                                   USD  3.737800e+10
OtherAssetsCurrent                                 USD  1.235200e+10
OtherAssetsNoncurrent                              USD  3.297800e+10

Form.liability_sheet(self)

Filters the form to generate a liability sheet. Wrapper around form.filter("Liability|Liabilities").

Returns:

  • pandas.DataFrame

    • a pandas dataframe with just values pertaining to liabilities

Example usage:

>>> form = instance.query10Q("AAPL", (2019, "Q2"))
>>> form.liability_sheet()
fy                                                              2019
fp                                                                Q2
tag                                                uom
ContractWithCustomerLiability                      USD  8.200000e+09
ContractWithCustomerLiabilityCurrent               USD  5.532000e+09
ContractWithCustomerLiabilityRevenueRecognized     USD  1.900000e+09
DerivativeLiabilitiesReductionforMasterNettingA... USD  1.700000e+09
IncreaseDecreaseInContractWithCustomerLiability    USD -5.400000e+08
IncreaseDecreaseInOtherOperatingLiabilities        USD -3.273000e+09
Liabilities                                        USD  2.361380e+11
LiabilitiesAndStockholdersEquity                   USD  3.419980e+11
LiabilitiesCurrent                                 USD  9.377200e+10
LiabilitiesNoncurrent                              USD  1.423660e+11
OtherAccruedLiabilitiesNoncurrent                  USD  2.117900e+10
OtherLiabilitiesCurrent                            USD  3.536800e+10
OtherLiabilitiesNoncurrent                         USD  5.216500e+10

Form.debt_sheet(self)

Filters the form to generate a debt sheet. Wrapper around form.filter("Debt|Debts").

Returns:

  • pandas.DataFrame

    • a pandas dataframe with just values pertaining to debts

Example usage:

>>> form = instance.query10Q("AAPL", 2019)
>>> form.debt_sheet()
fy                                                               2019
fp                                                                 Q1            Q2            Q3
tag                                                uom
AvailableForSaleDebtSecuritiesAccumulatedGrossU... USD   9.400000e+07  3.850000e+08  8.920000e+08
AvailableForSaleDebtSecuritiesAccumulatedGrossU... USD   3.871000e+09  1.532000e+09  4.610000e+08
AvailableForSaleDebtSecuritiesAmortizedCostBasis   USD   2.488120e+11  2.265580e+11  2.101790e+11
AvailableForSaleSecuritiesDebtSecurities           USD   2.450350e+11  2.254110e+11  2.106100e+11
...
ProceedsFromShortTermDebtMaturingInMoreThanThre... USD   2.166000e+09  1.023500e+10  1.297700e+10
RepaymentsOfLongTermDebt                           USD            NaN  2.500000e+09  5.500000e+09
RepaymentsOfShortTermDebtMaturingInMoreThanThre... USD   4.171000e+09  7.787000e+09  1.128300e+10
ShortTermDebtWeightedAverageInterestRate           pure  2.390000e-02  2.560000e-02  2.490000e-02

Form.to_csv(self, path_or_buf, …)

Saves the form as a csv file. Wrapper around pandas.DataFrame.to_csv; follow that link for the full documentation.

Example usage:

>>> form = instance.query10Q("aapl", 2018)
>>> form.to_csv("Apple_2018_10Q")

Form10K Functions

Form10K represents a SEC form 10-K and is a subclass of Form, thus inheriting all of the functions included in the Form class.

Form10K.calc_ROE(self, as_list=False)

Calculates return on equity (ROE) ratio. ROE = (net income) / (total stockholders equity).

Parameters:

  • as_list : boolean

    • returns the values as a list if True, otherwise returns values in a dataframe; defaults to False

Returns:

  • list or pandas.DataFrame

    • a list or pandas dataframe detailing the ROE for every year in the query

Example usage:

>>> form10K = instance.query10K("aapl", [2017, 2018, 2019])
>>> form10K.calc_ROE()
fy             2017      2018      2019
tag uom
ROE ratio  0.360702  0.555601  0.610645

Form10K.calc_CurrentRatio(self, as_list=False)

Calculates the current ratio. CurrentRatio = (current assets) / (current liabilities)

Parameters:

  • as_list : boolean

    • returns the values as a list if True, otherwise returns values in a dataframe; defaults to False

Returns:

  • list or pandas.DataFrame

    • a list or pandas dataframe detailing the CurrentRatio for every year in the query

Example usage:

>>> form10K = instance.query10K("aapl", [2017, 2018, 2019])
>>> form10K.calc_CurrentRatio()
fy                      2017      2018      2019
tag          uom
CurrentRatio ratio  1.276063  1.123843  1.540126

Form10K.calc_DebtToEquity(self, as_list=False)

Calculates the debt to equity ratio. DebtToEquity = (total liabilities) / (total stockholders equity)

Parameters:

  • as_list : boolean

    • returns the values as a list if True, otherwise returns values in a dataframe; defaults to False

Returns:

  • list or pandas.DataFrame

    • a list or pandas dataframe detailing the DebtToEquity for every year in the query

Example usage:

>>> form10K = instance.query10K("aapl", [2017, 2018, 2019])
>>> form10K.calc_DebtToEquity()
fy                      2017      2018      2019
tag          uom
DebtToEquity ratio  1.799906  2.413301  2.741004

Form10K.calc_BookValue(self, as_list=False)

Calculates the book value. BookValue = (total assets) - (total liabilities)

Parameters:

  • as_list : boolean

    • returns the values as a list if True, otherwise returns values in a dataframe; defaults to False

Returns:

  • list or pandas.DataFrame

    • a list or pandas dataframe detailing the BookValue for every year in the query

Example usage:

>>> form10K = instance.query10K("aapl", [2017, 2018, 2019])
>>> form10K.calc_BookValue(as_list=True)
[1.340470e+11, 1.071470e+11, 9.048800e+10]

Form10Q Functions

Form10K represents a SEC form 10-Q and is a subclass of Form, thus inheriting all of the functions included in the Form class.

Currently, there are no functions specifically for Form10Q.