remove intrinio provider (#7575)

Remove the openbb-intrinio provider extension from the repository.
Reason: proprietary vendor with no internal access to any endpoint;
cannot build, develop or maintain.
This commit is contained in:
Danglewood
2026-07-08 03:18:20 -07:00
committed by GitHub
parent 3a237fa981
commit 6ba0fb59f8
87 changed files with 0 additions and 27863 deletions

View File

@@ -1,13 +0,0 @@
# OpenBB Intrinio Provider
This extension integrates the [Intrinio](https://intrinio.com/) data provider into the OpenBB Platform.
## Installation
To install the extension:
```bash
pip install openbb-intrinio
```
Documentation available [here](https://docs.openbb.co/platform/developer_guide/contributing).

View File

@@ -1 +0,0 @@
"""Intrinio provider."""

View File

@@ -1,116 +0,0 @@
"""Intrinio Provider Modules."""
from openbb_core.provider.abstract.provider import Provider
from openbb_intrinio.models.balance_sheet import IntrinioBalanceSheetFetcher
from openbb_intrinio.models.calendar_ipo import IntrinioCalendarIpoFetcher
from openbb_intrinio.models.cash_flow import IntrinioCashFlowStatementFetcher
from openbb_intrinio.models.company_filings import IntrinioCompanyFilingsFetcher
from openbb_intrinio.models.company_news import IntrinioCompanyNewsFetcher
from openbb_intrinio.models.currency_pairs import IntrinioCurrencyPairsFetcher
from openbb_intrinio.models.equity_historical import IntrinioEquityHistoricalFetcher
from openbb_intrinio.models.equity_info import IntrinioEquityInfoFetcher
from openbb_intrinio.models.equity_quote import IntrinioEquityQuoteFetcher
from openbb_intrinio.models.equity_search import IntrinioEquitySearchFetcher
from openbb_intrinio.models.etf_holdings import IntrinioEtfHoldingsFetcher
from openbb_intrinio.models.etf_info import IntrinioEtfInfoFetcher
from openbb_intrinio.models.etf_price_performance import (
IntrinioEtfPricePerformanceFetcher,
)
from openbb_intrinio.models.etf_search import IntrinioEtfSearchFetcher
from openbb_intrinio.models.financial_ratios import IntrinioFinancialRatiosFetcher
from openbb_intrinio.models.forward_ebitda_estimates import (
IntrinioForwardEbitdaEstimatesFetcher,
)
from openbb_intrinio.models.forward_eps_estimates import (
IntrinioForwardEpsEstimatesFetcher,
)
from openbb_intrinio.models.forward_pe_estimates import (
IntrinioForwardPeEstimatesFetcher,
)
from openbb_intrinio.models.forward_sales_estimates import (
IntrinioForwardSalesEstimatesFetcher,
)
from openbb_intrinio.models.fred_series import IntrinioFredSeriesFetcher
from openbb_intrinio.models.historical_attributes import (
IntrinioHistoricalAttributesFetcher,
)
from openbb_intrinio.models.historical_dividends import (
IntrinioHistoricalDividendsFetcher,
)
from openbb_intrinio.models.historical_market_cap import (
IntrinioHistoricalMarketCapFetcher,
)
from openbb_intrinio.models.income_statement import IntrinioIncomeStatementFetcher
from openbb_intrinio.models.index_historical import IntrinioIndexHistoricalFetcher
from openbb_intrinio.models.insider_trading import IntrinioInsiderTradingFetcher
# from openbb_intrinio.models.institutional_ownership import (
# IntrinioInstitutionalOwnershipFetcher,
# )
from openbb_intrinio.models.key_metrics import IntrinioKeyMetricsFetcher
from openbb_intrinio.models.latest_attributes import IntrinioLatestAttributesFetcher
from openbb_intrinio.models.market_snapshots import IntrinioMarketSnapshotsFetcher
from openbb_intrinio.models.options_chains import IntrinioOptionsChainsFetcher
from openbb_intrinio.models.options_snapshots import IntrinioOptionsSnapshotsFetcher
from openbb_intrinio.models.options_unusual import IntrinioOptionsUnusualFetcher
from openbb_intrinio.models.price_target_consensus import (
IntrinioPriceTargetConsensusFetcher,
)
from openbb_intrinio.models.reported_financials import IntrinioReportedFinancialsFetcher
from openbb_intrinio.models.search_attributes import (
IntrinioSearchAttributesFetcher,
)
from openbb_intrinio.models.share_statistics import IntrinioShareStatisticsFetcher
from openbb_intrinio.models.world_news import IntrinioWorldNewsFetcher
intrinio_provider = Provider(
name="intrinio",
website="https://intrinio.com",
description="""Intrinio is a financial data platform that provides real-time and
historical financial market data to businesses and developers through an API.""",
credentials=["api_key"],
fetcher_dict={
"BalanceSheet": IntrinioBalanceSheetFetcher,
"CalendarIpo": IntrinioCalendarIpoFetcher,
"CashFlowStatement": IntrinioCashFlowStatementFetcher,
"CompanyFilings": IntrinioCompanyFilingsFetcher,
"CompanyNews": IntrinioCompanyNewsFetcher,
"CurrencyPairs": IntrinioCurrencyPairsFetcher,
"EquityHistorical": IntrinioEquityHistoricalFetcher,
"EquityInfo": IntrinioEquityInfoFetcher,
"EquityQuote": IntrinioEquityQuoteFetcher,
"EquitySearch": IntrinioEquitySearchFetcher,
"EtfHistorical": IntrinioEquityHistoricalFetcher,
"EtfHoldings": IntrinioEtfHoldingsFetcher,
"EtfInfo": IntrinioEtfInfoFetcher,
"EtfPricePerformance": IntrinioEtfPricePerformanceFetcher,
"EtfSearch": IntrinioEtfSearchFetcher,
"FinancialRatios": IntrinioFinancialRatiosFetcher,
"ForwardEbitdaEstimates": IntrinioForwardEbitdaEstimatesFetcher,
"ForwardEpsEstimates": IntrinioForwardEpsEstimatesFetcher,
"ForwardPeEstimates": IntrinioForwardPeEstimatesFetcher,
"ForwardSalesEstimates": IntrinioForwardSalesEstimatesFetcher,
"FredSeries": IntrinioFredSeriesFetcher,
"HistoricalAttributes": IntrinioHistoricalAttributesFetcher,
"HistoricalDividends": IntrinioHistoricalDividendsFetcher,
"HistoricalMarketCap": IntrinioHistoricalMarketCapFetcher,
"IncomeStatement": IntrinioIncomeStatementFetcher,
"IndexHistorical": IntrinioIndexHistoricalFetcher,
"InsiderTrading": IntrinioInsiderTradingFetcher,
# "InstitutionalOwnership": IntrinioInstitutionalOwnershipFetcher, # Disabled due to unreliable Intrinio endpoint
"KeyMetrics": IntrinioKeyMetricsFetcher,
"LatestAttributes": IntrinioLatestAttributesFetcher,
"MarketSnapshots": IntrinioMarketSnapshotsFetcher,
"OptionsChains": IntrinioOptionsChainsFetcher,
"OptionsSnapshots": IntrinioOptionsSnapshotsFetcher,
"OptionsUnusual": IntrinioOptionsUnusualFetcher,
"PriceTargetConsensus": IntrinioPriceTargetConsensusFetcher,
"ReportedFinancials": IntrinioReportedFinancialsFetcher,
"SearchAttributes": IntrinioSearchAttributesFetcher,
"ShareStatistics": IntrinioShareStatisticsFetcher,
"WorldNews": IntrinioWorldNewsFetcher,
},
repr_name="Intrinio",
deprecated_credentials={"API_INTRINIO_KEY": "intrinio_api_key"},
instructions="Go to: https://intrinio.com/starter-plan\n\n![Intrinio](https://user-images.githubusercontent.com/85772166/219207556-fcfee614-59f1-46ae-bff4-c63dd2f6991d.png)\n\nAn API key will be issued with a subscription. Find the token value within the account dashboard.", # noqa: E501 pylint: disable=line-too-long
)

View File

@@ -1 +0,0 @@
"""Intrinio models directory."""

View File

@@ -1,500 +0,0 @@
"""Intrinio Balance Sheet Model."""
# pylint: disable=unused-argument
from typing import Any, Literal
from warnings import warn
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.balance_sheet import (
BalanceSheetData,
BalanceSheetQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import ClientResponse, amake_requests
from openbb_intrinio.utils.helpers import get_data_one
from pydantic import Field, field_validator, model_validator
class IntrinioBalanceSheetQueryParams(BalanceSheetQueryParams):
"""Intrinio Balance Sheet Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_fundamentals_v2
Source: https://docs.intrinio.com/documentation/web_api/get_fundamental_standardized_financials_v2
"""
__json_schema_extra__ = {
"period": {
"choices": ["annual", "quarter"],
}
}
period: Literal["annual", "quarter"] = Field(
default="annual",
description=QUERY_DESCRIPTIONS.get("period", ""),
)
fiscal_year: int | None = Field(
default=None,
description="The specific fiscal year. Reports do not go beyond 2008.",
)
@field_validator("symbol", mode="after", check_fields=False)
@classmethod
def handle_symbol(cls, v) -> str:
"""Handle symbols with a dash and replace it with a dot for Intrinio."""
return v.replace("-", ".")
class IntrinioBalanceSheetData(BalanceSheetData):
"""Intrinio Balance Sheet Data."""
__alias_dict__ = {
"cash_and_cash_equivalents": "cashandequivalents",
"restricted_cash": "restrictedcash",
"short_term_investments": "shortterminvestments",
"federal_funds_sold": "fedfundssold",
"note_and_lease_receivable": "notereceivable",
"interest_bearing_deposits_at_other_banks": "interestbearingdepositsatotherbanks",
"accounts_receivable": "accountsreceivable",
"time_deposits_placed_and_other_short_term_investments": "timedepositsplaced",
"inventories": "netinventory",
"trading_account_securities": "tradingaccountsecurities",
"prepaid_expenses": "prepaidexpenses",
"loans_and_leases": "loansandleases",
"allowance_for_loan_and_lease_losses": "allowanceforloanandleaselosses",
"current_deferred_refundable_income_taxes": "currentdeferredtaxassets",
"other_current_assets": "othercurrentassets",
"loans_and_leases_net_of_allowance": "netloansandleases",
"other_current_non_operating_assets": "othercurrentnonoperatingassets",
"loans_held_for_sale": "loansheldforsale",
"total_current_assets": "totalcurrentassets",
"accrued_investment_income": "accruedinvestmentincome",
"plant_property_equipment_gross": "grossppe",
"customer_and_other_receivables": "customerandotherreceivables",
"accumulated_depreciation": "accumulateddepreciation",
"premises_and_equipment_net": "netpremisesandequipment",
"plant_property_equipment_net": "netppe",
"mortgage_servicing_rights": "mortgageservicingrights",
"long_term_investments": "longterminvestments",
"unearned_premiums_asset": "unearnedpremiumsdebit",
"non_current_note_lease_receivables": "noncurrentnotereceivables",
"deferred_acquisition_cost": "deferredacquisitioncost",
"goodwill": "goodwill",
"separate_account_business_assets": "separateaccountbusinessassets",
"intangible_assets": "intangibleassets",
"non_current_deferred_refundable_income_taxes": "noncurrentdeferredtaxassets",
"employee_benefit_assets": "employeebenefitassets",
"other_assets": "otherassets",
"other_non_current_operating_assets": "othernoncurrentassets",
"total_assets": "totalassets",
"other_non_current_non_operating_assets": "othernoncurrentnonoperatingassets",
"non_interest_bearing_deposits": "noninterestbearingdeposits",
"interest_bearing_deposits": "interestbearingdeposits",
"total_non_current_assets": "totalnoncurrentassets",
"federal_funds_purchased_and_securities_sold": "fedfundspurchased",
"short_term_debt": "shorttermdebt",
"bankers_acceptance_out_standing": "bankersacceptances",
"accrued_interest_payable": "accruedinterestpayable",
"accounts_payable": "accountspayable",
"accrued_expenses": "accruedexpenses",
"other_short_term_payables": "othershorttermpayables",
"long_term_debt": "longtermdebt",
"customer_deposits": "customerdeposits",
"capital_lease_obligations": "capitalleaseobligations",
"dividends_payable": "dividendspayable",
"claims_and_claim_expense": "claimsandclaimexpenses",
"current_deferred_revenue": "currentdeferredrevenue",
"future_policy_benefits": "futurepolicybenefits",
"current_deferred_payable_income_tax_liabilities": "currentdeferredtaxliabilities",
"current_employee_benefit_liabilities": "currentemployeebenefitliabilities",
"unearned_premiums_liability": "unearnedpremiumscredit",
"other_taxes_payable": "othertaxespayable",
"policy_holder_funds": "policyholderfunds",
"other_current_liabilities": "othercurrentliabilities",
"participating_policy_holder_equity": "participatingpolicyholderequity",
"other_current_non_operating_liabilities": "othercurrentnonoperatingliabilities",
"separate_account_business_liabilities": "separateaccountbusinessliabilities",
"total_current_liabilities": "totalcurrentliabilities",
"other_long_term_liabilities": "otherlongtermliabilities",
"total_liabilities": "totalliabilities",
"commitments_contingencies": "commitmentsandcontingencies",
"asset_retirement_reserve_litigation_obligation": "assetretirementandlitigationobligation",
"redeemable_non_controlling_interest": "redeemablenoncontrollinginterest",
"non_current_deferred_revenue": "noncurrentdeferredrevenue",
"preferred_stock": "totalpreferredequity",
"common_stock": "commonequity",
"non_current_deferred_payable_income_tax_liabilities": "noncurrentdeferredtaxliabilities",
"non_current_employee_benefit_liabilities": "noncurrentemployeebenefitliabilities",
"retained_earnings": "retainedearnings",
"other_non_current_operating_liabilities": "othernoncurrentliabilities",
"treasury_stock": "treasurystock",
"accumulated_other_comprehensive_income": "aoci",
"other_non_current_non_operating_liabilities": "othernoncurrentnonoperatingliabilities",
"other_equity_adjustments": "otherequity",
"total_non_current_liabilities": "totalnoncurrentliabilities",
"total_common_equity": "totalcommonequity",
"total_preferred_common_equity": "totalequity",
"non_controlling_interest": "noncontrollinginterests",
"total_equity_non_controlling_interests": "totalequityandnoncontrollinginterests",
"total_liabilities_shareholders_equity": "totalliabilitiesandequity",
}
reported_currency: str | None = Field(
description="The currency in which the balance sheet is reported.",
default=None,
)
cash_and_cash_equivalents: float | None = Field(
description="Cash and cash equivalents.", default=None
)
cash_and_due_from_banks: float | None = Field(
description="Cash and due from banks.", default=None
)
restricted_cash: float | None = Field(description="Restricted cash.", default=None)
short_term_investments: float | None = Field(
description="Short term investments.", default=None
)
federal_funds_sold: float | None = Field(
description="Federal funds sold.", default=None
)
accounts_receivable: float | None = Field(
description="Accounts receivable.", default=None
)
note_and_lease_receivable: float | None = Field(
description="Note and lease receivable. (Vendor non-trade receivables)",
default=None,
)
inventories: float | None = Field(description="Net Inventories.", default=None)
customer_and_other_receivables: float | None = Field(
description="Customer and other receivables.", default=None
)
interest_bearing_deposits_at_other_banks: float | None = Field(
description="Interest bearing deposits at other banks.", default=None
)
time_deposits_placed_and_other_short_term_investments: float | None = Field(
description="Time deposits placed and other short term investments.",
default=None,
)
trading_account_securities: float | None = Field(
description="Trading account securities.", default=None
)
loans_and_leases: float | None = Field(
description="Loans and leases.", default=None
)
allowance_for_loan_and_lease_losses: float | None = Field(
description="Allowance for loan and lease losses.", default=None
)
current_deferred_refundable_income_taxes: float | None = Field(
description="Current deferred refundable income taxes.", default=None
)
other_current_assets: float | None = Field(
description="Other current assets.", default=None
)
loans_and_leases_net_of_allowance: float | None = Field(
description="Loans and leases net of allowance.", default=None
)
accrued_investment_income: float | None = Field(
description="Accrued investment income.", default=None
)
other_current_non_operating_assets: float | None = Field(
description="Other current non-operating assets.", default=None
)
loans_held_for_sale: float | None = Field(
description="Loans held for sale.", default=None
)
prepaid_expenses: float | None = Field(
description="Prepaid expenses.", default=None
)
total_current_assets: float | None = Field(
description="Total current assets.", default=None
)
plant_property_equipment_gross: float | None = Field(
description="Plant property equipment gross.", default=None
)
accumulated_depreciation: float | None = Field(
description="Accumulated depreciation.", default=None
)
premises_and_equipment_net: float | None = Field(
description="Net premises and equipment.", default=None
)
plant_property_equipment_net: float | None = Field(
description="Net plant property equipment.", default=None
)
long_term_investments: float | None = Field(
description="Long term investments.", default=None
)
mortgage_servicing_rights: float | None = Field(
description="Mortgage servicing rights.", default=None
)
unearned_premiums_asset: float | None = Field(
description="Unearned premiums asset.", default=None
)
non_current_note_lease_receivables: float | None = Field(
description="Non-current note lease receivables.", default=None
)
deferred_acquisition_cost: float | None = Field(
description="Deferred acquisition cost.", default=None
)
goodwill: float | None = Field(description="Goodwill.", default=None)
separate_account_business_assets: float | None = Field(
description="Separate account business assets.", default=None
)
non_current_deferred_refundable_income_taxes: float | None = Field(
description="Noncurrent deferred refundable income taxes.", default=None
)
intangible_assets: float | None = Field(
description="Intangible assets.", default=None
)
employee_benefit_assets: float | None = Field(
description="Employee benefit assets.", default=None
)
other_assets: float | None = Field(description="Other assets.", default=None)
other_non_current_operating_assets: float | None = Field(
description="Other noncurrent operating assets.", default=None
)
other_non_current_non_operating_assets: float | None = Field(
description="Other noncurrent non-operating assets.", default=None
)
interest_bearing_deposits: float | None = Field(
description="Interest bearing deposits.", default=None
)
total_non_current_assets: float | None = Field(
description="Total noncurrent assets.", default=None
)
total_assets: float | None = Field(description="Total assets.", default=None)
non_interest_bearing_deposits: float | None = Field(
description="Non interest bearing deposits.", default=None
)
federal_funds_purchased_and_securities_sold: float | None = Field(
description="Federal funds purchased and securities sold.", default=None
)
bankers_acceptance_outstanding: float | None = Field(
description="Bankers acceptance outstanding.", default=None
)
short_term_debt: float | None = Field(description="Short term debt.", default=None)
accounts_payable: float | None = Field(
description="Accounts payable.", default=None
)
current_deferred_revenue: float | None = Field(
description="Current deferred revenue.", default=None
)
current_deferred_payable_income_tax_liabilities: float | None = Field(
description="Current deferred payable income tax liabilities.", default=None
)
accrued_interest_payable: float | None = Field(
description="Accrued interest payable.", default=None
)
accrued_expenses: float | None = Field(
description="Accrued expenses.", default=None
)
other_short_term_payables: float | None = Field(
description="Other short term payables.", default=None
)
customer_deposits: float | None = Field(
description="Customer deposits.", default=None
)
dividends_payable: float | None = Field(
description="Dividends payable.", default=None
)
claims_and_claim_expense: float | None = Field(
description="Claims and claim expense.", default=None
)
future_policy_benefits: float | None = Field(
description="Future policy benefits.", default=None
)
current_employee_benefit_liabilities: float | None = Field(
description="Current employee benefit liabilities.", default=None
)
unearned_premiums_liability: float | None = Field(
description="Unearned premiums liability.", default=None
)
other_taxes_payable: float | None = Field(
description="Other taxes payable.", default=None
)
policy_holder_funds: float | None = Field(
description="Policy holder funds.", default=None
)
other_current_liabilities: float | None = Field(
description="Other current liabilities.", default=None
)
other_current_non_operating_liabilities: float | None = Field(
description="Other current non-operating liabilities.", default=None
)
separate_account_business_liabilities: float | None = Field(
description="Separate account business liabilities.", default=None
)
total_current_liabilities: float | None = Field(
description="Total current liabilities.", default=None
)
long_term_debt: float | None = Field(description="Long term debt.", default=None)
other_long_term_liabilities: float | None = Field(
description="Other long term liabilities.", default=None
)
non_current_deferred_revenue: float | None = Field(
description="Non-current deferred revenue.", default=None
)
non_current_deferred_payable_income_tax_liabilities: float | None = Field(
description="Non-current deferred payable income tax liabilities.", default=None
)
non_current_employee_benefit_liabilities: float | None = Field(
description="Non-current employee benefit liabilities.", default=None
)
other_non_current_operating_liabilities: float | None = Field(
description="Other non-current operating liabilities.", default=None
)
other_non_current_non_operating_liabilities: float | None = Field(
description="Other non-current, non-operating liabilities.", default=None
)
total_non_current_liabilities: float | None = Field(
description="Total non-current liabilities.", default=None
)
capital_lease_obligations: float | None = Field(
description="Capital lease obligations.", default=None
)
asset_retirement_reserve_litigation_obligation: float | None = Field(
description="Asset retirement reserve litigation obligation.", default=None
)
total_liabilities: float | None = Field(
description="Total liabilities.", default=None
)
commitments_contingencies: float | None = Field(
description="Commitments contingencies.", default=None
)
redeemable_non_controlling_interest: float | None = Field(
description="Redeemable non-controlling interest.", default=None
)
preferred_stock: float | None = Field(description="Preferred stock.", default=None)
common_stock: float | None = Field(description="Common stock.", default=None)
retained_earnings: float | None = Field(
description="Retained earnings.", default=None
)
treasury_stock: float | None = Field(description="Treasury stock.", default=None)
accumulated_other_comprehensive_income: float | None = Field(
description="Accumulated other comprehensive income.", default=None
)
participating_policy_holder_equity: float | None = Field(
description="Participating policy holder equity.", default=None
)
other_equity_adjustments: float | None = Field(
description="Other equity adjustments.", default=None
)
total_common_equity: float | None = Field(
description="Total common equity.", default=None
)
total_preferred_common_equity: float | None = Field(
description="Total preferred common equity.", default=None
)
non_controlling_interest: float | None = Field(
description="Non-controlling interest.", default=None
)
total_equity_non_controlling_interests: float | None = Field(
description="Total equity non-controlling interests.", default=None
)
total_liabilities_shareholders_equity: float | None = Field(
description="Total liabilities and shareholders equity.", default=None
)
@model_validator(mode="before")
@classmethod
def replace_zero(cls, values): # pylint: disable=no-self-argument
"""Check for zero values and replace with None."""
return (
{k: None if v == 0 else v for k, v in values.items()}
if isinstance(values, dict)
else values
)
class IntrinioBalanceSheetFetcher(
Fetcher[
IntrinioBalanceSheetQueryParams,
list[IntrinioBalanceSheetData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioBalanceSheetQueryParams:
"""Transform the query params."""
return IntrinioBalanceSheetQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioBalanceSheetQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
statement_code = "balance_sheet_statement"
fundamentals_data: dict = {}
base_url = "https://api-v2.intrinio.com"
period = "FY" if query.period == "annual" else "QTR"
fundamentals_url = (
f"{base_url}/companies/{query.symbol}"
f"/fundamentals?statement_code={statement_code}&type={period}"
)
if query.fiscal_year is not None:
if query.fiscal_year < 2008:
warn("Financials data is only available from 2008 and later.")
query.fiscal_year = 2008
fundamentals_url = fundamentals_url + f"&fiscal_year={query.fiscal_year}"
fundamentals_url = fundamentals_url + f"&api_key={api_key}"
fundamentals_data = (await get_data_one(fundamentals_url, **kwargs)).get(
"fundamentals", []
)
fiscal_periods = [
f"{item['fiscal_year']}-{item['fiscal_period']}"
for item in fundamentals_data
]
fiscal_periods = fiscal_periods[: query.limit]
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
statement_data = await response.json() # type: ignore
return {
"period_ending": statement_data["fundamental"]["end_date"], # type: ignore
"fiscal_year": statement_data["fundamental"]["fiscal_year"], # type: ignore
"fiscal_period": statement_data["fundamental"]["fiscal_period"], # type: ignore
"financials": statement_data["standardized_financials"], # type: ignore
}
urls = [
f"{base_url}/fundamentals/{query.symbol}-{statement_code}-{p}/standardized_financials?api_key={api_key}"
for p in fiscal_periods
]
return await amake_requests(urls, callback, **kwargs) # type: ignore
@staticmethod
def transform_data(
query: IntrinioBalanceSheetQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioBalanceSheetData]:
"""Return the transformed data."""
transformed_data: list[IntrinioBalanceSheetData] = []
period = "FY" if query.period == "annual" else "QTR"
units = []
for item in data:
sub_dict: dict[str, Any] = {}
for sub_item in item["financials"]:
field_name = sub_item["data_tag"]["tag"]
unit = sub_item["data_tag"].get("unit", "")
if unit and len(unit) == 3:
units.append(unit)
sub_dict[field_name] = (
float(sub_item["value"])
if sub_item["value"] and sub_item["value"] != 0
else None
)
sub_dict["period_ending"] = item["period_ending"]
sub_dict["fiscal_year"] = item["fiscal_year"]
sub_dict["fiscal_period"] = item["fiscal_period"]
sub_dict["reported_currency"] = list(set(units))[0]
# Intrinio does not return Q4 data but FY data instead
if period == "QTR" and item["fiscal_period"] == "FY":
sub_dict["fiscal_period"] = "Q4"
transformed_data.append(IntrinioBalanceSheetData(**sub_dict))
return transformed_data

View File

@@ -1,192 +0,0 @@
"""Intrinio IPO Calendar Model."""
# pylint: disable=unused-argument
from typing import Any, Literal
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.calendar_ipo import (
CalendarIpoData,
CalendarIpoQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_one
from openbb_intrinio.utils.references import IntrinioCompany, IntrinioSecurity
from pydantic import Field
class IntrinioCalendarIpoQueryParams(CalendarIpoQueryParams):
"""Intrinio IPO Calendar Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_ipos_v2
"""
__alias_dict__ = {
"symbol": "ticker",
"limit": "page_size",
"min_value": "offer_amount_greater_than",
"max_value": "offer_amount_less_than",
}
status: Literal["upcoming", "priced", "withdrawn"] | None = Field(
description="Status of the IPO. [upcoming, priced, or withdrawn]", default=None
)
min_value: int | None = Field(
description="Return IPOs with an offer dollar amount greater than the given amount.",
default=None,
)
max_value: int | None = Field(
description="Return IPOs with an offer dollar amount less than the given amount.",
default=None,
)
class IntrinioCalendarIpoData(CalendarIpoData):
"""Intrinio IPO Calendar Data."""
__alias_dict__ = {"symbol": "ticker", "ipo_date": "date"}
status: Literal["upcoming", "priced", "withdrawn"] | None = Field(
description=(
"The status of the IPO. Upcoming IPOs have not taken place yet but are expected to. "
"Priced IPOs have taken place. Withdrawn IPOs were expected to take place, but were subsequently withdrawn."
),
default=None,
)
exchange: str | None = Field(
description=(
"The acronym of the stock exchange that the company is going to trade publicly on. Typically NYSE or NASDAQ."
),
default=None,
)
offer_amount: float | None = Field(
description="The total dollar amount of shares offered in the IPO. Typically this is share price * share count",
default=None,
)
share_price: float | None = Field(
description="The price per share at which the IPO was offered.", default=None
)
share_price_lowest: float | None = Field(
description=(
"The expected lowest price per share at which the IPO will be offered. "
"Before an IPO is priced, companies typically provide a range of prices per share at which "
"they expect to offer the IPO (typically available for upcoming IPOs)."
),
default=None,
)
share_price_highest: float | None = Field(
description=(
"The expected highest price per share at which the IPO will be offered. "
"Before an IPO is priced, companies typically provide a range of prices per share at which "
"they expect to offer the IPO (typically available for upcoming IPOs)."
),
default=None,
)
share_count: int | None = Field(
description="The number of shares offered in the IPO.", default=None
)
share_count_lowest: int | None = Field(
description=(
"The expected lowest number of shares that will be offered in the IPO. Before an IPO is priced, "
"companies typically provide a range of shares that they expect to offer in the IPO "
"(typically available for upcoming IPOs)."
),
default=None,
)
share_count_highest: int | None = Field(
description=(
"The expected highest number of shares that will be offered in the IPO. Before an IPO is priced, "
"companies typically provide a range of shares that they expect to offer in the IPO "
"(typically available for upcoming IPOs)."
),
default=None,
)
announcement_url: str | None = Field(
description="The URL to the company's announcement of the IPO", default=None
)
sec_report_url: str | None = Field(
description=(
"The URL to the company's S-1, S-1/A, F-1, or F-1/A SEC filing, which is required to be filed "
"before an IPO takes place."
),
default=None,
)
open_price: float | None = Field(
description="The opening price at the beginning of the first trading day (only available for priced IPOs).",
default=None,
)
close_price: float | None = Field(
description="The closing price at the end of the first trading day (only available for priced IPOs).",
default=None,
)
volume: int | None = Field(
description="The volume at the end of the first trading day (only available for priced IPOs).",
default=None,
)
day_change: float | None = Field(
description=(
"The percentage change between the open price and the close price on the first trading day "
"(only available for priced IPOs)."
),
default=None,
)
week_change: float | None = Field(
description=(
"The percentage change between the open price on the first trading day and the close price approximately "
"a week after the first trading day (only available for priced IPOs)."
),
default=None,
)
month_change: float | None = Field(
description=(
"The percentage change between the open price on the first trading day and the close price approximately "
"a month after the first trading day (only available for priced IPOs)."
),
default=None,
)
id: str | None = Field(description="The Intrinio ID of the IPO.", default=None)
company: IntrinioCompany | None = Field(
description="The company that is going public via the IPO.", default=None
)
security: IntrinioSecurity | None = Field(
description="The primary Security for the Company that is going public via the IPO",
default=None,
)
class IntrinioCalendarIpoFetcher(
Fetcher[IntrinioCalendarIpoQueryParams, list[IntrinioCalendarIpoData]]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioCalendarIpoQueryParams:
"""Transform the query params."""
return IntrinioCalendarIpoQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioCalendarIpoQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/companies/ipos"
query_str = get_querystring(query.model_dump(by_alias=True), [])
url = f"{base_url}?{query_str}&api_key={api_key}"
data = await get_data_one(url, **kwargs)
return data.get("initial_public_offerings", [])
@staticmethod
def transform_data(
query: IntrinioCalendarIpoQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioCalendarIpoData]:
"""Return the transformed data."""
if not data:
raise EmptyDataError("The request was returned empty.")
return [IntrinioCalendarIpoData.model_validate(d) for d in data]

View File

@@ -1,336 +0,0 @@
"""Intrinio Cash Flow Statement Model."""
# pylint: disable=unused-argument
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.cash_flow import (
CashFlowStatementData,
CashFlowStatementQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import ClientResponse, amake_requests
from openbb_intrinio.utils.helpers import get_data_one
from pydantic import Field, field_validator, model_validator
class IntrinioCashFlowStatementQueryParams(CashFlowStatementQueryParams):
"""Intrinio Cash Flow Statement Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_fundamentals_v2
Source: https://docs.intrinio.com/documentation/web_api/get_fundamental_standardized_financials_v2
"""
__json_schema_extra__ = {
"period": {
"choices": ["annual", "quarter", "ttm", "ytd"],
}
}
period: Literal["annual", "quarter", "ttm", "ytd"] = Field(
default="annual",
description=QUERY_DESCRIPTIONS.get("period", ""),
)
fiscal_year: int | None = Field(
default=None,
description="The specific fiscal year. Reports do not go beyond 2008.",
)
@field_validator("symbol", mode="after", check_fields=False)
@classmethod
def handle_symbol(cls, v) -> str:
"""Handle symbols with a dash and replace it with a dot for Intrinio."""
return v.replace("-", ".")
class IntrinioCashFlowStatementData(CashFlowStatementData):
"""Intrinio Cash Flow Statement Data."""
__alias_dict__ = {
"cash_and_equivalents": "cashandequivalents",
"acquisitions": "acquisitions",
"amortization_expense": "amortizationexpense",
"cash_income_taxes_paid": "cashincometaxespaid",
"cash_interest_paid": "cashinterestpaid",
"cash_interest_received": "cashinterestreceived",
"depreciation_expense": "depreciationexpense",
"divestitures": "divestitures",
"effect_of_exchange_rate_changes": "effectofexchangeratechanges",
"changes_in_operating_assets_and_liabilities": "increasedecreaseinoperatingcapital",
"issuance_of_common_equity": "issuanceofcommonequity",
"issuance_of_debt": "issuanceofdebt",
"issuance_of_preferred_equity": "issuanceofpreferredequity",
"loans_held_for_sale": "loansheldforsalenet",
"net_cash_from_continuing_financing_activities": "netcashfromcontinuingfinancingactivities",
"net_cash_from_continuing_investing_activities": "netcashfromcontinuinginvestingactivities",
"net_cash_from_continuing_operating_activities": "netcashfromcontinuingoperatingactivities",
"net_cash_from_discontinued_financing_activities": "netcashfromdiscontinuedfinancingactivities",
"net_cash_from_discontinued_investing_activities": "netcashfromdiscontinuedinvestingactivities",
"net_cash_from_discontinued_operating_activities": "netcashfromdiscontinuedoperatingactivities",
"net_cash_from_financing_activities": "netcashfromfinancingactivities",
"net_cash_from_investing_activities": "netcashfrominvestingactivities",
"net_cash_from_operating_activities": "netcashfromoperatingactivities",
"net_change_in_cash_and_equivalents": "netchangeincash",
"net_change_in_deposits": "netchangeindeposits",
"net_income": "netincome",
"net_income_continuing_operations": "netincomecontinuing",
"net_income_discontinued_operations": "netincomediscontinued",
"net_increase_in_fed_funds_sold": "netincreaseinfedfundssold",
"non_cash_adjustments_to_reconcile_net_income": "noncashadjustmentstonetincome",
"other_financing_activities": "otherfinancingactivitiesnet",
"other_investing_activities": "otherinvestingactivitiesnet",
"other_net_changes_in_cash": "othernetchangesincash",
"payment_of_dividends": "paymentofdividends",
"provision_for_loan_losses": "provisionforloanlosses",
"purchase_of_investments": "purchaseofinvestments",
"purchase_of_investment_securities": "purchaseofinvestments",
"purchase_of_property_plant_and_equipment": "purchaseofplantpropertyandequipment",
"repayment_of_debt": "repaymentofdebt",
"repurchase_of_common_equity": "repurchaseofcommonequity",
"repurchase_of_preferred_equity": "repurchaseofpreferredequity",
"sale_and_maturity_of_investments": "saleofinvestments",
"sale_of_property_plant_and_equipment": "saleofplantpropertyandequipment",
}
reported_currency: str | None = Field(
description="The currency in which the balance sheet is reported.",
default=None,
)
net_income_continuing_operations: float | None = Field(
default=None, description="Net Income (Continuing Operations)"
)
net_income_discontinued_operations: float | None = Field(
default=None, description="Net Income (Discontinued Operations)"
)
net_income: float | None = Field(
default=None, description="Consolidated Net Income."
)
provision_for_loan_losses: float | None = Field(
default=None, description="Provision for Loan Losses"
)
provision_for_credit_losses: float | None = Field(
default=None, description="Provision for credit losses"
)
depreciation_expense: float | None = Field(
default=None, description="Depreciation Expense."
)
amortization_expense: float | None = Field(
default=None, description="Amortization Expense."
)
share_based_compensation: float | None = Field(
default=None, description="Share-based compensation."
)
non_cash_adjustments_to_reconcile_net_income: float | None = Field(
default=None, description="Non-Cash Adjustments to Reconcile Net Income."
)
changes_in_operating_assets_and_liabilities: float | None = Field(
default=None, description="Changes in Operating Assets and Liabilities (Net)"
)
net_cash_from_continuing_operating_activities: float | None = Field(
default=None, description="Net Cash from Continuing Operating Activities"
)
net_cash_from_discontinued_operating_activities: float | None = Field(
default=None, description="Net Cash from Discontinued Operating Activities"
)
net_cash_from_operating_activities: float | None = Field(
default=None, description="Net Cash from Operating Activities"
)
divestitures: float | None = Field(default=None, description="Divestitures")
sale_of_property_plant_and_equipment: float | None = Field(
default=None, description="Sale of Property, Plant, and Equipment"
)
acquisitions: float | None = Field(default=None, description="Acquisitions")
purchase_of_investments: float | None = Field(
default=None, description="Purchase of Investments"
)
purchase_of_investment_securities: float | None = Field(
default=None, description="Purchase of Investment Securities"
)
sale_and_maturity_of_investments: float | None = Field(
default=None, description="Sale and Maturity of Investments"
)
loans_held_for_sale: float | None = Field(
default=None, description="Loans Held for Sale (Net)"
)
purchase_of_property_plant_and_equipment: float | None = Field(
default=None, description="Purchase of Property, Plant, and Equipment"
)
other_investing_activities: float | None = Field(
default=None, description="Other Investing Activities (Net)"
)
net_cash_from_continuing_investing_activities: float | None = Field(
default=None, description="Net Cash from Continuing Investing Activities"
)
net_cash_from_discontinued_investing_activities: float | None = Field(
default=None, description="Net Cash from Discontinued Investing Activities"
)
net_cash_from_investing_activities: float | None = Field(
default=None, description="Net Cash from Investing Activities"
)
payment_of_dividends: float | None = Field(
default=None, description="Payment of Dividends"
)
repurchase_of_common_equity: float | None = Field(
default=None, description="Repurchase of Common Equity"
)
repurchase_of_preferred_equity: float | None = Field(
default=None, description="Repurchase of Preferred Equity"
)
issuance_of_common_equity: float | None = Field(
default=None, description="Issuance of Common Equity"
)
issuance_of_preferred_equity: float | None = Field(
default=None, description="Issuance of Preferred Equity"
)
issuance_of_debt: float | None = Field(default=None, description="Issuance of Debt")
repayment_of_debt: float | None = Field(
default=None, description="Repayment of Debt"
)
other_financing_activities: float | None = Field(
default=None, description="Other Financing Activities (Net)"
)
cash_interest_received: float | None = Field(
default=None, description="Cash Interest Received"
)
net_change_in_deposits: float | None = Field(
default=None, description="Net Change in Deposits"
)
net_increase_in_fed_funds_sold: float | None = Field(
default=None, description="Net Increase in Fed Funds Sold"
)
net_cash_from_continuing_financing_activities: float | None = Field(
default=None, description="Net Cash from Continuing Financing Activities"
)
net_cash_from_discontinued_financing_activities: float | None = Field(
default=None, description="Net Cash from Discontinued Financing Activities"
)
net_cash_from_financing_activities: float | None = Field(
default=None, description="Net Cash from Financing Activities"
)
effect_of_exchange_rate_changes: float | None = Field(
default=None, description="Effect of Exchange Rate Changes"
)
other_net_changes_in_cash: float | None = Field(
default=None, description="Other Net Changes in Cash"
)
net_change_in_cash_and_equivalents: float | None = Field(
default=None, description="Net Change in Cash and Equivalents"
)
cash_income_taxes_paid: float | None = Field(
default=None, description="Cash Income Taxes Paid"
)
cash_interest_paid: float | None = Field(
default=None, description="Cash Interest Paid"
)
@model_validator(mode="before")
@classmethod
def replace_zero(cls, values):
"""Check for zero values and replace with None."""
return (
{k: None if v == 0 else v for k, v in values.items()}
if isinstance(values, dict)
else values
)
class IntrinioCashFlowStatementFetcher(
Fetcher[
IntrinioCashFlowStatementQueryParams,
list[IntrinioCashFlowStatementData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioCashFlowStatementQueryParams:
"""Transform the query params."""
return IntrinioCashFlowStatementQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioCashFlowStatementQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
statement_code = "cash_flow_statement"
if query.period in ["quarter", "annual"]:
period_type = "FY" if query.period == "annual" else "QTR"
elif query.period in ["ttm", "ytd"]:
period_type = query.period.upper()
else:
raise OpenBBError(f"Period '{query.period}' not supported.")
base_url = "https://api-v2.intrinio.com"
fundamentals_url = (
f"{base_url}/companies/{query.symbol}"
f"/fundamentals?statement_code={statement_code}&type={period_type}"
)
if query.fiscal_year is not None:
if query.fiscal_year < 2008:
warn("Financials data is only available from 2008 and later.")
query.fiscal_year = 2008
fundamentals_url = fundamentals_url + f"&fiscal_year={query.fiscal_year}"
fundamentals_url = fundamentals_url + f"&api_key={api_key}"
fundamentals_data = (await get_data_one(fundamentals_url, **kwargs)).get(
"fundamentals", []
)
fiscal_periods = [
f"{item['fiscal_year']}-{item['fiscal_period']}"
for item in fundamentals_data
]
fiscal_periods = fiscal_periods[: query.limit]
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
statement_data = await response.json()
return {
"period_ending": statement_data["fundamental"]["end_date"], # type: ignore
"fiscal_period": statement_data["fundamental"]["fiscal_period"], # type: ignore
"fiscal_year": statement_data["fundamental"]["fiscal_year"], # type: ignore
"financials": statement_data["standardized_financials"], # type: ignore
}
intrinio_id = f"{query.symbol}-{statement_code}"
urls = [
f"{base_url}/fundamentals/{intrinio_id}-{period}/standardized_financials?api_key={api_key}"
for period in fiscal_periods
]
return await amake_requests(urls, callback, **kwargs)
@staticmethod
def transform_data(
query: IntrinioCashFlowStatementQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioCashFlowStatementData]:
"""Return the transformed data."""
transformed_data: list[IntrinioCashFlowStatementData] = []
units = []
for item in data:
sub_dict: dict[str, Any] = {}
for sub_item in item["financials"]:
unit = sub_item["data_tag"].get("unit", "")
if unit and len(unit) == 3:
units.append(unit)
field_name = sub_item["data_tag"]["tag"]
sub_dict[field_name] = (
float(sub_item["value"])
if sub_item["value"] and sub_item["value"] != 0
else None
)
sub_dict["period_ending"] = item["period_ending"]
sub_dict["fiscal_year"] = item["fiscal_year"]
sub_dict["fiscal_period"] = item["fiscal_period"]
sub_dict["reported_currency"] = list(set(units))[0]
transformed_data.append(IntrinioCashFlowStatementData(**sub_dict))
return transformed_data

View File

@@ -1,173 +0,0 @@
"""Intrinio Company Filings Model."""
# pylint: disable=unused-argument
from datetime import (
date as dateType,
datetime,
)
from typing import Any
from dateutil.relativedelta import relativedelta
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.company_filings import (
CompanyFilingsData,
CompanyFilingsQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from pydantic import Field, field_validator
class IntrinioCompanyFilingsQueryParams(CompanyFilingsQueryParams):
"""Intrinio Company Filings Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_filings_v2
"""
__alias_dict__ = {"form_type": "report_type", "limit": "page_size"}
form_type: str | None = Field(
default=None, description="SEC form type to filter by."
)
start_date: dateType | None = Field(
default=None,
description=QUERY_DESCRIPTIONS["start_date"],
)
end_date: dateType | None = Field(
default=None,
description=QUERY_DESCRIPTIONS["end_date"],
)
limit: int | None = Field(
default=None,
description=QUERY_DESCRIPTIONS["limit"],
)
thea_enabled: bool | None = Field(
default=None,
description="Return filings that have been read by Intrinio's Thea NLP.",
)
@field_validator("symbol", mode="before", check_fields=False)
@classmethod
def _validate_symbol(cls, v):
"""Validate symbol."""
if not v:
raise ValueError("Symbol is required for Intrinio.")
return v
class IntrinioCompanyFilingsData(CompanyFilingsData):
"""Intrinio Company Filings Data."""
id: str = Field(description="Intrinio ID of the filing.")
period_end_date: dateType | None = Field(
default=None,
description="Ending date of the fiscal period for the filing.",
)
accepted_date: datetime | None = Field(
default=None, description="Accepted date of the filing."
)
sec_unique_id: str = Field(description="SEC unique ID of the filing.")
filing_url: str | None = Field(default=None, description="URL to the filing page.")
instance_url: str | None = Field(
default=None,
description="URL for the XBRL filing for the report.",
)
industry_group: str = Field(description="Industry group of the company.")
industry_category: str = Field(description="Industry category of the company.")
word_count: int | None = Field(
default=None, description="Number of words in the filing, if available."
)
class IntrinioCompanyFilingsFetcher(
Fetcher[
IntrinioCompanyFilingsQueryParams,
list[IntrinioCompanyFilingsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioCompanyFilingsQueryParams:
"""Transform the query."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None and params.get("form_type") is None:
transformed_params["start_date"] = now - relativedelta(years=1)
if params.get("end_date") is None and params.get("form_type") is None:
transformed_params["end_date"] = now
return IntrinioCompanyFilingsQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioCompanyFilingsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> dict:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
from openbb_core.provider.utils.errors import EmptyDataError, OpenBBError
from openbb_core.provider.utils.helpers import (
get_async_requests_session,
get_querystring,
)
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/companies"
query_str = get_querystring(
query.model_dump(by_alias=True), ["symbol", "limit", "page_size"]
)
url = f"{base_url}/{query.symbol}/filings?{query_str}&page_size={query.limit or 10000}&api_key={api_key}"
results: list = []
metadata: dict = {}
session = await get_async_requests_session()
async with await session.get(url) as response:
if response.status != 200:
raise OpenBBError(
f"Error fetching data from Intrinio: {response.status} -> {response.text}"
)
result = await response.json()
if filings := result.get("filings", []):
results.extend(filings)
metadata = result.get("company", {})
while next_page := result.get("next_page"):
url += f"&next_page={next_page}"
async with await session.get(url) as next_response:
if response.status != 200:
raise OpenBBError(
f"Error fetching data from Intrinio: {response.status} -> {response.text}"
)
result = await next_response.json()
if filings := result.get("filings", []):
results.extend(filings)
if not results:
raise EmptyDataError("No data was returned for the symbol provided.")
return {"data": results, "metadata": metadata}
@staticmethod
def transform_data(
query: IntrinioCompanyFilingsQueryParams, data: dict, **kwargs: Any
) -> AnnotatedResult[list[IntrinioCompanyFilingsData]]:
"""Return the transformed data."""
return AnnotatedResult(
result=[
IntrinioCompanyFilingsData.model_validate(
{
k: v
for k, v in d.items()
if k not in ["thea_enabled", "earnings_release"]
}
)
for d in data.get("data", [])
],
metadata=data.get("metadata", {}),
)

View File

@@ -1,295 +0,0 @@
"""Intrinio Company News Model."""
import asyncio
from datetime import datetime, timedelta
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.company_news import (
CompanyNewsData,
CompanyNewsQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError, UnauthorizedError
from openbb_core.provider.utils.helpers import (
amake_request,
get_querystring,
)
from openbb_intrinio.utils.helpers import get_data
from openbb_intrinio.utils.references import IntrinioSecurity
from pydantic import Field, field_validator
class IntrinioCompanyNewsQueryParams(CompanyNewsQueryParams):
"""Intrinio Company News Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_news_v2
"""
__alias_dict__ = {
"limit": "page_size",
"source": "specific_source",
}
__json_schema_extra__ = {
"symbol": {"multiple_items_allowed": True},
"source": {
"choices": ["yahoo", "moody", "moody_us_news", "moody_us_press_releases"]
},
"sentiment": {"choices": ["positive", "neutral", "negative"]},
}
source: (
Literal["yahoo", "moody", "moody_us_news", "moody_us_press_releases"] | None
) = Field(
default=None,
description="The source of the news article.",
)
sentiment: Literal["positive", "neutral", "negative"] | None = Field(
default=None,
description="Return news only from this source.",
)
language: str | None = Field(
default=None,
description="Filter by language. Unsupported for yahoo source.",
)
topic: str | None = Field(
default=None,
description="Filter by topic. Unsupported for yahoo source.",
)
word_count_greater_than: int | None = Field(
default=None,
description="News stories will have a word count greater than this value."
+ " Unsupported for yahoo source.",
)
word_count_less_than: int | None = Field(
default=None,
description="News stories will have a word count less than this value."
+ " Unsupported for yahoo source.",
)
is_spam: bool | None = Field(
default=None,
description="Filter whether it is marked as spam or not."
+ " Unsupported for yahoo source.",
)
business_relevance_greater_than: float | None = Field(
default=None,
ge=0,
le=1,
description="News stories will have a business relevance score more than this value."
+ " Unsupported for yahoo source. Value is a decimal between 0 and 1.",
)
business_relevance_less_than: float | None = Field(
default=None,
ge=0,
le=1,
description="News stories will have a business relevance score less than this value."
+ " Unsupported for yahoo source. Value is a decimal between 0 and 1.",
)
@field_validator("symbol", mode="before", check_fields=False)
@classmethod
def _symbol_mandatory(cls, v):
"""Symbol mandatory validator."""
if not v:
raise OpenBBError("Required field missing -> symbol")
return v
class IntrinioCompanyNewsData(CompanyNewsData):
"""Intrinio Company News Data."""
__alias_dict__ = {
"date": "publication_date",
"sentiment": "article_sentiment",
"sentiment_confidence": "article_sentiment_confidence",
"symbols": "symbol",
}
source: str | None = Field(
default=None,
description="The source of the news article.",
)
summary: str | None = Field(
default=None,
description="The summary of the news article.",
)
topics: str | None = Field(
default=None,
description="The topics related to the news article.",
)
word_count: int | None = Field(
default=None,
description="The word count of the news article.",
)
business_relevance: float | None = Field(
default=None,
description=" How strongly correlated the news article is to the business",
)
sentiment: str | None = Field(
default=None,
description="The sentiment of the news article - i.e, negative, positive.",
)
sentiment_confidence: float | None = Field(
default=None,
description="The confidence score of the sentiment rating.",
)
language: str | None = Field(
default=None,
description="The language of the news article.",
)
spam: bool | None = Field(
default=None,
description="Whether the news article is spam.",
)
copyright: str | None = Field(
default=None,
description="The copyright notice of the news article.",
)
id: str = Field(description="Article ID.")
security: IntrinioSecurity | None = Field(
default=None,
description="The Intrinio Security object. Contains the security details related to the news article.",
)
@field_validator("publication_date", mode="before", check_fields=False)
@classmethod
def date_validate(cls, v):
"""Return the date as a datetime object."""
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S.000Z")
@field_validator("topics", mode="before", check_fields=False)
@classmethod
def topics_validate(cls, v):
"""Parse the topics as a string."""
if v:
topics = [t.get("name") for t in v if t and t not in ["", " "]]
return ", ".join(topics)
return None
@field_validator("copyright", mode="before", check_fields=False)
@classmethod
def copyright_validate(cls, v):
"""Clean empty strings."""
return None if v in ["", " "] else v
class IntrinioCompanyNewsFetcher(
Fetcher[
IntrinioCompanyNewsQueryParams,
list[IntrinioCompanyNewsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioCompanyNewsQueryParams:
"""Transform the query params."""
transformed_params = params
if not transformed_params.get("start_date"):
transformed_params["start_date"] = (
datetime.now() - timedelta(days=365)
).date()
if not transformed_params.get("end_date"):
transformed_params["end_date"] = (datetime.now() + timedelta(days=1)).date()
if transformed_params["start_date"] == transformed_params["end_date"]:
transformed_params["end_date"] = (
transformed_params["end_date"] + timedelta(days=1)
).date()
return IntrinioCompanyNewsQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioCompanyNewsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/companies"
ignore = (
["symbol", "page_size", "is_spam"]
if not query.source or query.source == "yahoo"
else ["symbol", "page_size"]
)
query_str = get_querystring(query.model_dump(by_alias=True), ignore)
symbols = query.symbol.split(",") if query.symbol else []
news: list = []
async def callback(response, session):
"""Response callback."""
result = await response.json()
if isinstance(result, dict) and "error" in result:
if "api key" in result.get("message", "").lower():
raise UnauthorizedError(
f"Unauthorized Intrinio request -> {result.get('message')}"
)
raise OpenBBError(f"Error in Intrinio request -> {result}")
symbol = response.url.parts[-2]
_data = result.get("news", [])
data = []
data.extend([{"symbol": symbol, **d} for d in _data])
articles = len(data)
next_page = result.get("next_page")
# query.limit can be None...
limit = query.limit or 2500
while next_page and limit > articles:
url = (
f"{base_url}/{symbol}/news?{query_str}"
+ f"&page_size={query.limit}&api_key={api_key}&next_page={next_page}"
)
result = await get_data(url, session=session, **kwargs)
_data = result.get("news", [])
if _data:
data.extend([{"symbol": symbol, **d} for d in _data])
articles = len(data)
next_page = result.get("next_page")
return data
seen = set()
async def get_one(symbol):
"""Get the data for one symbol."""
url = f"{base_url}/{symbol}/news?{query_str}&page_size={query.limit}&api_key={api_key}"
data = await amake_request(url, response_callback=callback, **kwargs)
if not data:
warn(f"No data found for: {symbol}")
if data:
data = [x for x in data if not (x["url"] in seen or seen.add(x["url"]))] # type: ignore
news.extend(
sorted(data, key=lambda x: x["publication_date"], reverse=True)[
: query.limit
]
)
tasks = [get_one(symbol) for symbol in symbols]
await asyncio.gather(*tasks)
if not news:
raise EmptyDataError(
"Error: The request was returned as empty."
+ " Try adjusting the requested date ranges, if applicable."
)
return news
# pylint: disable=unused-argument
@staticmethod
def transform_data(
query: IntrinioCompanyNewsQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioCompanyNewsData]:
"""Return the transformed data."""
results: list[IntrinioCompanyNewsData] = []
for item in data:
body = item.get("body", {})
if not body:
item["text"] = item.pop("summary")
if body:
_ = item.pop("body")
item["publication_date"] = body.get("publication_date", None)
item["text"] = body.get("body", None)
results.append(IntrinioCompanyNewsData.model_validate(item))
return results

View File

@@ -1,90 +0,0 @@
"""Intrinio Currency Available Pairs Model."""
# pylint: disable=unused-argument
from typing import Any
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.currency_pairs import (
CurrencyPairsData,
CurrencyPairsQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from pydantic import Field
class IntrinioCurrencyPairsQueryParams(CurrencyPairsQueryParams):
"""Intrinio Currency Available Pairs Query.
Source: https://docs.intrinio.com/documentation/web_api/get_forex_pairs_v2
"""
class IntrinioCurrencyPairsData(CurrencyPairsData):
"""Intrinio Currency Available Pairs Data."""
__alias_dict__ = {"symbol": "code"}
base_currency: str = Field(
description="ISO 4217 currency code of the base currency."
)
quote_currency: str = Field(
description="ISO 4217 currency code of the quote currency."
)
class IntrinioCurrencyPairsFetcher(
Fetcher[
IntrinioCurrencyPairsQueryParams,
list[IntrinioCurrencyPairsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioCurrencyPairsQueryParams:
"""Transform the query params."""
return IntrinioCurrencyPairsQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioCurrencyPairsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
from openbb_intrinio.utils.helpers import get_data_many
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com"
url = f"{base_url}/forex/pairs?api_key={api_key}"
return await get_data_many(url, "pairs", **kwargs)
@staticmethod
def transform_data(
query: IntrinioCurrencyPairsQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioCurrencyPairsData]:
"""Return the transformed data."""
# pylint: disable=import-outside-toplevel
from pandas import DataFrame
if not data:
raise EmptyDataError("The request was returned empty.")
df = DataFrame(data)
if query.query:
df = df[
df["code"].str.contains(query.query, case=False)
| df["base_currency"].str.contains(query.query, case=False)
| df["quote_currency"].str.contains(query.query, case=False)
]
if len(df) == 0:
raise EmptyDataError(
f"No results were found with the query supplied. -> {query.query}"
+ " Hint: Names and descriptions are not searchable from Intrinio, try 3-letter symbols."
)
return [
IntrinioCurrencyPairsData.model_validate(d)
for d in df.to_dict(orient="records")
]

View File

@@ -1,274 +0,0 @@
"""Intrinio Equity Historical Price Model."""
# pylint: disable = unused-argument
from datetime import datetime, time
from typing import Any, Literal
from dateutil.relativedelta import relativedelta
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.equity_historical import (
EquityHistoricalData,
EquityHistoricalQueryParams,
)
from openbb_core.provider.utils.descriptions import (
DATA_DESCRIPTIONS,
QUERY_DESCRIPTIONS,
)
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_request,
get_querystring,
)
from pydantic import Field, PrivateAttr, model_validator
class IntrinioEquityHistoricalQueryParams(EquityHistoricalQueryParams):
"""Intrinio Equity Historical Price Query.
Source: https://docs.intrinio.com/documentation/web_api/get_security_interval_prices_v2
"""
__json_schema_extra__ = {
"interval": {
"choices": [
"1m",
"5m",
"10m",
"15m",
"30m",
"60m",
"1h",
"1d",
"1W",
"1M",
"1Q",
"1Y",
],
},
}
symbol: str = Field(
description="A Security identifier (Ticker, FIGI, ISIN, CUSIP, Intrinio ID)."
)
interval: Literal[
"1m", "5m", "10m", "15m", "30m", "60m", "1h", "1d", "1W", "1M", "1Q", "1Y"
] = Field(default="1d", description=QUERY_DESCRIPTIONS.get("interval", ""))
start_time: time | None = Field(
default=None,
description="Return intervals starting at the specified time on the `start_date` formatted as 'HH:MM:SS'.",
)
end_time: time | None = Field(
default=None,
description="Return intervals stopping at the specified time on the `end_date` formatted as 'HH:MM:SS'.",
)
timezone: str | None = Field(
default="America/New_York",
description="Timezone of the data, in the IANA format (Continent/City).",
)
source: Literal["realtime", "delayed", "nasdaq_basic"] = Field(
default="realtime", description="The source of the data."
)
_interval_size: Literal["1m", "5m", "10m", "15m", "30m", "60m", "1h"] = PrivateAttr(
default=None
)
_frequency: Literal["daily", "weekly", "monthly", "quarterly", "yearly"] = (
PrivateAttr(default=None)
)
# pylint: disable=protected-access
@model_validator(mode="after")
@classmethod
def set_time_params(cls, values: "IntrinioEquityHistoricalQueryParams"):
"""Set the default start & end date and time params for Intrinio API."""
frequency_dict = {
"1d": "daily",
"1W": "weekly",
"1M": "monthly",
"1Q": "quarterly",
"1Y": "yearly",
}
if values.interval in ["1m", "5m", "10m", "15m", "30m", "60m", "1h"]:
values._interval_size = values.interval # type: ignore
elif values.interval in ["1d", "1W", "1M", "1Q", "1Y"]:
values._frequency = frequency_dict[values.interval] # type: ignore
return values
class IntrinioEquityHistoricalData(EquityHistoricalData):
"""Intrinio Equity Historical Price Data."""
__alias_dict__ = {
"date": "time",
"change_percent": "percent_change",
"interval": "frequency",
"intra_period": "intraperiod",
}
average: float | None = Field(
default=None,
description="Average trade price of an individual equity during the interval.",
)
change: float | None = Field(
default=None,
description="Change in the price of the symbol from the previous day.",
)
change_percent: float | None = Field(
default=None,
description="Percent change in the price of the symbol from the previous day.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
adj_open: float | None = Field(
default=None,
description="The adjusted open price.",
)
adj_high: float | None = Field(
default=None,
description="The adjusted high price.",
)
adj_low: float | None = Field(
default=None,
description="The adjusted low price.",
)
adj_close: float | None = Field(
default=None,
description=DATA_DESCRIPTIONS.get("adj_close", ""),
)
adj_volume: float | None = Field(
default=None,
description="The adjusted volume.",
)
fifty_two_week_high: float | None = Field(
default=None,
description="52 week high price for the symbol.",
)
fifty_two_week_low: float | None = Field(
default=None,
description="52 week low price for the symbol.",
)
factor: float | None = Field(
default=None,
description="factor by which to multiply equity prices before this "
"date, in order to calculate historically-adjusted equity prices.",
)
split_ratio: float | None = Field(
default=None,
description="Ratio of the equity split, if a split occurred.",
)
dividend: float | None = Field(
default=None,
description="Dividend amount, if a dividend was paid.",
)
close_time: datetime | None = Field(
default=None,
description="The timestamp that represents the end of the interval span.",
)
interval: str | None = Field(
default=None,
description="The data time frequency.",
)
intra_period: bool | None = Field(
default=None,
description="If true, the equity price represents an unfinished period "
"(be it day, week, quarter, month, or year), meaning that the close "
"price is the latest price available, not the official close price "
"for the period",
)
class IntrinioEquityHistoricalFetcher(
Fetcher[
IntrinioEquityHistoricalQueryParams,
list[IntrinioEquityHistoricalData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioEquityHistoricalQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = now - relativedelta(years=1)
if params.get("end_date") is None:
transformed_params["end_date"] = now
if params.get("start_time") is None:
transformed_params["start_time"] = time(0, 0, 0)
if params.get("end_time") is None:
transformed_params["end_time"] = time(23, 59, 59)
return IntrinioEquityHistoricalQueryParams(**transformed_params)
# pylint: disable=protected-access
@staticmethod
async def aextract_data(
query: IntrinioEquityHistoricalQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = f"https://api-v2.intrinio.com/securities/{query.symbol}/prices"
query_str = get_querystring(
query.model_dump(by_alias=True), ["symbol", "interval"]
)
if query._interval_size:
base_url += f"/intervals?interval_size={query._interval_size}"
data_key = "intervals"
elif query._frequency:
base_url += f"?frequency={query._frequency}"
data_key = "stock_prices"
async def callback(response: ClientResponse, session: ClientSession) -> list:
"""Return the response."""
init_response = await response.json()
if "error" in init_response:
raise OpenBBError(
f"Intrinio Error Message -> {init_response['error']}: {init_response.get('message')}" # type: ignore
)
all_data: list = init_response.get(data_key, []) # type: ignore
next_page = init_response.get("next_page", None) # type: ignore
while next_page:
url = response.url.update_query(next_page=next_page).human_repr()
response_data = await session.get_json(url)
all_data.extend(response_data.get(data_key, [])) # type: ignore
next_page = response_data.get("next_page", None) # type: ignore
return all_data
url = f"{base_url}&{query_str}&api_key={api_key}"
return await amake_request(url, response_callback=callback, **kwargs) # type: ignore
@staticmethod
def transform_data(
query: IntrinioEquityHistoricalQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioEquityHistoricalData]:
"""Return the transformed data."""
if not data:
raise EmptyDataError("The request was returned empty.")
date_col = (
"time"
if query.interval in ["1m", "5m", "10m", "15m", "30m", "60m", "1h"]
else "date"
)
return [
IntrinioEquityHistoricalData.model_validate(d)
for d in sorted(data, key=lambda x: x[date_col], reverse=False)
]

View File

@@ -1,78 +0,0 @@
"""Intrinio Equity Info Model."""
from typing import Any
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.equity_info import (
EquityInfoData,
EquityInfoQueryParams,
)
from openbb_core.provider.utils.helpers import (
amake_requests,
)
from openbb_intrinio.utils.helpers import response_callback
from pydantic import Field
class IntrinioEquityInfoQueryParams(EquityInfoQueryParams):
"""Intrinio Equity Info Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
class IntrinioEquityInfoData(EquityInfoData):
"""Intrinio Equity Info Data."""
__alias_dict__ = {
"symbol": "ticker",
}
id: str = Field(default=None, description="Intrinio ID for the company.")
thea_enabled: bool | None = Field(
default=None, description="Whether the company has been enabled for Thea."
)
class IntrinioEquityInfoFetcher(
Fetcher[
IntrinioEquityInfoQueryParams,
list[IntrinioEquityInfoData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioEquityInfoQueryParams:
"""Transform the query."""
return IntrinioEquityInfoQueryParams(**params)
# pylint: disable=W0613:unused-argument
@staticmethod
async def aextract_data(
query: IntrinioEquityInfoQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> dict:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com"
urls = [
f"{base_url}/companies/{s.strip()}?api_key={api_key}"
for s in query.symbol.split(",")
]
return await amake_requests(urls, response_callback, **kwargs)
# pylint: disable=W0613:unused-argument
@staticmethod
def transform_data(
query: IntrinioEquityInfoQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioEquityInfoData]:
"""Transform the data."""
return [IntrinioEquityInfoData.model_validate(d) for d in data]

View File

@@ -1,140 +0,0 @@
"""Intrinio Equity Quote Model."""
# pylint: disable=unused-argument
import re
import warnings
from datetime import datetime
from typing import Any
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.equity_quote import (
EquityQuoteData,
EquityQuoteQueryParams,
)
from openbb_core.provider.utils.helpers import (
ClientResponse,
amake_requests,
)
from openbb_intrinio.utils.references import SOURCES, VENUES, IntrinioSecurity
from pydantic import Field, field_validator
_warn = warnings.warn
class IntrinioEquityQuoteQueryParams(EquityQuoteQueryParams):
"""Intrinio Equity Quote Query.
Source: https://docs.intrinio.com/documentation/web_api/get_security_realtime_price_v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
symbol: str = Field(
description="A Security identifier (Ticker, FIGI, ISIN, CUSIP, Intrinio ID)."
)
source: SOURCES = Field(default="iex", description="Source of the data.")
class IntrinioEquityQuoteData(EquityQuoteData):
"""Intrinio Equity Quote Data."""
__alias_dict__ = {
"exchange": "listing_venue",
"market_center": "market_center_code",
"bid": "bid_price",
"ask": "ask_price",
"open": "open_price",
"close": "close_price",
"low": "low_price",
"high": "high_price",
"last_timestamp": "last_time",
"volume": "market_volume",
}
is_darkpool: bool | None = Field(
default=None, description="Whether or not the current trade is from a darkpool."
)
source: str | None = Field(default=None, description="Source of the Intrinio data.")
updated_on: datetime = Field(
description="Date and Time when the data was last updated."
)
security: IntrinioSecurity | None = Field(
default=None, description="Security details related to the quote."
)
@field_validator("last_time", "updated_on", mode="before", check_fields=False)
@classmethod
def date_validate(cls, v): # pylint: disable=E0213
"""Return the date as a datetime object."""
return (
datetime.fromisoformat(v.replace("Z", "+00:00"))
if v.endswith(("Z", "+00:00"))
else datetime.fromisoformat(v)
)
@field_validator("sales_conditions", mode="before", check_fields=False)
@classmethod
def validate_sales_conditions(cls, v):
"""Validate sales conditions and remove empty strings."""
if v:
control_char_re = re.compile(r"[\x00-\x1f\x7f-\x9f]")
v = control_char_re.sub("", v).strip()
v = None if v == "" else v
return v if v else None
@field_validator("exchange", "market_center", mode="before", check_fields=False)
@classmethod
def validate_listing_venue(cls, v):
"""Validate listing venue and remove empty strings."""
if v:
return VENUES.get(v, v)
return None
class IntrinioEquityQuoteFetcher(
Fetcher[
IntrinioEquityQuoteQueryParams,
list[IntrinioEquityQuoteData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioEquityQuoteQueryParams:
"""Transform the query params."""
return IntrinioEquityQuoteQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioEquityQuoteQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com"
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
if response.status != 200:
return {}
response_data = await response.json()
response_data["symbol"] = response_data["security"].get("ticker", None) # type: ignore
if "messages" in response_data and response_data.get("messages"): # type: ignore
_message = list(response_data.pop("messages")) # type: ignore
_warn(str(",".join(_message)))
return response_data # type: ignore
urls = [
f"{base_url}/securities/{s.strip()}/prices/realtime?source={query.source}&api_key={api_key}"
for s in query.symbol.split(",")
]
return await amake_requests(urls, callback, **kwargs)
@staticmethod
def transform_data(
query: IntrinioEquityQuoteQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioEquityQuoteData]:
"""Return the transformed data."""
return [IntrinioEquityQuoteData.model_validate(d) for d in data]

View File

@@ -1,90 +0,0 @@
"""Intrinio Equity Search Model."""
# pylint: disable=unused-argument
from typing import Any
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.equity_search import (
EquitySearchData,
EquitySearchQueryParams,
)
from openbb_core.provider.utils.descriptions import (
DATA_DESCRIPTIONS,
QUERY_DESCRIPTIONS,
)
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_one
from pydantic import Field
class IntrinioEquitySearchQueryParams(EquitySearchQueryParams):
"""Intrinio Equity Search Query.
Source: https://docs.intrinio.com/documentation/web_api/search_companies_v2
"""
__alias_dict__ = {
"limit": "page_size",
}
active: bool = Field(
default=True,
description="When true, return companies that are actively traded (having stock prices within the past 14 days)."
+ " When false, return companies that are not actively traded or never have been traded.",
)
limit: int | None = Field(
default=10000,
description=QUERY_DESCRIPTIONS.get("limit", ""),
)
class IntrinioEquitySearchData(EquitySearchData):
"""Intrinio Equity Search Data."""
__alias_dict__ = {
"intrinio_id": "id",
"symbol": "ticker",
}
cik: str | None = Field(description=DATA_DESCRIPTIONS.get("CIK", ""))
lei: str | None = Field(
description="The Legal Entity Identifier (LEI) of the company."
)
intrinio_id: str = Field(description="The Intrinio ID of the company.")
class IntrinioEquitySearchFetcher(
Fetcher[
IntrinioEquitySearchQueryParams,
list[IntrinioEquitySearchData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioEquitySearchQueryParams:
"""Transform the query."""
return IntrinioEquitySearchQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioEquitySearchQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
query_str = get_querystring(query.model_dump(by_alias=True), ["is_symbol"])
base_url = "https://api-v2.intrinio.com/companies/search?"
url = f"{base_url}{query_str}&api_key={api_key}"
data = await get_data_one(url, **kwargs)
return data # type: ignore
@staticmethod
def transform_data(
query: IntrinioEquitySearchQueryParams, data: dict, **kwargs: Any
) -> list[IntrinioEquitySearchData]:
"""Transform the data to the standard format."""
return [IntrinioEquitySearchData.model_validate(d) for d in data["companies"]]

View File

@@ -1,211 +0,0 @@
"""Intrinio ETF Holdings Model."""
# pylint: disable=unused-argument
from datetime import date as dateType
from typing import Any
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.etf_holdings import (
EtfHoldingsData,
EtfHoldingsQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_request,
)
from pydantic import Field, model_validator
class IntrinioEtfHoldingsQueryParams(EtfHoldingsQueryParams):
"""
Intrinio ETF Holdings Query Params.
Source: https://docs.intrinio.com/documentation/web_api/get_etf_holdings_v2
"""
__alias_dict__ = {"date": "as_of_date"}
date: dateType | None = Field(
default=None, description=QUERY_DESCRIPTIONS.get("date", "")
)
class IntrinioEtfHoldingsData(EtfHoldingsData):
"""Intrinio ETF Holdings Data."""
__alias_dict__ = {
"symbol": "ticker",
"security_type": "type",
"unit": "quantity_units",
"face_value": "face",
"balance": "quantity_held",
"value": "market_value_held",
"derivatives_value": "notional_value",
"units_per_share": "quantity_per_share",
"weight": "weighting",
"updated": "as_of_date",
"country": "location",
"maturity_date": "maturity",
}
name: str | None = Field(
default=None,
description="The common name for the holding.",
)
security_type: str | None = Field(
default=None,
description="The type of instrument for this holding. Examples(Bond='BOND', Equity='EQUI')",
)
isin: str | None = Field(
default=None,
description="The International Securities Identification Number.",
)
ric: str | None = Field(
default=None,
description="The Reuters Instrument Code.",
)
sedol: str | None = Field(
default=None,
description="The Stock Exchange Daily Official List.",
)
share_class_figi: str | None = Field(
default=None,
description="The OpenFIGI symbol for the holding.",
)
country: str | None = Field(
default=None,
description="The country or region of the holding.",
)
maturity_date: dateType | None = Field(
default=None,
description="The maturity date for the debt security, if available.",
)
contract_expiry_date: dateType | None = Field(
default=None,
description="Expiry date for the futures contract held, if available.",
)
coupon: float | None = Field(
default=None,
description="The coupon rate of the debt security, if available.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
balance: int | float | None = Field(
default=None,
description="The number of units of the security held, if available.",
)
unit: str | None = Field(
default=None,
description="The units of the 'balance' field.",
)
units_per_share: float | None = Field(
default=None,
description="Number of units of the security held per share outstanding of the ETF, if available.",
)
face_value: float | None = Field(
default=None,
description="The face value of the debt security, if available.",
json_schema_extra={"x-unit_measurement": "currency"},
)
derivatives_value: float | None = Field(
default=None,
description="The notional value of derivatives contracts held.",
json_schema_extra={"x-unit_measurement": "currency"},
)
value: float | None = Field(
default=None,
description="The market value of the holding, on the 'as_of' date.",
json_schema_extra={"x-unit_measurement": "currency"},
)
weight: float | None = Field(
default=None,
description="The weight of the holding, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
updated: dateType | None = Field(
default=None,
description="The 'as_of' date for the holding.",
)
@model_validator(mode="before")
@classmethod
def replace_zero(cls, values):
"""Check for zero values and replace with None."""
return (
{k: None if v == 0 else v for k, v in values.items()}
if isinstance(values, dict)
else values
)
class IntrinioEtfHoldingsFetcher(
Fetcher[IntrinioEtfHoldingsQueryParams, list[IntrinioEtfHoldingsData]]
):
"""Intrinio ETF Holdings Fetcher."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioEtfHoldingsQueryParams:
"""Transform query."""
return IntrinioEtfHoldingsQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioEtfHoldingsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
symbol = query.symbol + ":US" if ":" not in query.symbol else query.symbol
URL = f"https://api-v2.intrinio.com/etfs/{symbol}/holdings?page_size=10000&api_key={api_key}"
if query.date:
URL += f"&as_of_date={query.date}"
data: list = []
async def response_callback(response: ClientResponse, session: ClientSession):
"""Async response callback."""
results = await response.json()
if results.get("error"): # type: ignore
return results
if results.get("holdings") and len(results.get("holdings")) > 0: # type: ignore
data.extend(results.get("holdings")) # type: ignore
while results.get("next_page"): # type: ignore
next_page = results["next_page"] # type: ignore
next_url = f"{URL}&next_page={next_page}"
results = await amake_request(next_url, session=session, **kwargs)
if "holdings" in results and len(results.get("holdings")) > 0: # type: ignore
data.extend(results.get("holdings")) # type: ignore
return data
return await amake_request(URL, response_callback=response_callback, **kwargs) # type: ignore
@staticmethod
def transform_data(
query: IntrinioEtfHoldingsQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioEtfHoldingsData]:
"""Transform data."""
if not data or isinstance(data, dict) and data.get("error"):
if isinstance(data, list) and data == []:
raise OpenBBError(
str(
f"No holdings were found for {query.symbol}, and the response from Intrinio was empty."
)
)
raise OpenBBError(str(f"{data.get('message')} {query.symbol}: {data['error']}")) # type: ignore
results: list[IntrinioEtfHoldingsData] = []
for d in sorted(data, key=lambda x: x["weighting"], reverse=True):
# This field is deprecated and is dupilcated in the response.
_ = d.pop("composite_figi", None)
if d.get("coupon"):
d["coupon"] = d["coupon"] / 100
results.append(IntrinioEtfHoldingsData.model_validate(d))
return results

View File

@@ -1,655 +0,0 @@
"""Intrinio ETF Info Model."""
# pylint: disable=unused-argument
from datetime import date as dateType
from typing import Any
from warnings import warn
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.etf_info import (
EtfInfoData,
EtfInfoQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import amake_requests
from pydantic import Field
class IntrinioEtfInfoQueryParams(EtfInfoQueryParams):
"""
Intrinio ETF Info Query Params.
Source: https://docs.intrinio.com/documentation/web_api/get_etf_v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
class IntrinioEtfInfoData(EtfInfoData):
"""Intrinio ETF Info Data."""
__alias_dict__ = {
"symbol": "ticker",
"exchange": "exchange_mic",
"issuer": "sponsor",
"investment_style": "type",
"industry_group": "sub_industry",
"holds_mlp": "holds_ml_ps",
"holds_adr": "holds_ad_rs",
"index_symbol": "index_ticker",
"figi_symbol": "figi_ticker",
"intrinio_id": "id",
"is_listed": "is_live_listed",
"beta_type": "smartvs_traditional_beta",
"beta_details": "smartvs_traditional_beta_level2",
"listing_country": "primary_ticker_country_code",
"listing_region": "primary_listing_region",
"primary_symbol": "primary_ticker",
"intraday_nav_symbol": "intraday_nav_ticker",
"issuer_country": "issuing_entity_country_code",
"livestock_type": "livestock",
}
fund_listing_date: dateType | None = Field(
default=None,
description="The date on which the Exchange Traded Product (ETP)"
+ " or share class of the ETP is listed on a specific exchange.",
)
data_change_date: dateType | None = Field(
default=None,
description="The last date on which there was a change in a classifications data field for this ETF.",
)
etn_maturity_date: dateType | None = Field(
default=None,
description="If the product is an ETN, this field identifies the maturity date for the ETN.",
)
is_listed: bool | None = Field(
default=None,
description="If true, the ETF is still listed on an exchange.",
)
close_date: dateType | None = Field(
default=None,
description="The date on which the ETF was de-listed if it is no longer listed.",
)
exchange: str | None = Field(
default=None,
description="The exchange Market Identifier Code (MIC).",
)
isin: str | None = Field(
default=None,
description="International Securities Identification Number (ISIN).",
)
ric: str | None = Field(
default=None,
description="Reuters Instrument Code (RIC).",
)
sedol: str | None = Field(
default=None,
description="Stock Exchange Daily Official List (SEDOL).",
)
figi_symbol: str | None = Field(
default=None,
description="Financial Instrument Global Identifier (FIGI) symbol.",
)
share_class_figi: str | None = Field(
default=None,
description="Financial Instrument Global Identifier (FIGI).",
)
firstbridge_id: str | None = Field(
default=None,
description="The FirstBridge unique identifier for the Exchange Traded Fund (ETF).",
)
firstbridge_parent_id: str | None = Field(
default=None,
description="The FirstBridge unique identifier for the parent Exchange Traded Fund (ETF), if applicable.",
)
intrinio_id: str | None = Field(
default=None,
description="Intrinio unique identifier for the security.",
)
intraday_nav_symbol: str | None = Field(
default=None,
description="Intraday Net Asset Value (NAV) symbol.",
)
primary_symbol: str | None = Field(
default=None,
description="The primary ticker field is used for Exchange Traded Products (ETPs)"
+ " that have multiple listings and share classes."
+ " If an ETP has multiple listings or share classes,"
+ " the same primary ticker is assigned to all the listings and share classes.",
)
etp_structure_type: str | None = Field(
default=None,
description="Classifies Exchange Traded Products (ETPs) into very broad categories based on its legal structure.",
)
legal_structure: str | None = Field(
default=None,
description="Legal structure of the fund.",
)
issuer: str | None = Field(
default=None,
description="Issuer of the ETF.",
)
etn_issuing_bank: str | None = Field(
default=None,
description="If the product is an Exchange Traded Note (ETN), this field identifies the issuing bank.",
)
fund_family: str | None = Field(
default=None,
description="This field identifies the fund family to which the ETF belongs, as categorized by the ETF Sponsor.",
)
investment_style: str | None = Field(
default=None,
description="Investment style of the ETF.",
)
derivatives_based: str | None = Field(
default=None,
description="This field is populated if the ETF holds either"
+ " listed or over-the-counter derivatives in its portfolio.",
)
income_category: str | None = Field(
default=None,
description="Identifies if an Exchange Traded Fund (ETF) falls into a category"
+ " that is specifically designed to provide a high yield or income",
)
asset_class: str | None = Field(
default=None,
description="Captures the underlying nature of the securities in the Exchanged Traded Product (ETP).",
)
other_asset_types: str | None = Field(
default=None,
description="If 'asset_class' field is classified as 'Other Asset Types'"
+ " this field captures the specific category of the underlying assets.",
)
single_category_designation: str | None = Field(
default=None,
description="This categorization is created for those users who want every ETF to be 'forced'"
+ " into a single bucket, so that the assets for all categories will always sum to the total market.",
)
beta_type: str | None = Field(
default=None,
description="This field identifies whether an ETF provides 'Traditional' beta exposure or 'Smart' beta exposure."
+ " ETFs that are active (i.e. non-indexed), leveraged / inverse or have a proprietary quant model"
+ " (i.e. that don't provide indexed exposure to a targeted factor) are classified separately.",
)
beta_details: str | None = Field(
default=None,
description="This field provides further detail within the traditional and smart beta categories.",
)
market_cap_range: str | None = Field(
default=None,
description="Equity ETFs are classified as falling into categories"
+ " based on the description of their investment strategy in the prospectus."
+ " Examples ('Mega Cap', 'Large Cap', 'Mid Cap', etc.)",
)
market_cap_weighting_type: str | None = Field(
default=None,
description="For ETFs that take the value 'Market Cap Weighted' in the 'index_weighting_scheme' field,"
+ " this field provides detail on the market cap weighting type.",
)
index_weighting_scheme: str | None = Field(
default=None,
description="For ETFs that track an underlying index,"
+ " this field provides detail on the index weighting type.",
)
index_linked: str | None = Field(
default=None,
description="This field identifies whether an ETF is index linked or active.",
)
index_name: str | None = Field(
default=None,
description="This field identifies the name of the underlying index tracked by the ETF, if applicable.",
)
index_symbol: str | None = Field(
default=None,
description="This field identifies the OpenFIGI ticker for the Index underlying the ETF.",
)
parent_index: str | None = Field(
default=None,
description="This field identifies the name of the parent index, which represents"
+ " the broader universe from which the index underlying the ETF is created, if applicable.",
)
index_family: str | None = Field(
default=None,
description="This field identifies the index family to which the index underlying the ETF belongs."
+ " The index family is represented as categorized by the index provider.",
)
broader_index_family: str | None = Field(
default=None,
description="This field identifies the broader index family to which the index underlying the ETF belongs."
+ " The broader index family is represented as categorized by the index provider.",
)
index_provider: str | None = Field(
default=None,
description="This field identifies the Index provider for the index underlying the ETF, if applicable.",
)
index_provider_code: str | None = Field(
default=None,
description="This field provides the First Bridge code for each Index provider,"
+ " corresponding to the index underlying the ETF if applicable.",
)
replication_structure: str | None = Field(
default=None,
description="The replication structure of the Exchange Traded Product (ETP).",
)
growth_value_tilt: str | None = Field(
default=None,
description="Classifies equity ETFs as either 'Growth' or Value' based on the stated style tilt"
+ " in the ETF prospectus. Equity ETFs that do not have a stated style tilt are classified as 'Core / Blend'.",
)
growth_type: str | None = Field(
default=None,
description="For ETFs that are classified as 'Growth' in 'growth_value_tilt',"
+ " this field further identifies those where the stocks in the"
+ " ETF are both selected and weighted based on their growth (style factor) scores.",
)
value_type: str | None = Field(
default=None,
description="For ETFs that are classified as 'Value' in 'growth_value_tilt',"
+ " this field further identifies those where the stocks in the"
+ " ETF are both selected and weighted based on their value (style factor) scores.",
)
sector: str | None = Field(
default=None,
description="For equity ETFs that aim to provide targeted exposure to a sector or industry,"
+ " this field identifies the Sector that it provides the exposure to.",
)
industry: str | None = Field(
default=None,
description="For equity ETFs that aim to provide targeted exposure to an industry,"
+ " this field identifies the Industry that it provides the exposure to.",
)
industry_group: str | None = Field(
default=None,
description="For equity ETFs that aim to provide targeted exposure to a sub-industry,"
+ " this field identifies the sub-Industry that it provides the exposure to.",
)
cross_sector_theme: str | None = Field(
default=None,
description="For equity ETFs that aim to provide targeted exposure to a specific investment theme"
+ " that cuts across GICS sectors, this field identifies the specific cross-sector theme."
+ " Examples ('Agri-business', 'Natural Resources', 'Green Investing', etc.)",
)
natural_resources_type: str | None = Field(
default=None,
description="For ETFs that are classified as 'Natural Resources' in the 'cross_sector_theme' field,"
+ " this field provides further detail on the type of Natural Resources exposure.",
)
us_or_excludes_us: str | None = Field(
default=None,
description="Takes the value of 'Domestic' for US exposure,"
+ " 'International' for non-US exposure and 'Global' for exposure that includes all regions including the US.",
)
developed_emerging: str | None = Field(
default=None,
description="This field identifies the stage of development of the markets that the ETF provides exposure to.",
)
specialized_region: str | None = Field(
default=None,
description="This field is populated if the ETF provides targeted"
+ " exposure to a specific type of geography-based grouping"
+ " that does not fall into a specific country or continent grouping."
+ " Examples ('BRIC', 'Chindia', etc.)",
)
continent: str | None = Field(
default=None,
description="This field is populated if the ETF provides targeted exposure"
+ " to a specific continent or country within that Continent.",
)
latin_america_sub_group: str | None = Field(
default=None,
description="For ETFs that are classified as 'Latin America' in the 'continent' field,"
+ " this field provides further detail on the type of regional exposure.",
)
europe_sub_group: str | None = Field(
default=None,
description="For ETFs that are classified as 'Europe' in the 'continent' field,"
+ " this field provides further detail on the type of regional exposure.",
)
asia_sub_group: str | None = Field(
default=None,
description="For ETFs that are classified as 'Asia' in the 'continent' field,"
+ " this field provides further detail on the type of regional exposure.",
)
specific_country: str | None = Field(
default=None,
description="This field is populated if the ETF provides targeted exposure to a specific country.",
)
china_listing_location: str | None = Field(
default=None,
description="For ETFs that are classified as 'China' in the 'country' field,"
+ " this field provides further detail on the type of exposure in the underlying securities.",
)
us_state: str | None = Field(
default=None,
description="Takes the value of a US state if the ETF provides"
+ " targeted exposure to the municipal bonds or equities of companies.",
)
real_estate: str | None = Field(
default=None,
description="For ETFs that provide targeted real estate exposure,"
+ " this field is populated if the ETF provides targeted"
+ " exposure to a specific segment of the real estate market.",
)
fundamental_weighting_type: str | None = Field(
default=None,
description="For ETFs that take the value 'Fundamental Weighted' in the 'index_weighting_scheme' field,"
+ " this field provides detail on the fundamental weighting methodology.",
)
dividend_weighting_type: str | None = Field(
default=None,
description="For ETFs that take the value 'Dividend Weighted' in the 'index_weighting_scheme' field,"
+ " this field provides detail on the dividend weighting methodology.",
)
bond_type: str | None = Field(
default=None,
description="For ETFs where 'asset_class_type' is 'Bonds',"
+ " this field provides detail on the type of bonds held in the ETF.",
)
government_bond_types: str | None = Field(
default=None,
description="For bond ETFs that take the value 'Treasury & Government' in 'bond_type',"
+ " this field provides detail on the exposure.",
)
municipal_bond_region: str | None = Field(
default=None,
description="For bond ETFs that take the value 'Municipal' in 'bond_type',"
+ " this field provides additional detail on the geographic exposure.",
)
municipal_vrdo: bool | None = Field(
default=None,
description="For bond ETFs that take the value 'Municipal' in 'bond_type',"
+ " this field identifies those ETFs that specifically provide exposure to Variable Rate Demand Obligations.",
)
mortgage_bond_types: str | None = Field(
default=None,
description="For bond ETFs that take the value 'Mortgage' in 'bond_type',"
+ " this field provides additional detail on the type of underlying securities.",
)
bond_tax_status: str | None = Field(
default=None,
description="For all US bond ETFs, this field provides additional"
+ " detail on the tax treatment of the underlying securities.",
)
credit_quality: str | None = Field(
default=None,
description="For all bond ETFs, this field helps to identify if the ETF"
+ " provides targeted exposure to securities of a specific credit quality range.",
)
average_maturity: str | None = Field(
default=None,
description="For all bond ETFs, this field helps to identify if the ETF"
+ " provides targeted exposure to securities of a specific maturity range.",
)
specific_maturity_year: int | None = Field(
default=None,
description="For all bond ETFs that take the value 'Specific Maturity Year' in the 'average_maturity' field,"
+ " this field specifies the calendar year.",
)
commodity_types: str | None = Field(
default=None,
description="For ETFs where 'asset_class_type' is 'Commodities',"
+ " this field provides detail on the type of commodities held in the ETF.",
)
energy_type: str | None = Field(
default=None,
description="For ETFs where 'commodity_type' is 'Energy',"
+ " this field provides detail on the type of energy exposure provided by the ETF.",
)
agricultural_type: str | None = Field(
default=None,
description="For ETFs where 'commodity_type' is 'Agricultural',"
+ " this field provides detail on the type of agricultural exposure provided by the ETF.",
)
livestock_type: str | None = Field(
default=None,
description="For ETFs where 'commodity_type' is 'Livestock',"
+ " this field provides detail on the type of livestock exposure provided by the ETF.",
)
metal_type: str | None = Field(
default=None,
description="For ETFs where 'commodity_type' is 'Gold & Metals',"
+ " this field provides detail on the type of exposure provided by the ETF.",
)
inverse_leveraged: str | None = Field(
default=None,
description="This field is populated if the ETF provides inverse or leveraged exposure.",
)
target_date_multi_asset_type: str | None = Field(
default=None,
description="For ETFs where 'asset_class_type' is 'Target Date / MultiAsset',"
+ " this field provides detail on the type of commodities held in the ETF.",
)
currency_pair: str | None = Field(
default=None,
description="This field is populated if the ETF's strategy involves providing exposure to"
+ " the movements of a currency or involves hedging currency exposure.",
)
social_environmental_type: str | None = Field(
default=None,
description="This field is populated if the ETF's strategy involves providing"
+ " exposure to a specific social or environmental theme.",
)
clean_energy_type: str | None = Field(
default=None,
description="This field is populated if the ETF has a value of 'Clean Energy'"
+ " in the 'social_environmental_type' field.",
)
dividend_type: str | None = Field(
default=None,
description="This field is populated if the ETF has an intended"
+ " investment objective of holding dividend-oriented stocks as stated in the prospectus.",
)
regular_dividend_payor_type: str | None = Field(
default=None,
description="This field is populated if the ETF has a value of"
+ "'Dividend - Regular Payors' in the 'dividend_type' field.",
)
quant_strategies_type: str | None = Field(
default=None,
description="This field is populated if the ETF has either an index-linked"
+ " or active strategy that is based on a proprietary quantitative strategy.",
)
other_quant_models: str | None = Field(
default=None,
description="For ETFs where 'quant_strategies_type' is 'Other Quant Model',"
+ " this field provides the name of the specific proprietary quant model"
+ " used as the underlying strategy for the ETF.",
)
hedge_fund_type: str | None = Field(
default=None,
description="For ETFs where 'other_asset_types' is 'Hedge Fund Replication',"
+ " this field provides detail on the type of hedge fund replication strategy.",
)
excludes_financials: bool | None = Field(
default=None,
description="For equity ETFs, identifies those ETFs"
+ " where the underlying fund holdings will not hold financials stocks,"
+ " based on the funds intended objective.",
)
excludes_technology: bool | None = Field(
default=None,
description="For equity ETFs, identifies those ETFs"
+ " where the underlying fund holdings will not hold technology stocks,"
+ " based on the funds intended objective.",
)
holds_only_nyse_stocks: bool | None = Field(
default=None,
description="If true, the ETF is an equity ETF and holds only stocks listed on NYSE.",
)
holds_only_nasdaq_stocks: bool | None = Field(
default=None,
description="If true, the ETF is an equity ETF and holds only stocks listed on Nasdaq.",
)
holds_mlp: bool | None = Field(
default=None,
description="If true, the ETF's investment objective explicitly specifies"
+ " that it holds MLPs as an intended part of its investment strategy.",
)
holds_preferred_stock: bool | None = Field(
default=None,
description="If true, the ETF's investment objective explicitly specifies"
+ " that it holds preferred stock as an intended part of its investment strategy.",
)
holds_closed_end_funds: bool | None = Field(
default=None,
description="If true, the ETF's investment objective explicitly specifies"
+ " that it holds closed end funds as an intended part of its investment strategy.",
)
holds_adr: bool | None = Field(
default=None,
description="If true, he ETF's investment objective explicitly specifies that it holds"
+ " American Depositary Receipts (ADRs) as an intended part of its investment strategy.",
)
laddered: bool | None = Field(
default=None,
description="For bond ETFs, this field identifies those ETFs that"
+ " specifically hold bonds in a laddered structure,"
+ " where the bonds are scheduled to mature in an annual, sequential structure.",
)
zero_coupon: bool | None = Field(
default=None,
description="For bond ETFs, this field identifies those ETFs that specifically hold zero coupon Treasury Bills.",
)
floating_rate: bool | None = Field(
default=None,
description="For bond ETFs, this field identifies those ETFs that specifically hold floating rate bonds.",
)
build_america_bonds: bool | None = Field(
default=None,
description="For municipal bond ETFs, this field identifies those"
+ " ETFs that specifically hold Build America Bonds.",
)
dynamic_futures_roll: bool | None = Field(
default=None,
description="If the product holds futures contracts, this field identifies those products where the roll strategy"
+ " is dynamic (rather than entirely rules based), so as to minimize roll costs.",
)
currency_hedged: bool | None = Field(
default=None,
description="This field is populated if the ETF's strategy involves hedging currency exposure.",
)
includes_short_exposure: bool | None = Field(
default=None,
description="This field is populated if the ETF has short exposure"
+ " in any of its holdings e.g. in a long/short or inverse ETF.",
)
ucits: bool | None = Field(
default=None,
description="If true, the Exchange Traded Product (ETP) is Undertakings for the Collective Investment"
+ " in Transferable Securities (UCITS) compliant",
)
registered_countries: str | None = Field(
default=None,
description="The list of countries where the ETF is legally registered for sale."
+ " This may differ from where the ETF is domiciled or traded, particularly in Europe.",
)
issuer_country: str | None = Field(
default=None,
description="2 letter ISO country code for the country where the issuer is located.",
)
domicile: str | None = Field(
default=None,
description="2 letter ISO country code for the country where the ETP is domiciled.",
)
listing_country: str | None = Field(
default=None,
description="2 letter ISO country code for the country of the primary listing.",
alias="listing_country_code",
)
listing_region: str | None = Field(
default=None,
description="Geographic region in the country of the primary listing falls.",
)
bond_currency_denomination: str | None = Field(
default=None,
description="For all bond ETFs, this field provides additional"
+ " detail on the currency denomination of the underlying securities.",
)
base_currency: str | None = Field(
default=None,
description="Base currency in which NAV is reported.",
)
listing_currency: str | None = Field(
default=None,
description="Listing currency of the Exchange Traded Product (ETP) in which it is traded."
+ " Reported using the 3-digit ISO currency code.",
)
number_of_holdings: int | None = Field(
default=None,
description="The number of holdings in the ETF.",
)
month_end_assets: float | None = Field(
default=None,
description="Net assets in millions of dollars as of the most recent month end.",
)
net_expense_ratio: float | None = Field(
default=None,
description="Gross expense net of Fee Waivers, as a percentage of net assets"
+ " as published by the ETF issuer.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
etf_portfolio_turnover: float | None = Field(
default=None,
description="The percentage of positions turned over in the last 12 months.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
class IntrinioEtfInfoFetcher(
Fetcher[IntrinioEtfInfoQueryParams, list[IntrinioEtfInfoData]]
):
"""Intrinio ETF Info Fetcher."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioEtfInfoQueryParams:
"""Transform query."""
return IntrinioEtfInfoQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioEtfInfoQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/etfs/"
symbols = query.symbol.split(",")
symbols = [
symbol + ":US" if ":" not in symbol else symbol for symbol in symbols
]
urls = [f"{base_url}{symbol}?api_key={api_key}" for symbol in symbols]
results = []
async def response_callback(response, _):
"""Response callback."""
result = await response.json()
if "error" in result:
warn(f"Symbol Error: {result['error']} for {response.url.parts[-1]}")
return
_ = result.pop("messages", None)
results.append(result)
await amake_requests(urls, response_callback, **kwargs) # type: ignore
if not results:
raise EmptyDataError("No data was returned.")
return sorted(
results,
key=(lambda item: (symbols.index(item.get("figi_ticker", len(symbols))))),
)
@staticmethod
def transform_data(
query: IntrinioEtfInfoQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioEtfInfoData]:
"""Transform data."""
return [IntrinioEtfInfoData.model_validate(d) for d in data]

View File

@@ -1,227 +0,0 @@
"""Intrinio ETF Performance Model."""
# pylint: disable=unused-argument
import asyncio
from datetime import date as dateType
from typing import Any, Literal
from warnings import warn
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.recent_performance import (
RecentPerformanceData,
RecentPerformanceQueryParams,
)
from openbb_core.provider.utils.descriptions import DATA_DESCRIPTIONS
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import amake_request
from openbb_intrinio.utils.references import ETF_PERFORMANCE_MAP
from pydantic import Field
class IntrinioEtfPricePerformanceQueryParams(RecentPerformanceQueryParams):
"""
Intrinio ETF Performance Query Params.
Source: https://docs.intrinio.com/documentation/web_api/get_etf_stats_v2
Source: https://docs.intrinio.com/documentation/web_api/get_etf_analytics_v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
return_type: Literal["trailing", "calendar"] = Field(
default="trailing",
description="The type of returns to return, a trailing or calendar window.",
)
adjustment: Literal["splits_only", "splits_and_dividends"] = Field(
default="splits_and_dividends",
description="The adjustment factor, 'splits_only' will return pure price performance.",
)
class IntrinioEtfPricePerformanceData(RecentPerformanceData):
"""Intrinio ETF Performance Data."""
__alias_dict__ = {
"updated": "date",
"year_high": "fifty_two_week_high",
"year_low": "fifty_two_week_low",
"volume": "volume_traded",
"volume_avg_30": "average_daily_volume_one_month",
"volume_avg_90": "average_daily_volume_three_month",
"volume_avg_180": "average_daily_volume_six_month",
}
max_annualized: float | None = Field(
default=None,
description="Annualized rate of return from inception.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
volatility_one_year: float | None = Field(
default=None,
description="Trailing one-year annualized volatility.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
volatility_three_year: float | None = Field(
default=None,
description="Trailing three-year annualized volatility.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
volatility_five_year: float | None = Field(
default=None,
description="Trailing five-year annualized volatility.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
volume: int | None = Field(
default=None,
description=DATA_DESCRIPTIONS.get("volume", ""),
)
volume_avg_30: float | None = Field(
default=None,
description="The one-month average daily volume.",
)
volume_avg_90: float | None = Field(
default=None,
description="The three-month average daily volume.",
)
volume_avg_180: float | None = Field(
default=None,
description="The six-month average daily volume.",
)
beta: float | None = Field(
default=None,
description="Beta compared to the S&P 500.",
)
nav: float | None = Field(
default=None,
description="Net asset value per share.",
)
year_high: float | None = Field(
default=None,
description="The 52-week high price.",
)
year_low: float | None = Field(
default=None,
description="The 52-week low price.",
)
market_cap: float | None = Field(
default=None,
description="The market capitalization.",
)
shares_outstanding: int | None = Field(
default=None,
description="The number of shares outstanding.",
)
updated: dateType | None = Field(
default=None,
description=DATA_DESCRIPTIONS.get("date", ""),
)
class IntrinioEtfPricePerformanceFetcher(
Fetcher[
IntrinioEtfPricePerformanceQueryParams, list[IntrinioEtfPricePerformanceData]
]
):
"""Intrinio ETF Performance Fetcher."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioEtfPricePerformanceQueryParams:
"""Transform query."""
return IntrinioEtfPricePerformanceQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioEtfPricePerformanceQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/etfs/"
symbols = query.symbol.split(",")
symbols = [
symbol + ":US" if ":" not in symbol else symbol for symbol in symbols
]
adjustment = (
"split_only"
if query.adjustment == "splits_and_dividends"
else "split_and_dividend"
)
return_type = "trailing" if query.return_type == "calendar" else "calendar"
results = []
async def get_one(symbol: str, **kwargs):
"""Get data for one symbol."""
url = f"{base_url}{symbol}/stats?api_key={api_key}"
result = await amake_request(url, **kwargs)
if "message" in result and result["message"] != []: # type: ignore
warn(f"Symbol Error: {symbol} - {result['message']}") # type: ignore
return
_ = result.pop("message", None) # type: ignore
_ = result.pop("messages", None) # type: ignore
data = {}
etf = result.pop("etf", {}) # type: ignore
data["symbol"] = etf.get("ticker")
# These items will be kept regardless of the adjustment and return_type.
keep = ["volatility", "month", "year_to_date"]
for k, v in result.copy().items(): # type: ignore
if not any(substring in k for substring in keep):
_ = result.pop(k, None) if adjustment in k else None # type: ignore
_ = result.pop(k, None) if return_type in k else None # type: ignore
if k in result:
data[ETF_PERFORMANCE_MAP.get(k, k)] = v
# Get an additional set of data to combine with the first set.
analytics_url = (
f"https://api-v2.intrinio.com/etfs/{symbol}/analytics?api_key={api_key}"
)
if data:
analytics = await amake_request(analytics_url, **kwargs)
if "messages" in analytics and analytics["messages"] != []: # type: ignore
warn(
f"Symbol Error: {analytics['messages']}" # type: ignore
+ f"for {etf.get('ticker')}" # type: ignore
)
return
# Remove the duplicate data from the analytics response.
_ = analytics.pop("messages", None) # type: ignore
_ = analytics.pop("etf", None) # type: ignore
_ = analytics.pop("date", None) # type: ignore
data.update(analytics) # type: ignore
results.append(data)
tasks = [get_one(symbol, **kwargs) for symbol in symbols]
await asyncio.gather(*tasks)
if not results:
raise EmptyDataError("No data was returned.")
# Undo any formatting changes made to the symbols before sorting.
symbols = query.symbol.replace(":US", "").split(",")
return sorted(
results,
key=(lambda item: (symbols.index(item.get("symbol", len(symbols))))),
)
@staticmethod
def transform_data(
query: IntrinioEtfPricePerformanceQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioEtfPricePerformanceData]:
"""Transform data."""
return [IntrinioEtfPricePerformanceData.model_validate(d) for d in data]

View File

@@ -1,145 +0,0 @@
"""Intrinio ETF Search Model."""
# pylint: disable=unused-argument
from typing import Any
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.etf_search import (
EtfSearchData,
EtfSearchQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_intrinio.utils.references import ETF_EXCHANGES
from pydantic import Field
class IntrinioEtfSearchQueryParams(EtfSearchQueryParams):
"""
Intrinio ETF Search Query Params.
Source: https://docs.intrinio.com/documentation/web_api/search_etfs_v2
"""
exchange: None | ETF_EXCHANGES = Field(
default=None,
description="Target a specific exchange by providing the MIC code.",
)
class IntrinioEtfSearchData(EtfSearchData):
"""Intrinio ETF Search Data."""
__alias_dict__ = {
"intrinio_id": "id",
"symbol": "ticker",
"exchange": "exchange_mic",
}
exchange: str | None = Field(
default=None,
description="The exchange MIC code.",
)
figi_ticker: str | None = Field(
None,
description="The OpenFIGI ticker.",
)
ric: str | None = Field(
None,
description="The Reuters Instrument Code.",
)
isin: str | None = Field(
None,
description="The International Securities Identification Number.",
)
sedol: str | None = Field(
None,
description="The Stock Exchange Daily Official List.",
)
intrinio_id: str | None = Field(
None,
description="The unique Intrinio ID for the security.",
)
class IntrinioEtfSearchFetcher(
Fetcher[IntrinioEtfSearchQueryParams, list[IntrinioEtfSearchData]]
):
"""Intrinio ETF Search Fetcher."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioEtfSearchQueryParams:
"""Transform query."""
return IntrinioEtfSearchQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioEtfSearchQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_request,
)
api_key = credentials.get("intrinio_api_key") if credentials else ""
BASE = "https://api-v2.intrinio.com/etfs"
if query.exchange is not None:
url = f"{BASE}?exchange={query.exchange.upper()}&page_size=10000&api_key={api_key}"
elif query.query:
url = f"{BASE}/search?query={query.query}&page_size=10000&api_key={api_key}"
else:
url = f"{BASE}?page_size=10000&api_key={api_key}"
data: list = []
async def response_callback(response: ClientResponse, session: ClientSession):
"""Async response callback."""
results = await response.json()
if results.get("messages"): # type: ignore
messages = results.get("messages") # type: ignore
raise OpenBBError(str(messages))
if results.get("etfs") and len(results.get("etfs")) > 0: # type: ignore
data.extend(results.get("etfs")) # type: ignore
while results.get("next_page"): # type: ignore
next_page = results["next_page"] # type: ignore
next_url = f"{url}&next_page={next_page}"
results = await amake_request(next_url, session=session, **kwargs)
if "etfs" in results and len(results.get("etfs")) > 0: # type: ignore
data.extend(results.get("etfs")) # type: ignore
return data
return await amake_request(url, response_callback=response_callback, **kwargs) # type: ignore
@staticmethod
def transform_data(
query: IntrinioEtfSearchQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioEtfSearchData]:
"""Transform data."""
# pylint: disable=import-outside-toplevel
import re # noqa
from pandas import DataFrame # noqa
if not data:
raise EmptyDataError("No data found.")
results = DataFrame(data)
if query.query:
pattern = f".*{re.escape(query.query)}.*"
results = results[
results["name"].str.contains(pattern, case=False, regex=True)
]
return [
IntrinioEtfSearchData.model_validate(d)
for d in results.to_dict(orient="records")
]

View File

@@ -1,80 +0,0 @@
"""Intrinio Financial Attributes Model."""
# pylint: disable=unused-argument
from datetime import datetime
from typing import Any
from dateutil.relativedelta import relativedelta
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.financial_attributes import (
FinancialAttributesData,
FinancialAttributesQueryParams,
)
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_many
class IntrinioFinancialAttributesQueryParams(FinancialAttributesQueryParams):
"""Intrinio Financial Attributes Query."""
__alias_dict__ = {"sort": "sort_order", "limit": "page_size"}
class IntrinioFinancialAttributesData(FinancialAttributesData):
"""Intrinio Financial Attributes Data."""
class IntrinioFinancialAttributesFetcher(
Fetcher[
IntrinioFinancialAttributesQueryParams,
list[IntrinioFinancialAttributesData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioFinancialAttributesQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = now - relativedelta(years=5)
if params.get("end_date") is None:
transformed_params["end_date"] = now
return IntrinioFinancialAttributesQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioFinancialAttributesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
frequency = "yearly" if query.period == "annual" else "quarterly"
data: list[dict] = []
base_url = "https://api-v2.intrinio.com"
query_str = get_querystring(query.model_dump(by_alias=True), ["frequency"])
query_str = f"{query_str}&frequency={frequency}"
url = f"{base_url}/historical_data/{query.symbol}/{query.tag}?{query_str}&api_key={api_key}"
# data = get_data_one(url).get("historical_data", [])
data = await get_data_many(url, "historical_data")
return data
@staticmethod
def transform_data(
query: IntrinioFinancialAttributesQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioFinancialAttributesData]:
"""Return the transformed data."""
return [IntrinioFinancialAttributesData.model_validate(item) for item in data]

View File

@@ -1,322 +0,0 @@
"""Intrinio Financial Ratios Model."""
# pylint: disable=unused-argument
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.financial_ratios import (
FinancialRatiosData,
FinancialRatiosQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import ClientResponse, amake_requests
from openbb_intrinio.utils.helpers import get_data_one
from pydantic import Field, field_validator
class IntrinioFinancialRatiosQueryParams(FinancialRatiosQueryParams):
"""Intrinio Financial Ratios Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_fundamentals_v2
Source: https://docs.intrinio.com/documentation/web_api/get_fundamental_standardized_financials_v2
"""
__json_schema_extra__ = {
"period": {
"choices": ["annual", "quarter", "ttm", "ytd"],
}
}
period: Literal["annual", "quarter", "ttm", "ytd"] = Field(
default="annual",
description=QUERY_DESCRIPTIONS.get("period", ""),
)
fiscal_year: int | None = Field(
default=None,
description="The specific fiscal year. Reports do not go beyond 2008.",
)
@field_validator("symbol", mode="after", check_fields=False)
@classmethod
def handle_symbol(cls, v) -> str:
"""Handle symbols with a dash and replace it with a dot for Intrinio."""
return v.replace("-", ".")
class IntrinioFinancialRatiosData(FinancialRatiosData):
"""Intrinio Financial Ratios Data."""
__alias_dict__ = {
"net_operating_profit_after_tax_margin": "nopatmargin",
"invested_capital_turnover": "investedcapitalturnover",
"book_value_per_share": "bookvaluepershare",
"tangible_book_value": "tangiblebookvaluepershare",
"price_to_book_ratio": "pricetobook",
"price_to_tangible_book_ratio": "pricetotangiblebook",
"price_to_revenue": "pricetorevenue",
"price_to_earnings": "pricetoearnings",
"dividend_yield": "dividendyield",
"earnings_yield": "earningsyield",
"ev_to_invested_capital": "evtoinvestedcapital",
"ev_to_sales": "evtorevenue",
"ev_to_ebitda": "evtoebitda",
"ev_to_ebit": "evtoebit",
"ev_to_nopat": "evtonopat",
"ev_to_operating_cash_flow": "evtoocf",
"ev_to_free_cash_flow": "evtofcff",
"gross_margin": "grossmargin",
"ebitda_margin": "ebitdamargin",
"operating_margin": "operatingmargin",
"ebit_margin": "ebitmargin",
"net_profit_margin": "profitmargin",
"cost_of_rev_to_revenue": "costofrevtorevenue",
"sga_expense_to_revenue": "sgaextorevenue",
"rd_expense_to_revenue": "rdextorevenue",
"op_expense_to_revenue": "opextorevenue",
"tax_burden_percent": "taxburdenpct",
"interest_burden_percent": "interestburdenpct",
"effective_tax_rate": "efftaxrate",
"asset_turnover": "assetturnover",
"receivables_turnover": "arturnover",
"inventory_turnover": "invturnover",
"fixed_asset_turnover": "faturnover",
"payables_turnover": "apturnover",
"days_of_sales_outstanding": "dso",
"days_of_inventory_outstanding": "dio",
"days_payable_outstanding": "dpo",
"cash_conversion_cycle": "ccc",
"financial_leverage": "finleverage",
"leverage_ratio": "leverageratio",
"compound_leverage_factor": "compoundleveragefactor",
"long_term_debt_equity_ratio": "ltdebttoequity",
"debt_equity_ratio": "debttoequity",
"return_on_invested_capital": "roic",
"net_non_operating_expense_percent": "nnep",
"roic_nnep_spread": "roicnnepspread",
"return_on_net_non_operating_assets": "rnnoa",
"return_on_equity": "roe",
"cash_returned_on_invested_capitals": "croic",
"operating_return_on_assets": "oroa",
"return_on_assets": "roa",
"non_controlling_interest_sharing_ratio": "noncontrollinginterestsharingratio",
"return_on_common_equity": "roce",
"dividend_payout_ratio": "divpayoutratio",
"augmented_payout_ratio": "augmentedpayoutratio",
"operating_cash_flow_to_capex": "ocftocapex",
"short_term_debt_to_capitalization": "stdebttocap",
"long_term_debt_to_capitalization": "ltdebttocap",
"debt_to_capitalization": "debttototalcapital",
"preferred_equity_to_capitalization": "preferredtocap",
"non_controlling_interests_to_capitalization": "noncontrolinttocap",
"equity_to_capitalization": "commontocap",
"debt_to_ebitda": "debttoebitda",
"net_debt_to_ebitda": "netdebttoebitda",
"long_term_debt_to_ebita": "ltdebttoebitda",
"debt_to_nopat": "debttonopat",
"net_debt_to_nopat": "netdebttonopat",
"long_term_debt_to_nopat": "ltdebttonopat",
"altman_z_score": "altmanzscore",
"ebit_to_interest_expense": "ebittointerestex",
"nopat_to_intersest_expense": "nopattointerestex",
"ebit_less_capex_to_interest_expense": "ebitlesscapextointerestex",
"nopat_less_capex_to_interest_expense": "nopatlesscapextointex",
"operating_cash_flow_to_interest_expense": "ocftointerestex",
"operating_cash_flow_less_capex_to_interest_expense": "ocflesscapextointerestex",
"free_cash_flow_to_interest_expense": "fcfftointerestex",
"current_ratio": "curratio",
"quick_ratio": "quickratio",
"debt_free_cash_free_nwc_to_revenue": "dfcfnwctorev",
"debt_free_nwc_to_revenue": "dfnwctorev",
"net_working_capital_to_revenue": "nwctorev",
"normalized_nopat_margin": "normalizednopatmargin",
"pre_tax_income_margin": "pretaxincomemargin",
"adjusted_basic_eps": "adjbasiceps",
"adjusted_diluted_eps": "adjdilutedeps",
"adjusted_basic_diluted_eps": "adjbasicdilutedeps",
"return_on_equity_simple": "roe_simple",
}
class IntrinioFinancialRatiosFetcher(
Fetcher[
IntrinioFinancialRatiosQueryParams,
list[IntrinioFinancialRatiosData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioFinancialRatiosQueryParams:
"""Transform the query params."""
return IntrinioFinancialRatiosQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioFinancialRatiosQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
statement_code = "calculations"
if query.period in ["quarter", "annual"]:
period_type = "FY" if query.period == "annual" else "QTR"
elif query.period in ["ttm", "ytd"]:
period_type = query.period.upper()
else:
raise OpenBBError(f"Period '{query.period}' not supported.")
fundamentals_data: dict = {}
base_url = "https://api-v2.intrinio.com"
fundamentals_url = (
f"{base_url}/companies/{query.symbol}"
f"/fundamentals?statement_code={statement_code}&type={period_type}"
)
if query.fiscal_year is not None:
if query.fiscal_year < 2008:
warn("Financials data is only available from 2008 and later.")
query.fiscal_year = 2008
fundamentals_url = fundamentals_url + f"&fiscal_year={query.fiscal_year}"
fundamentals_url = fundamentals_url + f"&api_key={api_key}"
fundamentals_data = (await get_data_one(fundamentals_url, **kwargs)).get(
"fundamentals", []
)
ids = [item["id"] for item in fundamentals_data]
ids = ids[: query.limit]
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
statement_data = await response.json()
return {
"period_ending": statement_data["fundamental"]["end_date"], # type: ignore
"fiscal_year": statement_data["fundamental"]["fiscal_year"], # type: ignore
"fiscal_period": statement_data["fundamental"]["fiscal_period"], # type: ignore
"calculations": statement_data["standardized_financials"], # type: ignore
}
urls = [
f"https://api-v2.intrinio.com/fundamentals/{id}/standardized_financials?api_key={api_key}"
for id in ids
]
return await amake_requests(urls, callback, **kwargs) # type: ignore
@staticmethod
def transform_data(
query: IntrinioFinancialRatiosQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioFinancialRatiosData]:
"""Return the transformed data."""
transformed_data: list[IntrinioFinancialRatiosData] = []
tags = [
"nopatmargin",
"investedcapitalturnover",
"bookvaluepershare",
"tangiblebookvaluepershare",
"pricetobook",
"pricetotangiblebook",
"pricetorevenue",
"pricetoearnings",
"dividendyield",
"earningsyield",
"evtoinvestedcapital",
"evtorevenue",
"evtoebitda",
"evtoebit",
"evtonopat",
"evtoocf",
"evtofcff",
"grossmargin",
"ebitdamargin",
"operatingmargin",
"ebitmargin",
"profitmargin",
"costofrevtorevenue",
"sgaextorevenue",
"rdextorevenue",
"opextorevenue",
"taxburdenpct",
"interestburdenpct",
"efftaxrate",
"assetturnover",
"arturnover",
"invturnover",
"faturnover",
"apturnover",
"dso",
"dio",
"dpo",
"ccc",
"finleverage",
"leverageratio",
"compoundleveragefactor",
"ltdebttoequity",
"debttoequity",
"roic",
"nnep",
"roicnnepspread",
"rnnoa",
"roe",
"croic",
"oroa",
"roa",
"noncontrollinginterestsharingratio",
"roce",
"divpayoutratio",
"augmentedpayoutratio",
"ocftocapex",
"stdebttocap",
"ltdebttocap",
"debttototalcapital",
"preferredtocap",
"noncontrolinttocap",
"commontocap",
"debttoebitda",
"netdebttoebitda",
"ltdebttoebitda",
"debttonopat",
"netdebttonopat",
"ltdebttonopat",
"altmanzscore",
"ebittointerestex",
"nopattointerestex",
"ebitlesscapextointerestex",
"nopatlesscapextointex",
"ocftointerestex",
"ocflesscapextointerestex",
"fcfftointerestex",
"curratio",
"quickratio",
"dfcfnwctorev",
"dfnwctorev",
"nwctorev",
"normalizednopatmargin",
"pretaxincomemargin",
"adjbasiceps",
"adjdilutedeps",
"adjbasicdilutedeps",
"roe_simple",
]
for item in data:
sub_dict: dict[str, Any] = {}
for sub_item in item["calculations"]:
field_name = sub_item["data_tag"]["tag"]
if field_name in tags:
sub_dict[field_name] = (
float(sub_item["value"])
if sub_item["value"] and sub_item["value"] != 0
else None
)
sub_dict["period_ending"] = item["period_ending"]
sub_dict["fiscal_year"] = item["fiscal_year"]
sub_dict["fiscal_period"] = item["fiscal_period"]
transformed_data.append(IntrinioFinancialRatiosData(**sub_dict))
return transformed_data

View File

@@ -1,199 +0,0 @@
"""Intrinio Forward EBITDA Estimates Model."""
# pylint: disable=unused-argument
import asyncio
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.forward_ebitda_estimates import (
ForwardEbitdaEstimatesData,
ForwardEbitdaEstimatesQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError, UnauthorizedError
from openbb_core.provider.utils.helpers import (
amake_request,
get_querystring,
)
from openbb_intrinio.utils.helpers import response_callback
from pydantic import Field
class IntrinioForwardEbitdaEstimatesQueryParams(ForwardEbitdaEstimatesQueryParams):
"""Intrinio Forward EBITDA Estimates Query.
https://docs.intrinio.com/documentation/web_api/get_zacks_sales_estimates_v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
__alias_dict__ = {"estimate_type": "type"}
fiscal_period: Literal["annual", "quarter"] | None = Field(
default=None, description="Filter for only full-year or quarterly estimates."
)
estimate_type: (
Literal[
"ebitda", "ebit", "enterprise_value", "cash_flow_per_share", "pretax_income"
]
| None
) = Field(
default=None,
description="Limit the EBITDA estimates to this type.",
)
class IntrinioForwardEbitdaEstimatesData(ForwardEbitdaEstimatesData):
"""Intrinio Forward EBITDA Estimates Data."""
__alias_dict__ = {
"last_updated": "updated_date",
"symbol": "ticker",
"calendar_period": "estimate_month",
"name": "company_name",
"fiscal_year": "estimate_year",
"fiscal_period": "period",
"low_estimate": "low",
"high_estimate": "high",
"number_of_analysts": "estimate_count",
"standard_deviation": "std_dev",
}
conensus_type: (
Literal[
"ebitda",
"ebitda",
"ebit",
"enterprise_value",
"cash_flow_per_share",
"pretax_income",
]
| None
) = Field(
default=None,
description="The type of estimate.",
)
class IntrinioForwardEbitdaEstimatesFetcher(
Fetcher[
IntrinioForwardEbitdaEstimatesQueryParams,
list[IntrinioForwardEbitdaEstimatesData],
]
):
"""Intrinio Forward EBITDA Estimates Fetcher."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioForwardEbitdaEstimatesQueryParams:
"""Transform the query params."""
return IntrinioForwardEbitdaEstimatesQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioForwardEbitdaEstimatesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
BASE_URL = (
"https://api-v2.intrinio.com/zacks/ebitda_consensus?"
+ f"page_size=10000&api_key={api_key}"
)
symbols = query.symbol.split(",") if query.symbol else None
query_str = get_querystring(query.model_dump(by_alias=True), ["symbol"])
results: list[dict] = []
async def get_one(symbol):
"""Get the data for one symbol."""
url = f"{BASE_URL}&identifier={symbol}"
url = url + f"&{query_str}" if query_str else url
data = await amake_request(
url, response_callback=response_callback, **kwargs
)
consensus = (
data.get("ebitda_consensus")
if isinstance(data, dict) and "ebitda_consensus" in data
else []
)
if not data or not consensus:
warn(f"Symbol Error: No data found for {symbol}")
if consensus:
results.extend(consensus)
if symbols:
await asyncio.gather(*[get_one(symbol) for symbol in symbols])
if not results:
raise EmptyDataError(f"No results were found. -> {query.symbol}")
return results
async def fetch_callback(response, session):
"""Use callback for pagination."""
data = await response.json()
error = data.get("error", None)
if error:
message = data.get("message", "")
if "api key" in message.lower():
raise UnauthorizedError(
f"Unauthorized Intrinio request -> {message}"
)
raise OpenBBError(f"Error: {error} -> {message}")
estimates = data.get("ebitda_consensus", []) # type: ignore
if estimates and len(estimates) > 0:
results.extend(estimates)
while data.get("next_page"): # type: ignore
next_page = data["next_page"] # type: ignore
next_url = f"{url}&next_page={next_page}"
data = await amake_request(next_url, session=session, **kwargs)
consensus = (
data.get("ebitda_consensus")
if isinstance(data, dict) and "ebitda_consensus" in data
else []
)
if consensus:
results.extend(consensus) # type: ignore
return results
url = f"{BASE_URL}&{query_str}" if query_str else BASE_URL
results = await amake_request(url, response_callback=fetch_callback, **kwargs) # type: ignore
if not results:
raise EmptyDataError("The request was successful but was returned empty.")
return results
@staticmethod
def transform_data(
query: IntrinioForwardEbitdaEstimatesQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioForwardEbitdaEstimatesData]:
"""Transform the raw data into the standard format."""
if not data:
raise EmptyDataError()
results: list[IntrinioForwardEbitdaEstimatesData] = []
fiscal_period = None
if query.fiscal_period is not None:
fiscal_period = "fy" if query.fiscal_period == "annual" else "fq"
for item in data:
estimate_count = item.get("estimate_count")
if (
not estimate_count
or estimate_count == 0
or not item.get("updated_date")
):
continue
if fiscal_period and item.get("period") != fiscal_period:
continue
results.append(IntrinioForwardEbitdaEstimatesData.model_validate(item))
if not results:
raise EmptyDataError()
return sorted(
results, key=lambda x: (x.fiscal_year, x.last_updated), reverse=True
)

View File

@@ -1,231 +0,0 @@
"""Intrinio Forward EPS Estimates Model."""
# pylint: disable=unused-argument
import asyncio
from datetime import datetime
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.forward_eps_estimates import (
ForwardEpsEstimatesData,
ForwardEpsEstimatesQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError, UnauthorizedError
from openbb_core.provider.utils.helpers import (
amake_request,
get_querystring,
)
from openbb_intrinio.utils.helpers import response_callback
from pydantic import Field, field_validator, model_validator
class IntrinioForwardEpsEstimatesQueryParams(ForwardEpsEstimatesQueryParams):
"""Intrinio Forward EPS Estimates Query.
https://docs.intrinio.com/documentation/web_api/get_zacks_sales_estimates_v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
fiscal_year: int | None = Field(
default=None,
description="The future fiscal year to retrieve estimates for."
+ " When no symbol and year is supplied the current calendar year is used.",
)
fiscal_period: Literal["fy", "q1", "q2", "q3", "q4"] | None = Field(
default=None,
description="The future fiscal period to retrieve estimates for.",
)
calendar_year: int | None = Field(
default=None,
description="The future calendar year to retrieve estimates for."
+ " When no symbol and year is supplied the current calendar year is used.",
)
calendar_period: Literal["q1", "q2", "q3", "q4"] | None = Field(
default=None,
description="The future calendar period to retrieve estimates for.",
)
@model_validator(mode="after")
@classmethod
def validate_choices(cls, values):
"""Validate the model and set a safe default state."""
if values.symbol is None and (
values.calendar_year is None and values.fiscal_year is None
):
values.calendar_year = datetime.now().year
return values
class IntrinioForwardEpsEstimatesData(ForwardEpsEstimatesData):
"""Intrinio Forward EPS Estimates Data."""
__alias_dict__ = {
"high_estimate": "high",
"low_estimate": "low",
"number_of_analysts": "count",
"mean": "estimated_sales_mean",
"revisions_change_percent": "percent_change",
"mean_1w": "mean_7_days_ago",
"mean_1m": "mean_30_days_ago",
"mean_2m": "mean_60_days_ago",
"mean_3m": "mean_90_days_ago",
}
revisions_change_percent: float | None = Field(
default=None,
description="The earnings per share (EPS) percent change in estimate for the period.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
mean_1w: float | None = Field(
default=None,
description="The mean estimate for the period one week ago.",
)
mean_1m: float | None = Field(
default=None,
description="The mean estimate for the period one month ago.",
)
mean_2m: float | None = Field(
default=None,
description="The mean estimate for the period two months ago.",
)
mean_3m: float | None = Field(
default=None,
description="The mean estimate for the period three months ago.",
)
@field_validator(
"revisions_change_percent",
mode="before",
check_fields=False,
)
@classmethod
def normalize_percent(cls, v: int | float | None) -> int | float | None:
"""Normalize percent values."""
return v / 100 if v else None
class IntrinioForwardEpsEstimatesFetcher(
Fetcher[
IntrinioForwardEpsEstimatesQueryParams, list[IntrinioForwardEpsEstimatesData]
]
):
"""Intrinio Forward EPS Estimates Fetcher."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioForwardEpsEstimatesQueryParams:
"""Transform the query params."""
return IntrinioForwardEpsEstimatesQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioForwardEpsEstimatesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
BASE_URL = "https://api-v2.intrinio.com/zacks/eps_estimates?page_size=10000"
symbols = query.symbol.split(",") if query.symbol else None
query_str = get_querystring(
query.model_dump(by_alias=True),
["symbol", "calendar_period", "fiscal_period", "limit"],
)
results: list[dict] = []
async def get_one(symbol):
"""Get the data for one symbol."""
url = f"{BASE_URL}&identifier={symbol}&{query_str}&api_key={api_key}"
new_data: list[dict] = []
data = await amake_request(
url, response_callback=response_callback, **kwargs
)
if not data or not isinstance(data, dict) or not data.get("estimates"):
warn(f"Symbol Error: No data found for {symbol}")
if isinstance(data, dict) and data.get("estimates"):
new_data = data.get("estimates") # type: ignore
if new_data:
results.extend(new_data)
if symbols:
await asyncio.gather(*[get_one(symbol) for symbol in symbols])
return results
async def fetch_callback(response, session):
"""Use callback for pagination."""
data = await response.json()
error = data.get("error", None)
if error:
message = data.get("message", "")
if "api key" in message.lower():
raise UnauthorizedError(
f"Unauthorized Intrinio request -> {message}"
)
raise OpenBBError(f"Error: {error} -> {message}")
if data.get("estimates") and len(data.get("estimates")) > 0: # type: ignore
results.extend(data.get("estimates")) # type: ignore
while data.get("next_page"): # type: ignore
next_page = data["next_page"] # type: ignore
next_url = f"{url}&next_page={next_page}"
data = await amake_request(next_url, session=session, **kwargs)
if "estimates" in data and len(data.get("estimates")) > 0: # type: ignore
results.extend(data.get("estimates")) # type: ignore
return results
url = f"{BASE_URL}&{query_str}&api_key={api_key}"
results = await amake_request(url, response_callback=fetch_callback, **kwargs) # type: ignore
if not results:
raise EmptyDataError("The request was successful but was returned empty.")
return results
@staticmethod
def transform_data(
query: IntrinioForwardEpsEstimatesQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioForwardEpsEstimatesData]:
"""Transform the raw data into the standard format."""
symbols = query.symbol.split(",") if query.symbol else []
results: list[IntrinioForwardEpsEstimatesData] = []
for item in sorted(
data,
key=lambda item: ( # type: ignore
(
symbols.index(item.get("symbol")) if item.get("symbol") in symbols else len(symbols), # type: ignore
item.get("date"),
)
if symbols
else item.get("date")
),
):
temp: dict[str, Any] = {}
company = item.pop("company")
if company.get("ticker") is None:
continue
temp["symbol"] = company.get("ticker")
temp["name"] = company.get("name")
if query.fiscal_period and query.fiscal_period.upper() != item.get(
"fiscal_period"
):
continue
if query.calendar_period and query.calendar_period.upper() != item.get(
"calendar_period"
):
continue
temp.update(item)
results.append(IntrinioForwardEpsEstimatesData.model_validate(temp))
return results

View File

@@ -1,163 +0,0 @@
"""Intrinio Forward PE Estimates Model."""
# pylint: disable=unused-argument
from datetime import date as dateType
from typing import Any
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.forward_pe_estimates import (
ForwardPeEstimatesData,
ForwardPeEstimatesQueryParams,
)
from pydantic import Field
class IntrinioForwardPeEstimatesQueryParams(ForwardPeEstimatesQueryParams):
"""Intrinio Forward PE Estimates Query.
https://api-v2.intrinio.com/zacks/forward_pe?
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
class IntrinioForwardPeEstimatesData(ForwardPeEstimatesData):
"""Intrinio Forward PE Estimates Data."""
__alias_dict__ = {
"symbol": "ticker",
"name": "company_name",
"year1": "forward_pe_year1",
"year2": "forward_pe_year2",
"year3": "forward_pe_year3",
"year4": "forward_pe_year4",
"year5": "forward_pe_year5",
"peg_ratio_year1": "forward_peg_ratio_year1",
"eps_ttm": "latest_ttm_eps",
"last_updated": "updated_date",
}
peg_ratio_year1: float | None = Field(
default=None,
description="Estimated Forward PEG ratio for the next fiscal year.",
)
eps_ttm: float | None = Field(
default=None,
description="The latest trailing twelve months earnings per share.",
)
last_updated: dateType | None = Field(
default=None,
description="The date the data was last updated.",
)
class IntrinioForwardPeEstimatesFetcher(
Fetcher[IntrinioForwardPeEstimatesQueryParams, list[IntrinioForwardPeEstimatesData]]
):
"""Intrinio Forward PE Estimates Fetcher."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioForwardPeEstimatesQueryParams:
"""Transform the query params."""
return IntrinioForwardPeEstimatesQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioForwardPeEstimatesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
import asyncio # noqa
from openbb_core.provider.utils.errors import EmptyDataError, UnauthorizedError
from openbb_core.provider.utils.helpers import amake_request
from openbb_intrinio.utils.helpers import response_callback
api_key = credentials.get("intrinio_api_key") if credentials else ""
BASE_URL = "https://api-v2.intrinio.com/zacks/forward_pe"
symbols = query.symbol.split(",") if query.symbol else None
results: list[dict] = []
async def get_one(symbol):
"""Get the data for one symbol."""
url = f"{BASE_URL}/{symbol}?api_key={api_key}"
try:
data = await amake_request(
url, response_callback=response_callback, **kwargs
)
except Exception as e:
raise OpenBBError(e) from e
if data:
results.append(data) # type: ignore
if symbols:
try:
gather_results = await asyncio.gather(
*[get_one(symbol) for symbol in symbols], return_exceptions=True
)
for result in gather_results:
if isinstance(result, UnauthorizedError):
raise result
if isinstance(result, OpenBBError):
raise result
if not results:
raise EmptyDataError(
f"There were no results found for any of the given symbols. -> {symbols}"
)
return results
except Exception as e:
raise OpenBBError(
f"Error in Intrinio request -> {e} -> {symbols}"
) from e
async def fetch_callback(response, session):
"""Use callback for pagination."""
data = await response.json()
error = data.get("error", None)
if error:
message = data.get("message", "")
if "api key" in message.lower() or "view this data" in error.lower():
raise UnauthorizedError(
f"Unauthorized Intrinio request -> {message} -> {error}"
)
raise OpenBBError(f"Error: {error} -> {message}")
forward_pe = data.get("forward_pe")
if forward_pe and len(forward_pe) > 0: # type: ignore
results.extend(forward_pe) # type: ignore
return results
url = f"{BASE_URL}?page_size=10000&api_key={api_key}"
results = await amake_request(url, response_callback=fetch_callback, **kwargs) # type: ignore
if not results:
raise EmptyDataError("The request was successful but was returned empty.")
return results
@staticmethod
def transform_data(
query: IntrinioForwardPeEstimatesQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioForwardPeEstimatesData]:
"""Transform the raw data into the standard format."""
symbols = query.symbol.split(",") if query.symbol else []
if symbols:
data.sort(
key=lambda item: (
symbols.index(item.get("ticker")) if item.get("ticker") in symbols else len(symbols) # type: ignore
)
)
return [IntrinioForwardPeEstimatesData.model_validate(d) for d in data]

View File

@@ -1,249 +0,0 @@
"""Intrinio Forward Sales Estimates Model."""
# pylint: disable=unused-argument
import asyncio
from datetime import datetime
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.forward_sales_estimates import (
ForwardSalesEstimatesData,
ForwardSalesEstimatesQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError, UnauthorizedError
from openbb_core.provider.utils.helpers import (
amake_request,
get_querystring,
)
from openbb_intrinio.utils.helpers import response_callback
from pydantic import Field, field_validator, model_validator
class IntrinioForwardSalesEstimatesQueryParams(ForwardSalesEstimatesQueryParams):
"""Intrinio Forward Sales Estimates Query.
https://docs.intrinio.com/documentation/web_api/get_zacks_sales_estimates_v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
fiscal_year: int | None = Field(
default=None,
description="The future fiscal year to retrieve estimates for."
+ " When no symbol and year is supplied the current calendar year is used.",
)
fiscal_period: Literal["fy", "q1", "q2", "q3", "q4"] | None = Field(
default=None,
description="The future fiscal period to retrieve estimates for.",
)
calendar_year: int | None = Field(
default=None,
description="The future calendar year to retrieve estimates for."
+ " When no symbol and year is supplied the current calendar year is used.",
)
calendar_period: Literal["q1", "q2", "q3", "q4"] | None = Field(
default=None,
description="The future calendar period to retrieve estimates for.",
)
@model_validator(mode="after")
@classmethod
def validate_choices(cls, values):
"""Validate the model and set a safe default state."""
if values.symbol is None and (
values.calendar_year is None and values.fiscal_year is None
):
values.calendar_year = datetime.now().year
return values
class IntrinioForwardSalesEstimatesData(ForwardSalesEstimatesData):
"""Intrinio Forward Sales Estimates Data."""
__alias_dict__ = {
"low_estimate": "low",
"high_estimate": "high",
"number_of_analysts": "count",
"mean": "estimated_sales_mean",
"revisions_1w_up": "analyst_revisions_up_1w",
"revisions_1w_down": "analyst_revisions_down_1w",
"revisions_1w_change_percent": "analyst_revisions_percent_change_1w",
"revisions_1m_up": "analyst_revisions_up_1m",
"revisions_1m_down": "analyst_revisions_down_1m",
"revisions_1m_change_percent": "analyst_revisions_percent_change_1m",
"revisions_3m_up": "analyst_revisions_up_3m",
"revisions_3m_down": "analyst_revisions_down_3m",
"revisions_3m_change_percent": "analyst_revisions_percent_change_3m",
}
revisions_1w_up: int | None = Field(
default=None, description="Number of revisions up in the last week."
)
revisions_1w_down: int | None = Field(
default=None, description="Number of revisions down in the last week."
)
revisions_1w_change_percent: float | None = Field(
default=None,
description="The analyst revisions percent change in estimate for the period of 1 week.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
revisions_1m_up: int | None = Field(
default=None, description="Number of revisions up in the last month."
)
revisions_1m_down: int | None = Field(
default=None, description="Number of revisions down in the last month."
)
revisions_1m_change_percent: float | None = Field(
default=None,
description="The analyst revisions percent change in estimate for the period of 1 month.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
revisions_3m_up: int | None = Field(
default=None, description="Number of revisions up in the last 3 months."
)
revisions_3m_down: int | None = Field(
default=None, description="Number of revisions down in the last 3 months."
)
revisions_3m_change_percent: float | None = Field(
default=None,
description="The analyst revisions percent change in estimate for the period of 3 months.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
@field_validator(
"revisions_1w_change_percent",
"revisions_1m_change_percent",
"revisions_3m_change_percent",
mode="before",
check_fields=False,
)
@classmethod
def normalize_percent(cls, v: int | float | None) -> int | float | None:
"""Normalize percent values."""
return v / 100 if v else None
class IntrinioForwardSalesEstimatesFetcher(
Fetcher[
IntrinioForwardSalesEstimatesQueryParams,
list[IntrinioForwardSalesEstimatesData],
]
):
"""Intrinio Forward Sales Estimates Fetcher."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioForwardSalesEstimatesQueryParams:
"""Transform the query params."""
return IntrinioForwardSalesEstimatesQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioForwardSalesEstimatesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
BASE_URL = "https://api-v2.intrinio.com/zacks/sales_estimates?page_size=10000"
symbols = query.symbol.split(",") if query.symbol else None
query_str = get_querystring(
query.model_dump(by_alias=True),
["symbol", "calendar_period", "fiscal_period", "limit"],
)
results: list[dict] = []
async def get_one(symbol):
"""Get the data for one symbol."""
url = f"{BASE_URL}&identifier={symbol}&{query_str}&api_key={api_key}"
new_data: list[dict] = []
data = await amake_request(
url, response_callback=response_callback, **kwargs
)
if not data or not isinstance(data, dict) or not data.get("estimates"):
warn(f"Symbol Error: No data found for {symbol}")
if isinstance(data, dict) and data.get("estimates"):
new_data = data.get("estimates") # type: ignore
if new_data:
results.extend(new_data)
if symbols:
await asyncio.gather(*[get_one(symbol) for symbol in symbols])
return results
async def fetch_callback(response, session):
"""Use callback for pagination."""
data = await response.json()
error = data.get("error", None)
if error:
message = data.get("message", "")
if "api key" in message.lower():
raise UnauthorizedError(
f"Unauthorized Intrinio request -> {message}"
)
raise OpenBBError(f"Error: {error} -> {message}")
if data.get("estimates") and len(data.get("estimates")) > 0: # type: ignore
results.extend(data.get("estimates")) # type: ignore
while data.get("next_page"): # type: ignore
next_page = data["next_page"] # type: ignore
next_url = f"{url}&next_page={next_page}"
data = await amake_request(next_url, session=session, **kwargs)
if "estimates" in data and len(data.get("estimates")) > 0: # type: ignore
results.extend(data.get("estimates")) # type: ignore
return results
url = f"{BASE_URL}&{query_str}&api_key={api_key}"
results = await amake_request(url, response_callback=fetch_callback, **kwargs) # type: ignore
if not results:
raise EmptyDataError("The request was successful but was returned empty.")
return results
@staticmethod
def transform_data(
query: IntrinioForwardSalesEstimatesQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioForwardSalesEstimatesData]:
"""Transform the raw data into the standard format."""
symbols = query.symbol.split(",") if query.symbol else []
results: list[IntrinioForwardSalesEstimatesData] = []
for item in sorted(
data,
key=lambda item: ( # type: ignore
(
symbols.index(item.get("symbol")) if item.get("symbol") in symbols else len(symbols), # type: ignore
item.get("date"),
)
if symbols
else item.get("date")
),
):
temp: dict[str, Any] = {}
company = item.pop("company")
if company.get("ticker") is None:
continue
temp["symbol"] = company.get("ticker")
temp["name"] = company.get("name")
if query.fiscal_period and query.fiscal_period.upper() != item.get(
"fiscal_period"
):
continue
if query.calendar_period and query.calendar_period.upper() != item.get(
"calendar_period"
):
continue
temp.update(item)
results.append(IntrinioForwardSalesEstimatesData.model_validate(temp))
return results

View File

@@ -1,119 +0,0 @@
"""Intrinio FRED Series Model."""
# pylint: disable=unused-argument
import asyncio
from datetime import datetime
from typing import Any
from dateutil.relativedelta import relativedelta
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.fred_series import (
SeriesData,
SeriesQueryParams,
)
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_requests,
get_querystring,
)
from pydantic import Field
class IntrinioFredSeriesQueryParams(SeriesQueryParams):
"""Intrinio FRED Series Query.
Source: https://docs.intrinio.com/documentation/web_api/get_economic_index_historical_data_v2
"""
__alias_dict__ = {"limit": "page_size"}
all_pages: bool | None = Field(
default=False,
description="Returns all pages of data from the API call at once.",
)
sleep: float | None = Field(
default=1.0,
description="Time to sleep between requests to avoid rate limiting.",
)
class IntrinioFredSeriesData(SeriesData):
"""Intrinio FRED Series Data."""
value: float | None = Field(default=None, description="Value of the index.")
class IntrinioFredSeriesFetcher(
Fetcher[
IntrinioFredSeriesQueryParams,
list[IntrinioFredSeriesData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioFredSeriesQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = now - relativedelta(years=1)
if params.get("end_date") is None:
transformed_params["end_date"] = now
return IntrinioFredSeriesQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioFredSeriesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com"
query_str = get_querystring(
query.model_dump(), ["symbol", "all_pages", "sleep"]
)
url = (
f"{base_url}/indices/economic/${query.symbol.replace('$', '')}/historical_data/level"
f"?{query_str}&api_key={api_key}"
)
async def callback(response: ClientResponse, session: ClientSession) -> list:
"""Return the response."""
init_response: Any = await response.json()
all_data: list = []
init_data = init_response.get("historical_data", [])
if init_data and isinstance(init_data, list):
all_data.extend(init_data)
if query.all_pages:
next_page = init_response.get("next_page", None)
while next_page:
if query.limit and query.limit > 100:
await asyncio.sleep(query.sleep or 1.0)
url = response.url.update_query(next_page=next_page).human_repr()
response_data = await session.get_json(url)
all_data.extend(response_data.get("historical_data", [])) # type: ignore
next_page = response_data.get("next_page", None) # type: ignore
return all_data
return await amake_requests([url], callback, **kwargs)
@staticmethod
def transform_data(
query: IntrinioFredSeriesQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioFredSeriesData]:
"""Return the transformed data."""
return [IntrinioFredSeriesData.model_validate(d) for d in data]

View File

@@ -1,140 +0,0 @@
"""Intrinio Historical Attributes Model."""
# pylint: disable = unused-argument
import warnings
from datetime import datetime
from typing import Any
from dateutil.relativedelta import relativedelta
from openbb_core.app.model.abstract.warning import OpenBBWarning
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.historical_attributes import (
HistoricalAttributesData,
HistoricalAttributesQueryParams,
)
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_requests,
get_querystring,
)
class IntrinioHistoricalAttributesQueryParams(HistoricalAttributesQueryParams):
"""Intrinio Historical Attributes Query.
Source: https://docs.intrinio.com/documentation/web_api/get_historical_data_v2
"""
__alias_dict__ = {"sort": "sort_order", "limit": "page_size", "tag_type": "type"}
__json_schema_extra__ = {
"tag": {"multiple_items_allowed": True},
"symbol": {"multiple_items_allowed": True},
}
class IntrinioHistoricalAttributesData(HistoricalAttributesData):
"""Intrinio Historical Attributes Data."""
class IntrinioHistoricalAttributesFetcher(
Fetcher[
IntrinioHistoricalAttributesQueryParams,
list[IntrinioHistoricalAttributesData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioHistoricalAttributesQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = now - relativedelta(years=5)
if params.get("end_date") is None:
transformed_params["end_date"] = now
return IntrinioHistoricalAttributesQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioHistoricalAttributesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com"
query_str = get_querystring(query.model_dump(by_alias=True), ["symbol", "tag"])
def generate_url(symbol: str, tag: str) -> str:
"""Return the url for the given symbol and tag."""
url_params = f"{symbol}/{tag}?{query_str}&api_key={api_key}"
url = f"{base_url}/historical_data/{url_params}"
return url
async def callback(
response: ClientResponse, session: ClientSession
) -> list[dict]:
"""Return the response."""
init_response = await response.json()
if message := init_response.get( # type: ignore
"error"
) or init_response.get( # type: ignore
"message"
):
warnings.warn(message=str(message), category=OpenBBWarning)
return []
symbol = response.url.parts[-2] # type: ignore
tag = response.url.parts[-1] # type: ignore
all_data: list = init_response.get("historical_data", []) # type: ignore
all_data = [{**item, "symbol": symbol, "tag": tag} for item in all_data]
next_page = init_response.get("next_page", None) # type: ignore
while next_page:
url = response.url.update_query(next_page=next_page).human_repr() # type: ignore
response_data = await session.get_json(url)
if message := response_data.get("error") or response_data.get("message"): # type: ignore
warnings.warn(message=message, category=OpenBBWarning)
return []
symbol = response.url.parts[-2] # type: ignore
tag = response_data.url.parts[-1] # type: ignore
response_data = response_data.get("historical_data", []) # type: ignore
response_data = [
{**item, "symbol": symbol, "tag": tag} for item in response_data
]
all_data.extend(response_data)
next_page = response_data.get("next_page", None) # type: ignore
return all_data
urls = [
generate_url(symbol, tag)
for symbol in query.symbol.split(",")
for tag in query.tag.split(",")
]
return await amake_requests(urls, callback, **kwargs)
@staticmethod
def transform_data(
query: IntrinioHistoricalAttributesQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioHistoricalAttributesData]:
"""Return the transformed data."""
return [IntrinioHistoricalAttributesData.model_validate(d) for d in data]

View File

@@ -1,107 +0,0 @@
"""Intrinio Historical Dividends Model."""
# pylint: disable=unused-argument
from datetime import datetime
from typing import Any
from dateutil.relativedelta import relativedelta
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.historical_dividends import (
HistoricalDividendsData,
HistoricalDividendsQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_many
from pydantic import Field
class IntrinioHistoricalDividendsQueryParams(HistoricalDividendsQueryParams):
"""Intrinio Historical Dividends Query.
Source: https://docs.intrinio.com/documentation/web_api/get_security_stock_price_adjustments_v2
"""
__alias_dict__ = {"limit": "page_size"}
limit: int | None = Field(
default=100,
description=QUERY_DESCRIPTIONS.get("limit", ""),
)
class IntrinioHistoricalDividendsData(HistoricalDividendsData):
"""Intrinio Historical Dividends Data."""
__alias_dict__ = {
"ex_dividend_date": "date",
"amount": "dividend",
"currency": "dividend_currency",
}
factor: float | None = Field(
default=None,
description=(
"factor by which to multiply stock prices before this date, "
"in order to calculate historically-adjusted stock prices."
),
)
currency: str | None = Field(
default=None,
description="The currency in which the dividend is paid.",
)
split_ratio: float | None = Field(
default=None,
description="The ratio of the stock split, if a stock split occurred.",
)
class IntrinioHistoricalDividendsFetcher(
Fetcher[
IntrinioHistoricalDividendsQueryParams,
list[IntrinioHistoricalDividendsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioHistoricalDividendsQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = now - relativedelta(year=1)
if params.get("end_date") is None:
transformed_params["end_date"] = now
return IntrinioHistoricalDividendsQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioHistoricalDividendsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/securities"
query_str = get_querystring(query.model_dump(), ["symbol"])
url = f"{base_url}/{query.symbol}/prices/adjustments?{query_str}&api_key={api_key}"
return await get_data_many(url, "stock_price_adjustments", **kwargs)
@staticmethod
def transform_data(
query: IntrinioHistoricalDividendsQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioHistoricalDividendsData]:
"""Return the transformed data."""
transformed_data: list[dict] = [
{"symbol": query.symbol, **item} for item in data
]
return [
IntrinioHistoricalDividendsData.model_validate(d) for d in transformed_data
]

View File

@@ -1,150 +0,0 @@
"""Intrinio Historical Market Cap Model."""
# pylint: disable=unused-argument
from datetime import datetime
from typing import Any, Literal
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.historical_market_cap import (
HistoricalMarketCapData,
HistoricalMarketCapQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from pydantic import Field
class IntrinioHistoricalMarketCapQueryParams(HistoricalMarketCapQueryParams):
"""Intrinio Historical MarketCap Query.
Source: https://docs.intrinio.com/documentation/web_api/get_historical_data_v2
"""
__json_schema_extra__ = {
"symbol": {"multiple_items_allowed": True},
"interval": {
"multiple_items_allowed": False,
"choices": ["day", "week", "month", "quarter", "year"],
},
}
interval: Literal["day", "week", "month", "quarter", "year"] = Field(
default="day",
)
class IntrinioHistoricalMarketCapData(HistoricalMarketCapData):
"""Intrinio Historical MarketCap Data."""
__alias_dict__ = {
"market_cap": "value",
}
class IntrinioHistoricalMarketCapFetcher(
Fetcher[
IntrinioHistoricalMarketCapQueryParams,
list[IntrinioHistoricalMarketCapData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioHistoricalMarketCapQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = datetime(
2007,
1,
1,
).date()
if params.get("end_date") is None:
transformed_params["end_date"] = now
return IntrinioHistoricalMarketCapQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioHistoricalMarketCapQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
import asyncio # noqa
from openbb_core.provider.utils.helpers import amake_request
from openbb_intrinio.utils.helpers import response_callback
from warnings import warn
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/historical_data/"
frequency = f"frequency={query.interval}ly&" if query.interval != "day" else ""
start_date = query.start_date
end_date = query.end_date
results: list = []
messages: list = []
symbols = query.symbol.split(",")
async def get_one(symbol):
"""Get data for one symbol."""
url_params = (
f"{symbol}/marketcap?{frequency}start_date={start_date}"
f"&end_date={end_date}&page_size=10000"
f"&api_key={api_key}"
)
url = f"{base_url}{url_params}"
try:
response = await amake_request(url, response_callback=response_callback)
except OpenBBError as e:
if "Cannot look up this item/identifier combination" in str(e):
msg = f"Symbol not found: {symbol}"
messages.append(msg)
return
raise e from e
if not isinstance(response, dict):
raise OpenBBError(
f"Unexpected response format, expected a dictionary, got {response.__class__.__name__}"
)
if not response:
msg = f"No data found for symbol: {symbol}"
messages.append(msg)
if response.get("historical_data"):
data = response.get("historical_data", {})
result = [
{"symbol": symbol, **item} for item in data if item.get("value")
]
results.extend(result)
return
await asyncio.gather(*[get_one(symbol) for symbol in symbols])
if messages and not results:
raise OpenBBError(messages)
if messages and results:
for message in messages:
warn(message)
if not results:
raise EmptyDataError("The response was returned empty.")
return results
@staticmethod
def transform_data(
query: IntrinioHistoricalMarketCapQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioHistoricalMarketCapData]:
"""Return the transformed data."""
return [
IntrinioHistoricalMarketCapData.model_validate(d)
for d in sorted(data, key=lambda x: x["date"])
]

View File

@@ -1,502 +0,0 @@
"""Intrinio Income Statement Model."""
# pylint: disable=unused-argument
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.income_statement import (
IncomeStatementData,
IncomeStatementQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_requests,
)
from openbb_intrinio.utils.helpers import get_data_one
from pydantic import Field, field_validator
class IntrinioIncomeStatementQueryParams(IncomeStatementQueryParams):
"""Intrinio Income Statement Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_fundamentals_v2
Source: https://docs.intrinio.com/documentation/web_api/get_fundamental_standardized_financials_v2
"""
__json_schema_extra__ = {
"period": {
"choices": ["annual", "quarter", "ttm", "ytd"],
}
}
period: Literal["annual", "quarter", "ttm", "ytd"] = Field(
default="annual",
description=QUERY_DESCRIPTIONS.get("period", ""),
)
fiscal_year: int | None = Field(
default=None,
description="The specific fiscal year. Reports do not go beyond 2008.",
)
@field_validator("symbol", mode="after", check_fields=False)
@classmethod
def handle_symbol(cls, v) -> str:
"""Handle symbols with a dash and replace it with a dot for Intrinio."""
return v.replace("-", ".")
class IntrinioIncomeStatementData(IncomeStatementData):
"""Intrinio Income Statement Data."""
__alias_dict__ = {
"amortization_expense": "amortizationexpense",
"amortizationof_deferred_policy_acquisition_costs": "amortizationofdeferredpolicyacquisitioncosts",
"basic_and_diluted_earnings_per_share": "basicdilutedeps",
"basic_earnings_per_share": "basiceps",
"capitalized_lease_obligations_interest_expense": "capitalizedleaseobligationinterestexpense",
"cash_dividends_to_common_per_share": "cashdividendspershare",
"current_and_future_benefits": "currentandfuturebenefits",
"depletion_expense": "depletionexpense",
"deposits_interest_expense": "depositsinterestexpense",
"deposits_and_money_market_investments_interest_income": "depositsinterestincome",
"depreciation_expense": "depreciationexpense",
"diluted_earnings_per_share": "dilutedeps",
"exploration_expense": "explorationexpense",
"extraordinary_income": "extraordinaryincome",
"federal_funds_purchased_and_securities_sold_interest_expense": "fedfundsandrepointerestexpense",
"federal_funds_sold_and_securities_borrowed_interest_income": "fedfundsandrepointerestincome",
"impairment_charge": "impairmentexpense",
"income_tax_expense": "incometaxexpense",
"pre_tax_income_margin": "pretaxincomemargin",
"investment_banking_income": "investmentbankingincome",
"investment_securities_interest_income": "investmentsecuritiesinterestincome",
"loans_and_leases_interest_income": "loansandleaseinterestincome",
"long_term_debt_interest_expense": "longtermdebtinterestexpense",
"marketing_expense": "marketingexpense",
"consolidated_net_income": "netincome",
"net_income_continuing_operations": "netincomecontinuing",
"net_income_discontinued_operations": "netincomediscontinued",
"net_income_attributable_to_common_shareholders": "netincometocommon",
"net_income_attributable_to_noncontrolling_interest": "netincometononcontrollinginterest",
"net_interest_income": "netinterestincome",
"net_occupancy_and_equipment_expense": "netoccupancyequipmentexpense",
"net_realized_and_unrealized_capital_gains_on_investments": "netrealizedcapitalgains",
"non_operating_income": "nonoperatingincome",
"operating_revenue": "operatingrevenue",
"operating_cost_of_revenue": "operatingcostofrevenue",
"other_adjustments_to_consolidated_net_income": "otheradjustmentstoconsolidatednetincome",
"other_adjustments_to_net_income_attributable_to_common_shareholders": "otheradjustmentstonetincometocommon",
"other_adjustment_to_net_income_attributable_to_common_shareholders": "otheradjustmentstonetincometocommon",
"other_cost_of_revenue": "othercostofrevenue",
"other_gains": "othergains",
"other_income": "otherincome",
"other_interest_expense": "otherinterestexpense",
"other_interest_income": "otherinterestincome",
"other_non_interest_income": "othernoninterestincome",
"other_operating_expenses": "otheroperatingexpenses",
"other_revenue": "otherrevenue",
"other_service_charges": "otherservicechargeincome",
"other_special_charges": "otherspecialcharges",
"insurance_policy_acquisition_costs": "policyacquisitioncosts",
"preferred_stock_dividends_declared": "preferreddividends",
"premiums_earned": "premiumsearned",
"property_and_liability_insurance_claims": "propertyliabilityinsuranceclaims",
"provision_for_credit_losses": "provisionforcreditlosses",
"research_and_development_expense": "rdexpense",
"restructuring_charge": "restructuringcharge",
"salaries_and_employee_benefits": "salariesandemployeebenefitsexpense",
"service_charges_on_deposit_accounts": "servicechargesondepositsincome",
"selling_general_and_admin_expense": "sgaexpense",
"short_term_borrowings_interest_expense": "shorttermborrowinginterestexpense",
"cost_of_revenue": "totalcostofrevenue",
"gross_profit": "totalgrossprofit",
"gross_profit_margin": "grossmargin",
"total_interest_expense": "totalinterestexpense",
"interest_and_investment_income": "totalinterestincome",
"total_non_interest_expense": "totalnoninterestexpense",
"total_non_interest_income": "totalnoninterestincome",
"total_operating_expenses": "totaloperatingexpenses",
"total_operating_income": "totaloperatingincome",
"total_other_income": "totalotherincome",
"total_pre_tax_income": "totalpretaxincome",
"revenue": "totalrevenue",
"trading_account_interest_income": "tradingaccountinterestincome",
"trust_fees_by_commissions": "trustfeeincome",
"ebit": "ebit",
"ebitda": "ebitda",
"ebitda_margin": "ebitdamargin",
"weighted_average_basic_and_diluted_shares_outstanding": "weightedavebasicdilutedsharesos",
"weighted_average_basic_shares_outstanding": "weightedavebasicsharesos",
"weighted_average_diluted_shares_outstanding": "weightedavedilutedsharesos",
}
reported_currency: str | None = Field(
description="The currency in which the balance sheet is reported.",
default=None,
)
revenue: float | None = Field(default=None, description="Total revenue")
operating_revenue: float | None = Field(
default=None, description="Total operating revenue"
)
cost_of_revenue: float | None = Field(
default=None, description="Total cost of revenue"
)
operating_cost_of_revenue: float | None = Field(
default=None, description="Total operating cost of revenue"
)
gross_profit: float | None = Field(default=None, description="Total gross profit")
gross_profit_margin: float | None = Field(
default=None,
description="Gross margin ratio.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
provision_for_credit_losses: float | None = Field(
default=None,
description="Provision for credit losses",
)
research_and_development_expense: float | None = Field(
default=None, description="Research and development expense"
)
selling_general_and_admin_expense: float | None = Field(
default=None, description="Selling, general, and admin expense"
)
salaries_and_employee_benefits: float | None = Field(
default=None, description="Salaries and employee benefits"
)
marketing_expense: float | None = Field(
default=None, description="Marketing expense"
)
net_occupancy_and_equipment_expense: float | None = Field(
default=None, description="Net occupancy and equipment expense"
)
other_operating_expenses: float | None = Field(
default=None, description="Other operating expenses"
)
depreciation_expense: float | None = Field(
default=None, description="Depreciation expense"
)
amortization_expense: float | None = Field(
default=None, description="Amortization expense"
)
amortization_of_deferred_policy_acquisition_costs: float | None = Field(
default=None, description="Amortization of deferred policy acquisition costs"
)
exploration_expense: float | None = Field(
default=None, description="Exploration expense"
)
depletion_expense: float | None = Field(
default=None, description="Depletion expense"
)
total_operating_expenses: float | None = Field(
default=None, description="Total operating expenses"
)
total_operating_income: float | None = Field(
default=None, description="Total operating income"
)
deposits_and_money_market_investments_interest_income: float | None = Field(
default=None,
description="Deposits and money market investments interest income",
)
federal_funds_sold_and_securities_borrowed_interest_income: float | None = Field(
default=None,
description="Federal funds sold and securities borrowed interest income",
)
investment_securities_interest_income: float | None = Field(
default=None, description="Investment securities interest income"
)
loans_and_leases_interest_income: float | None = Field(
default=None, description="Loans and leases interest income"
)
trading_account_interest_income: float | None = Field(
default=None, description="Trading account interest income"
)
other_interest_income: float | None = Field(
default=None, description="Other interest income"
)
total_non_interest_income: float | None = Field(
default=None, description="Total non-interest income"
)
interest_and_investment_income: float | None = Field(
default=None, description="Interest and investment income"
)
short_term_borrowings_interest_expense: float | None = Field(
default=None, description="Short-term borrowings interest expense"
)
long_term_debt_interest_expense: float | None = Field(
default=None, description="Long-term debt interest expense"
)
capitalized_lease_obligations_interest_expense: float | None = Field(
default=None, description="Capitalized lease obligations interest expense"
)
deposits_interest_expense: float | None = Field(
default=None, description="Deposits interest expense"
)
federal_funds_purchased_and_securities_sold_interest_expense: float | None = Field(
default=None,
description="Federal funds purchased and securities sold interest expense",
)
other_interest_expense: float | None = Field(
default=None, description="Other interest expense"
)
total_interest_expense: float | None = Field(
default=None, description="Total interest expense"
)
net_interest_income: float | None = Field(
default=None, description="Net interest income"
)
other_non_interest_income: float | None = Field(
default=None, description="Other non-interest income"
)
investment_banking_income: float | None = Field(
default=None, description="Investment banking income"
)
trust_fees_by_commissions: float | None = Field(
default=None, description="Trust fees by commissions"
)
premiums_earned: float | None = Field(default=None, description="Premiums earned")
insurance_policy_acquisition_costs: float | None = Field(
default=None, description="Insurance policy acquisition costs"
)
current_and_future_benefits: float | None = Field(
default=None, description="Current and future benefits"
)
property_and_liability_insurance_claims: float | None = Field(
default=None, description="Property and liability insurance claims"
)
total_non_interest_expense: float | None = Field(
default=None, description="Total non-interest expense"
)
net_realized_and_unrealized_capital_gains_on_investments: float | None = Field(
default=None,
description="Net realized and unrealized capital gains on investments",
)
other_gains: float | None = Field(default=None, description="Other gains")
non_operating_income: float | None = Field(
default=None, description="Non-operating income"
)
other_income: float | None = Field(default=None, description="Other income")
other_revenue: float | None = Field(default=None, description="Other revenue")
extraordinary_income: float | None = Field(
default=None, description="Extraordinary income"
)
total_other_income: float | None = Field(
default=None, description="Total other income"
)
ebitda: float | None = Field(
default=None,
description="Earnings Before Interest, Taxes, Depreciation and Amortization.",
)
ebitda_margin: float | None = Field(
default=None,
description="Margin on Earnings Before Interest, Taxes, Depreciation and Amortization.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
total_pre_tax_income: float | None = Field(
default=None, description="Total pre-tax income"
)
ebit: float | None = Field(
default=None, description="Earnings Before Interest and Taxes."
)
pre_tax_income_margin: float | None = Field(
default=None,
description="Pre-Tax Income Margin.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
income_tax_expense: float | None = Field(
default=None, description="Income tax expense"
)
impairment_charge: float | None = Field(
default=None, description="Impairment charge"
)
restructuring_charge: float | None = Field(
default=None, description="Restructuring charge"
)
service_charges_on_deposit_accounts: float | None = Field(
default=None, description="Service charges on deposit accounts"
)
other_service_charges: float | None = Field(
default=None, description="Other service charges"
)
other_special_charges: float | None = Field(
default=None, description="Other special charges"
)
other_cost_of_revenue: float | None = Field(
default=None, description="Other cost of revenue"
)
net_income_continuing_operations: float | None = Field(
default=None, description="Net income (continuing operations)"
)
net_income_discontinued_operations: float | None = Field(
default=None, description="Net income (discontinued operations)"
)
consolidated_net_income: float | None = Field(
default=None, description="Consolidated net income"
)
other_adjustments_to_consolidated_net_income: float | None = Field(
default=None, description="Other adjustments to consolidated net income"
)
other_adjustment_to_net_income_attributable_to_common_shareholders: float | None = (
Field(
default=None,
description="Other adjustment to net income attributable to common shareholders",
)
)
net_income_attributable_to_noncontrolling_interest: float | None = Field(
default=None, description="Net income attributable to noncontrolling interest"
)
net_income_attributable_to_common_shareholders: float | None = Field(
default=None, description="Net income attributable to common shareholders"
)
basic_earnings_per_share: float | None = Field(
default=None, description="Basic earnings per share"
)
diluted_earnings_per_share: float | None = Field(
default=None, description="Diluted earnings per share"
)
basic_and_diluted_earnings_per_share: float | None = Field(
default=None, description="Basic and diluted earnings per share"
)
cash_dividends_to_common_per_share: float | None = Field(
default=None, description="Cash dividends to common per share"
)
preferred_stock_dividends_declared: float | None = Field(
default=None, description="Preferred stock dividends declared"
)
weighted_average_basic_shares_outstanding: float | None = Field(
default=None, description="Weighted average basic shares outstanding"
)
weighted_average_diluted_shares_outstanding: float | None = Field(
default=None, description="Weighted average diluted shares outstanding"
)
weighted_average_basic_and_diluted_shares_outstanding: float | None = Field(
default=None,
description="Weighted average basic and diluted shares outstanding",
)
class IntrinioIncomeStatementFetcher(
Fetcher[
IntrinioIncomeStatementQueryParams,
list[IntrinioIncomeStatementData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioIncomeStatementQueryParams:
"""Transform the query params."""
return IntrinioIncomeStatementQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioIncomeStatementQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
statement_code = "income_statement"
if query.period in ["quarter", "annual"]:
period_type = "FY" if query.period == "annual" else "QTR"
elif query.period in ["ttm", "ytd"]:
period_type = query.period.upper()
else:
raise OpenBBError(f"Period '{query.period}' not supported.")
data_tags = [
"ebit",
"ebitda",
"ebitdamargin",
"pretaxincomemargin",
"grossmargin",
]
fundamentals_data: dict = {}
base_url = "https://api-v2.intrinio.com"
fundamentals_url = (
f"{base_url}/companies/{query.symbol}"
f"/fundamentals?statement_code={statement_code}&type={period_type}"
)
if query.fiscal_year is not None:
if query.fiscal_year < 2008:
warn("Financials data is only available from 2008 and later.")
query.fiscal_year = 2008
fundamentals_url = fundamentals_url + f"&fiscal_year={query.fiscal_year}"
fundamentals_url = fundamentals_url + f"&api_key={api_key}"
fundamentals_data = (await get_data_one(fundamentals_url, **kwargs)).get(
"fundamentals", []
)
fiscal_periods = [
f"{item['fiscal_year']}-{item['fiscal_period']}"
for item in fundamentals_data
]
fiscal_periods = fiscal_periods[: query.limit]
async def callback(response: ClientResponse, session: ClientSession) -> dict:
"""Return the response."""
intrinio_id = response.url.parts[-2].replace(statement_code, "calculations")
statement_data = await response.json()
calculations_url = f"{base_url}/fundamentals/{intrinio_id}/standardized_financials?api_key={api_key}"
calculations_data = await session.get_json(calculations_url)
calculations_data = [
item
for item in calculations_data.get("standardized_financials", []) # type: ignore
if item["data_tag"]["tag"] in data_tags
]
return {
"period_ending": statement_data["fundamental"]["end_date"], # type: ignore
"fiscal_period": statement_data["fundamental"]["fiscal_period"], # type: ignore
"fiscal_year": statement_data["fundamental"]["fiscal_year"], # type: ignore
"financials": statement_data["standardized_financials"] + calculations_data, # type: ignore
}
intrinio_id = f"{query.symbol}-{statement_code}"
urls = [
f"{base_url}/fundamentals/{intrinio_id}-{period}/standardized_financials?api_key={api_key}"
for period in fiscal_periods
]
return await amake_requests(urls, callback, **kwargs)
@staticmethod
def transform_data(
query: IntrinioIncomeStatementQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioIncomeStatementData]:
"""Return the transformed data."""
transformed_data: list[IntrinioIncomeStatementData] = []
units = []
for item in data:
sub_dict: dict[str, Any] = {}
for sub_item in item["financials"]:
unit = sub_item["data_tag"].get("unit", "")
if unit and len(unit) == 3:
units.append(unit)
field_name = sub_item["data_tag"]["tag"]
sub_dict[field_name] = (
float(sub_item["value"])
if sub_item["value"] and sub_item["value"] != 0
else None
)
sub_dict["period_ending"] = item["period_ending"]
sub_dict["fiscal_year"] = item["fiscal_year"]
sub_dict["fiscal_period"] = item["fiscal_period"]
sub_dict["reported_currency"] = list(set(units))[0]
transformed_data.append(IntrinioIncomeStatementData(**sub_dict))
return transformed_data

View File

@@ -1,101 +0,0 @@
"""Intrinio Index Historical Model."""
from datetime import datetime
from typing import Any
from dateutil.relativedelta import relativedelta
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.index_historical import (
IndexHistoricalData,
IndexHistoricalQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import amake_requests, get_querystring
from pydantic import Field
class IntrinioIndexHistoricalQueryParams(IndexHistoricalQueryParams):
"""Intrinio Index Historical Query.
Source:
https://docs.intrinio.com/documentation/web_api/get_stock_market_index_historical_data_v2
"""
__alias_dict__ = {"limit": "page_size", "sort": "sort_order"}
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
limit: int | None = Field(
default=10000,
description=QUERY_DESCRIPTIONS.get("limit", ""),
)
class IntrinioIndexHistoricalData(IndexHistoricalData):
"""Intrinio Index Historical Data."""
__alias_dict__ = {"close": "value"}
class IntrinioIndexHistoricalFetcher(
Fetcher[
IntrinioIndexHistoricalQueryParams,
list[IntrinioIndexHistoricalData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioIndexHistoricalQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = now - relativedelta(years=1)
if params.get("end_date") is None:
transformed_params["end_date"] = now
return IntrinioIndexHistoricalQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioIndexHistoricalQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
results = []
api_key = credentials.get("intrinio_api_key") if credentials else ""
symbols = query.symbol.replace("$", "").replace("^", "").split(",")
base_url = "https://api-v2.intrinio.com/indices/stock_market"
query_str = get_querystring(query.model_dump(by_alias=True), ["symbol"])
urls = [
f"{base_url}/${symbol}/historical_data/level?{query_str}&api_key={api_key}"
for symbol in symbols
]
async def callback(response, _) -> list[dict]:
"""Response callback."""
_response = await response.json()
data = _response.get("historical_data")
symbol = _response["index"].get("symbol").replace("$", "")
data = [d for d in data if d.get("value") is not None]
data = [{"symbol": symbol, **d} for d in data] if len(symbols) > 1 else data
return results.extend(data) if len(data) > 0 else results # type: ignore
await amake_requests(urls, callback, **kwargs)
if len(results) == 0:
raise EmptyDataError()
return results
@staticmethod
def transform_data(
query: IntrinioIndexHistoricalQueryParams, # pylint: disable=unused-argument
data: list[dict],
**kwargs: Any,
) -> list[IntrinioIndexHistoricalData]:
"""Return the transformed data."""
return [IntrinioIndexHistoricalData.model_validate(d) for d in data]

View File

@@ -1,181 +0,0 @@
"""Intrinio Insider Trading Model."""
# pylint: disable=unused-argument
from datetime import (
date as dateType,
datetime,
)
from typing import Any, Literal
from dateutil.relativedelta import relativedelta
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.insider_trading import (
InsiderTradingData,
InsiderTradingQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_many
from pydantic import Field, model_validator
class IntrinioInsiderTradingQueryParams(InsiderTradingQueryParams):
"""Intrinio Insider Trading Query.
Source: https://docs.intrinio.com/documentation/web_api/insider_transaction_filings_by_company_v2
"""
__alias_dict__ = {"limit": "page_size"}
start_date: dateType | None = Field(
description=QUERY_DESCRIPTIONS.get("start_date", "")
)
end_date: dateType | None = Field(
description=QUERY_DESCRIPTIONS.get("end_date", "")
)
ownership_type: Literal["D", "I"] | None = Field(
default=None,
description="Type of ownership.",
)
sort_by: Literal["filing_date", "updated_on"] | None = Field(
default="updated_on",
description="Field to sort by.",
)
class IntrinioInsiderTradingData(InsiderTradingData):
"""Intrinio Insider Trading Data."""
__alias_dict__ = {
"owner_title": "officer_title",
"transaction_type": "transaction_type_code",
"acquisition_or_disposition": "acquisition_disposition_code",
"security_type": "security_title",
"securities_owned": "total_shares_owned",
"securities_transacted": "amount_of_shares",
}
company_name: str = Field(description="Name of the company.")
conversion_exercise_price: float | None = Field(
default=None,
description="Conversion/Exercise price of the shares.",
)
deemed_execution_date: dateType | None = Field(
default=None,
description="Deemed execution date of the trade.",
)
exercise_date: dateType | None = Field(
default=None,
description="Exercise date of the trade.",
)
expiration_date: dateType | None = Field(
default=None,
description="Expiration date of the derivative.",
)
underlying_security_title: str | None = Field(
default=None,
description="Name of the underlying non-derivative security related to this derivative transaction.",
)
underlying_shares: int | float | None = Field(
default=None,
description="Number of underlying shares related to this derivative transaction.",
)
nature_of_ownership: str | None = Field(
default=None,
description="Nature of ownership of the insider trading.",
)
director: bool | None = Field(
default=None, description="Whether the owner is a director."
)
officer: bool | None = Field(
default=None, description="Whether the owner is an officer."
)
ten_percent_owner: bool | None = Field(
default=None, description="Whether the owner is a 10% owner."
)
other_relation: bool | None = Field(
default=None, description="Whether the owner is having another relation."
)
derivative_transaction: bool | None = Field(
default=None,
description="Whether the owner is having a derivative transaction.",
)
report_line_number: int | None = Field(
default=None, description="Report line number of the insider trading."
)
filing_url: str | None = Field(default=None, description="URL of the filing.")
@model_validator(mode="before")
@classmethod
def empty_strings(cls, values): # pylint: disable=no-self-argument
"""Check for empty strings and replace with None."""
return (
{k: None if v == "" else v for k, v in values.items()}
if isinstance(values, dict)
else values
)
class IntrinioInsiderTradingFetcher(
Fetcher[
IntrinioInsiderTradingQueryParams,
list[IntrinioInsiderTradingData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioInsiderTradingQueryParams:
"""Transform the query params."""
transformed_params = params
now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = now - relativedelta(years=5)
if params.get("end_date") is None:
transformed_params["end_date"] = now
return IntrinioInsiderTradingQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioInsiderTradingQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/companies"
query.limit = query.limit or 500
query_str = get_querystring(query.model_dump(by_alias=True), ["symbol"])
url = f"{base_url}/{query.symbol}/insider_transaction_filings?{query_str}&api_key={api_key}"
return await get_data_many(url, "transaction_filings", **kwargs)
@staticmethod
def transform_data(
query: IntrinioInsiderTradingQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioInsiderTradingData]:
"""Return the transformed data."""
transformed_data: list[dict] = []
for item in data:
transformed_data.extend(
[
{
**sub_item,
"filing_date": item["filing_date"],
"filing_url": item["filing_url"],
"symbol": item["issuer_ticker"],
"company_cik": item["issuer_cik"],
"company_name": item["issuer_company"],
"owner_cik": item["owner"]["owner_cik"],
"owner_name": item["owner"]["owner_name"],
}
for sub_item in item["transactions"]
]
)
return [IntrinioInsiderTradingData.model_validate(d) for d in transformed_data]

View File

@@ -1,130 +0,0 @@
"""Intrinio Institutional Ownership Model."""
# pylint: disable=unused-argument
import asyncio
from typing import Any
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.institutional_ownership import (
InstitutionalOwnershipData,
InstitutionalOwnershipQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_many, get_data_one
from pydantic import Field
class IntrinioInstitutionalOwnershipQueryParams(InstitutionalOwnershipQueryParams):
"""Intrinio Institutional Ownership Query.
Source: https://docs.intrinio.com/documentation/web_api/get_security_insider_ownership_v2
https://docs.intrinio.com/documentation/web_api/get_owner_by_id_v2
"""
__alias_dict__ = {
"limit": "page_size",
}
limit: int | None = Field(
default=100,
description=QUERY_DESCRIPTIONS.get("limit", ""),
)
class IntrinioInstitutionalOwnershipData(InstitutionalOwnershipData):
"""Intrinio Institutional Ownership Data."""
__alias_dict__ = {
"cik": "owner_cik",
"date": "period_ended",
"name": "owner_name",
}
name: str = Field(
description="Name of the institutional owner.",
)
value: float = Field(description="Value of the institutional owner.")
amount: float = Field(description="Amount of the institutional owner.")
sole_voting_authority: float = Field(
description="Sole voting authority of the institutional owner."
)
shared_voting_authority: float = Field(
description="Shared voting authority of the institutional owner."
)
no_voting_authority: float = Field(
description="No voting authority of the institutional owner."
)
previous_amount: float = Field(
description="Previous amount of the institutional owner."
)
amount_change: float = Field(
description="Amount change of the institutional owner."
)
amount_percent_change: float = Field(
description="Amount percent change of the institutional owner."
)
class IntrinioInstitutionalOwnershipFetcher(
Fetcher[
IntrinioInstitutionalOwnershipQueryParams,
list[IntrinioInstitutionalOwnershipData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioInstitutionalOwnershipQueryParams:
"""Transform the query params."""
return IntrinioInstitutionalOwnershipQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioInstitutionalOwnershipQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
data: list[dict] = []
base_url = "https://api-v2.intrinio.com"
query_str = get_querystring(query.model_dump(by_alias=True), ["symbol"])
url = f"{base_url}/securities/{query.symbol}/institutional_ownership?{query_str}&api_key={api_key}"
async def get_owner_name(item: dict) -> dict:
cik = item["owner_cik"]
cik_url = f"{base_url}/owners/{cik}?api_key={api_key}"
cik_data = await get_data_one(cik_url, **kwargs)
owner_name = cik_data["owner_name"]
item["symbol"] = query.symbol
item["owner_name"] = owner_name
return item
results = await asyncio.gather(
*[
get_owner_name(item)
for item in await get_data_many(url, "ownership", **kwargs)
],
return_exceptions=True,
)
for item in results:
if isinstance(item, Exception):
continue
data.append(item) # type: ignore
return data
@staticmethod
def transform_data(
query: IntrinioInstitutionalOwnershipQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioInstitutionalOwnershipData]:
"""Return the transformed data."""
return [IntrinioInstitutionalOwnershipData.model_validate(d) for d in data]

View File

@@ -1,367 +0,0 @@
"""Intrinio Key Metrics Model."""
# pylint: disable=unused-argument
import asyncio
from typing import Any
from warnings import warn
from openbb_core.provider.abstract.data import ForceInt
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.key_metrics import (
KeyMetricsData,
KeyMetricsQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import (
ClientResponse,
amake_requests,
)
from pydantic import Field
class IntrinioKeyMetricsQueryParams(KeyMetricsQueryParams):
"""
Intrinio Key Metrics Query.
Source: https://data.intrinio.com/data-tags/
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
class IntrinioKeyMetricsData(KeyMetricsData):
"""Intrinio Key Metrics Data."""
__alias_dict__ = {
"market_cap": "marketcap",
"pe_ratio": "pricetoearnings",
"price_to_book": "pricetobook",
"price_to_tangible_book": "pricetotangiblebook",
"price_to_revenue": "pricetorevenue",
"long_term_debt": "ltdebtandcapleases",
"total_debt": "debt",
"total_capital": "totalcapital",
"enterprise_value": "enterprisevalue",
"eps_growth": "epsgrowth",
"ebit_growth": "ebitgrowth",
"ebitda_growth": "ebitdagrowth",
"revenue_growth": "revenuegrowth",
"net_income_growth": "netincomegrowth",
"free_cash_flow_to_firm_growth": "fcffgrowth",
"invested_capital_growth": "investedcapitalgrowth",
"quick_ratio": "quickratio",
"gross_margin": "grossmargin",
"ebit_margin": "ebitmargin",
"profit_margin": "profitmargin",
"return_on_assets": "roa",
"return_on_equity": "roe",
"return_on_invested_capital": "roic",
"free_cash_flow_to_firm": "freecashflow",
"altman_z_score": "altmanzscore",
"earnings_yield": "earningsyield",
"dividend_yield": "dividendyield",
"year_high": "52_week_high",
"year_low": "52_week_low",
"volume_avg": "average_daily_volume",
"shares_outstanding": "adjweightedavebasicsharesos",
"eps": "basiceps",
}
pe_ratio: float | None = Field(
default=None,
description="Price-to-earnings ratio (TTM).",
)
price_to_book: float | None = Field(
default=None,
description="Price to book ratio.",
)
price_to_tangible_book: float | None = Field(
default=None,
description="Price to tangible book ratio.",
)
price_to_revenue: float | None = Field(
default=None,
description="Price to revenue ratio.",
)
quick_ratio: float | None = Field(
default=None,
description="Quick ratio.",
)
gross_margin: float | None = Field(
default=None,
description="Gross margin, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
ebit_margin: float | None = Field(
default=None,
description="EBIT margin, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
profit_margin: float | None = Field(
default=None,
description="Profit margin, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
eps: float | None = Field(
default=None,
description="Basic earnings per share.",
)
eps_growth: float | None = Field(
default=None,
description="EPS growth, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
revenue_growth: float | None = Field(
default=None,
description="Revenue growth, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
ebitda_growth: float | None = Field(
default=None,
description="EBITDA growth, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
ebit_growth: float | None = Field(
default=None,
description="EBIT growth, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
net_income_growth: float | None = Field(
default=None,
description="Net income growth, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
free_cash_flow_to_firm_growth: float | None = Field(
default=None,
description="Free cash flow to firm growth, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
invested_capital_growth: float | None = Field(
default=None,
description="Invested capital growth, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
return_on_assets: float | None = Field(
default=None,
description="Return on assets, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
return_on_equity: float | None = Field(
default=None,
description="Return on equity, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
return_on_invested_capital: float | None = Field(
default=None,
description="Return on invested capital, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
ebitda: ForceInt | None = Field(
default=None,
description="Earnings before interest, taxes, depreciation, and amortization.",
)
ebit: ForceInt | None = Field(
default=None,
description="Earnings before interest and taxes.",
)
long_term_debt: ForceInt | None = Field(
default=None,
description="Long-term debt.",
)
total_debt: ForceInt | None = Field(
default=None,
description="Total debt.",
)
total_capital: ForceInt | None = Field(
default=None,
description="The sum of long-term debt and total shareholder equity.",
)
enterprise_value: ForceInt | None = Field(
default=None,
description="Enterprise value.",
)
free_cash_flow_to_firm: ForceInt | None = Field(
default=None,
description="Free cash flow to firm.",
)
altman_z_score: float | None = Field(
default=None,
description="Altman Z-score.",
)
beta: float | None = Field(
default=None,
description="Beta relative to the broad market (rolling three-year).",
)
dividend_yield: float | None = Field(
default=None,
description="Dividend yield, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
earnings_yield: float | None = Field(
default=None,
description="Earnings yield, as a normalized percent.",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
last_price: float | None = Field(
default=None,
description="Last price of the stock.",
)
year_high: float | None = Field(
default=None,
description="52 week high",
)
year_low: float | None = Field(default=None, description="52 week low")
volume_avg: ForceInt | None = Field(
default=None,
description="Average daily volume.",
)
short_interest: ForceInt | None = Field(
default=None,
description="Number of shares reported as sold short.",
)
shares_outstanding: ForceInt | None = Field(
default=None,
description="Weighted average shares outstanding (TTM).",
)
days_to_cover: float | None = Field(
default=None,
description="Days to cover short interest, based on average daily volume.",
)
class IntrinioKeyMetricsFetcher(
Fetcher[
IntrinioKeyMetricsQueryParams,
list[IntrinioKeyMetricsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioKeyMetricsQueryParams:
"""Transform the query params."""
if params.get("period") is not None and params.get("period") != "annual":
warn(
"The period parameter is not available for this Intrinio endpoint, it will be ignored."
)
return IntrinioKeyMetricsQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioKeyMetricsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
tags = [
"beta",
"average_daily_volume",
"basiceps",
"basicdilutedeps",
"marketcap",
"last_price",
"52_week_high",
"52_week_low",
"dividendyield",
"pricetoearnings",
"pricetorevenue",
"pricetobook",
"pricetotangiblebook",
"grossmargin",
"ebitmargin",
"profitmargin",
"roa",
"roe",
"roic",
"earningsyield",
"days_to_cover",
"short_interest",
"revenuegrowth",
"ebitgrowth",
"ebitdagrowth",
"epsgrowth",
"netincomegrowth",
"investedcapitalgrowth",
"debt",
"totalcapital",
"enterprisevalue",
"freecashflow",
"fcffgrowth",
"ltdebtandcapleases",
"altmanzscore",
"quickratio",
"ebit",
"ebitda",
"adjweightedavebasicsharesos",
]
results = []
urls = []
symbols = query.symbol.split(",")
async def get_one(symbol: str):
"""Get data for one symbol."""
_urls = [
f"https://api-v2.intrinio.com/companies/{symbol}/data_point/{tag}?api_key={api_key}"
for tag in tags
]
urls.extend(_urls)
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
return {response.url.parts[-1]: await response.json()}
data = {}
for result in await amake_requests(urls, callback, **kwargs):
data.update(result)
if data:
data["symbol"] = symbol
results.append(data)
tasks = [get_one(symbol) for symbol in symbols]
await asyncio.gather(*tasks)
if not results:
raise EmptyDataError()
return results
@staticmethod
def transform_data(
query: IntrinioKeyMetricsQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioKeyMetricsData]:
"""Validate and transform the data."""
# Sort the results by the order of the symbols in the query.
symbols = query.symbol.split(",")
data = sorted(
data,
key=(
lambda item: (
symbols.index(item["symbol"])
if item["symbol"] in symbols
else len(symbols)
)
),
)
results: list[IntrinioKeyMetricsData] = []
for item in data:
if item.get("marketcap") is None or isinstance(item.get("marketcap"), dict):
warn(f"Symbol Error: No data found for {item.get('symbol')}")
continue
for key, value in item.copy().items():
# A bad response in a field will return a dict here, so we remove it.
if isinstance(value, dict):
_ = item.pop(key)
results.append(IntrinioKeyMetricsData.model_validate(item))
return results

View File

@@ -1,99 +0,0 @@
"""Intrinio Latest Attributes Model."""
import warnings
from typing import Any
from openbb_core.app.model.abstract.warning import OpenBBWarning
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.latest_attributes import (
LatestAttributesData,
LatestAttributesQueryParams,
)
from openbb_core.provider.utils.helpers import (
ClientResponse,
amake_requests,
)
class IntrinioLatestAttributesQueryParams(LatestAttributesQueryParams):
"""Intrinio Latest Attributes Query.
Source: https://docs.intrinio.com/documentation/web_api/get_data_point_number_v2
https://docs.intrinio.com/documentation/web_api/get_data_point_text_v2
"""
__json_schema_extra__ = {
"tag": {"multiple_items_allowed": True},
"symbol": {"multiple_items_allowed": True},
}
class IntrinioLatestAttributesData(LatestAttributesData):
"""Intrinio Latest Attributes Data."""
class IntrinioLatestAttributesFetcher(
Fetcher[
IntrinioLatestAttributesQueryParams,
list[IntrinioLatestAttributesData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioLatestAttributesQueryParams:
"""Transform the query params."""
return IntrinioLatestAttributesQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioLatestAttributesQueryParams, # pylint: disable=unused-argument
credentials: dict[str, str] | None,
**kwargs: Any,
) -> dict:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/companies"
def generate_url(symbol: str, tag: str) -> str:
"""Return the url for the given symbol and tag."""
return f"{base_url}/{symbol}/data_point/{tag}?api_key={api_key}"
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
response_data = await response.json()
if isinstance(response_data, dict) and (
"error" in response_data or "message" in response_data
):
warnings.warn(
message=str(response_data.get("error"))
or str(response_data.get("message")),
category=OpenBBWarning,
)
return {}
if not response_data:
return {}
tag = response.url.parts[-1]
symbol = response.url.parts[-3]
return {"symbol": symbol, "tag": tag, "value": response_data}
urls = [
generate_url(symbol, tag)
for symbol in query.symbol.split(",")
for tag in query.tag.split(",")
]
return await amake_requests(urls, callback, **kwargs)
@staticmethod
def transform_data(
query: IntrinioLatestAttributesQueryParams, # pylint: disable=unused-argument
data: dict,
**kwargs: Any,
) -> list[IntrinioLatestAttributesData]:
"""Return the transformed data."""
return [IntrinioLatestAttributesData.model_validate(d) for d in data]

View File

@@ -1,263 +0,0 @@
"""Intrinio Market Snapshots Model."""
# pylint: disable=unused-argument
from datetime import (
date as dateType,
datetime,
)
from typing import Any
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.market_snapshots import (
MarketSnapshotsData,
MarketSnapshotsQueryParams,
)
from pydantic import Field
class IntrinioMarketSnapshotsQueryParams(MarketSnapshotsQueryParams):
"""Intrinio Market Snapshots Query.
Source: https://docs.intrinio.com/documentation/web_api/get_security_snapshots_v2
"""
date: dateType | datetime | str | None = Field(
default=None,
description="The date of the data. Can be a datetime or an ISO datetime string."
+ " Historical data appears to go back to mid-June 2022."
+ " Example: '2024-03-08T12:15:00+0400'",
)
class IntrinioMarketSnapshotsData(MarketSnapshotsData):
"""Intrinio Market Snapshots Data."""
__alias_dict__ = {
"last_price": "trade_price",
"last_size": "trade_size",
"last_volume": "total_trade_volume",
}
last_price: float | None = Field(
default=None,
description="The last trade price.",
)
last_size: int | None = Field(
default=None,
description="The last trade size.",
)
last_volume: int | None = Field(
default=None,
description="The last trade volume.",
)
last_trade_timestamp: datetime | None = Field(
default=None,
description="The timestamp of the last trade.",
)
bid_size: int | None = Field(
default=None,
description="The size of the last bid price. Bid price and size is not always available.",
)
bid_price: float | None = Field(
default=None,
description="The last bid price. Bid price and size is not always available.",
)
ask_price: float | None = Field(
default=None,
description="The last ask price. Ask price and size is not always available.",
)
ask_size: int | None = Field(
default=None,
description="The size of the last ask price. Ask price and size is not always available.",
)
last_bid_timestamp: datetime | None = Field(
default=None,
description="The timestamp of the last bid price. Bid price and size is not always available.",
)
last_ask_timestamp: datetime | None = Field(
default=None,
description="The timestamp of the last ask price. Ask price and size is not always available.",
)
class IntrinioMarketSnapshotsFetcher(
Fetcher[
IntrinioMarketSnapshotsQueryParams,
list[IntrinioMarketSnapshotsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioMarketSnapshotsQueryParams:
"""Transform the query params."""
# pylint: disable=import-outside-toplevel
from pytz import timezone
transformed_params = params
if "date" in transformed_params:
if isinstance(transformed_params["date"], datetime):
dt = transformed_params["date"]
dt = dt.astimezone(tz=timezone("America/New_York"))
if isinstance(transformed_params["date"], dateType):
dt = transformed_params["date"] # type: ignore
if isinstance(dt, dateType):
dt = datetime(
dt.year,
dt.month,
dt.day,
20,
0,
0,
0,
tzinfo=timezone("America/New_York"),
)
if isinstance(transformed_params["date"], str):
dt = datetime.fromisoformat(transformed_params["date"])
else:
try:
dt = datetime.fromisoformat(str(transformed_params["date"])) # type: ignore
except ValueError as exc:
raise OpenBBError(
"Invalid date format. Please use '2024-03-08T12:15-0400'."
) from exc
transformed_params["date"] = (
dt.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
.replace("+", "-")
.replace("T00:", "T20:")
if isinstance(dt, datetime)
else dt
)
return IntrinioMarketSnapshotsQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioMarketSnapshotsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
import asyncio # noqa
import gzip # noqa
from datetime import timezone as datetime_timezone # noqa
from io import BytesIO # noqa
from openbb_core.provider.utils.helpers import (
amake_request,
safe_fromtimestamp,
) # noqa
from pandas import DataFrame, notna, read_csv, to_datetime # noqa
api_key = credentials.get("intrinio_api_key") if credentials else ""
# This gets the URL to the actual file.
url = f"https://api-v2.intrinio.com/securities/snapshots?api_key={api_key}"
if query.date:
url += f"&at_datetime={query.date}"
response = await amake_request(url, **kwargs)
if isinstance(response, dict) and "error" in response:
raise OpenBBError(
f"Error: {response.get('error')}. Message: {response.get('message')}"
)
urls: list = []
# Get the URL to the CSV file.
if response.get("snapshots"): # type: ignore
for d in response["snapshots"]: # type: ignore
if d.get("files"):
for f in d["files"]:
if f.get("url"):
urls.append(f.get("url"))
if not urls:
raise OpenBBError("No snapshots found.")
results: list = []
async def response_callback(response, _):
"""Response Callback."""
return await response.read()
async def get_csv(url):
"""Return the CSV data."""
response = await amake_request(
url, response_callback=response_callback, **kwargs
)
df = DataFrame()
if isinstance(response, bytes):
file = gzip.decompress(response)
df = read_csv(BytesIO(file))
if df.empty:
raise OpenBBError("Empty CSV file.")
df.columns = df.columns.str.lower().str.replace(" ", "_")
df = (
df.dropna(how="all", axis=1)
.dropna(subset=["trade_price", "last_trade_timestamp", "symbol"])
.sort_values("last_trade_timestamp", ascending=False)
)[
[
"symbol",
"trade_price",
"trade_size",
"total_trade_volume",
"bid_size",
"bid_price",
"ask_price",
"ask_size",
"last_trade_timestamp",
"last_bid_timestamp",
"last_ask_timestamp",
]
]
for col in [
"last_trade_timestamp",
"last_bid_timestamp",
"last_ask_timestamp",
]:
df[col] = (
to_datetime(
df[col].apply(
lambda x: (
safe_fromtimestamp(x, tz=datetime_timezone.utc)
if notna(x)
else x
)
)
)
.dt.tz_convert("America/New_York")
.dt.floor("s")
)
for c in ["trade_size", "total_trade_volume"]:
df[c] = df[c].astype("int64")
# Clear out NaN and non-numeric values with None.
df = (
df.replace("Max", None)
.replace("Min", None)
.replace(0, None)
.fillna("N/A")
.replace("N/A", None)
)
if len(df) > 0:
results.extend(df.reset_index(drop=True).to_dict(orient="records"))
await asyncio.gather(*[get_csv(url) for url in urls])
return results
@staticmethod
def transform_data(
query: IntrinioMarketSnapshotsQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioMarketSnapshotsData]:
"""Return the transformed data."""
return [IntrinioMarketSnapshotsData.model_validate(d) for d in data]

View File

@@ -1,376 +0,0 @@
"""Intrinio Options Chains Model."""
# pylint: disable=unused-argument
from datetime import (
date as dateType,
datetime,
)
from typing import Any, Literal
from warnings import warn
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.options_chains import (
OptionsChainsData,
OptionsChainsQueryParams,
)
from openbb_core.provider.utils.errors import OpenBBError
from openbb_intrinio.models.equity_historical import IntrinioEquityHistoricalFetcher
from openbb_intrinio.models.index_historical import IntrinioIndexHistoricalFetcher
from pydantic import Field, field_validator, model_validator
class IntrinioOptionsChainsQueryParams(OptionsChainsQueryParams):
"""Intrinio Options Chains Query.
source: https://docs.intrinio.com/documentation/web_api/get_options_chain_eod_v2
"""
__alias_dict__ = {
"strike_gt": "strike_greater_than",
"strike_lt": "strike_less_than",
"volume_gt": "volume_greater_than",
"volume_lt": "volume_less_than",
"oi_gt": "open_interest_greater_than",
"oi_lt": "open_interest_less_than",
"option_type": "type",
}
__json_schema_extra__ = {
"moneyness": {
"multiple_items_allowed": False,
"choices": ["otm", "itm", "all"],
},
"delay": {
"multiple_items_allowed": False,
"choices": ["eod", "realtime", "delayed"],
},
"option_type": {
"multiple_items_allowed": False,
"choices": ["call", "put"],
},
"model": {
"multiple_items_allowed": False,
"choices": ["black_scholes", "bjerk"],
},
}
delay: Literal["eod", "realtime", "delayed"] = Field(
description="Whether to return delayed, realtime, or eod data.",
default="eod",
)
date: dateType | None = Field(
default=None, description="The end-of-day date for options chains data."
)
option_type: Literal["call", "put"] | None = Field(
default=None,
description="The option type, call or put, 'None' is both (default).",
)
moneyness: Literal["otm", "itm", "all"] = Field(
default="all",
description="Return only contracts that are in or out of the money, default is 'all'."
+ " Parameter is ignored when a date is supplied.",
)
strike_gt: int | None = Field(
default=None,
description="Return options with a strike price greater than the given value."
+ " Parameter is ignored when a date is supplied.",
)
strike_lt: int | None = Field(
default=None,
description="Return options with a strike price less than the given value."
+ " Parameter is ignored when a date is supplied.",
)
volume_gt: int | None = Field(
default=None,
description="Return options with a volume greater than the given value."
+ " Parameter is ignored when a date is supplied.",
)
volume_lt: int | None = Field(
default=None,
description="Return options with a volume less than the given value."
+ " Parameter is ignored when a date is supplied.",
)
oi_gt: int | None = Field(
default=None,
description="Return options with an open interest greater than the given value."
+ " Parameter is ignored when a date is supplied.",
)
oi_lt: int | None = Field(
default=None,
description="Return options with an open interest less than the given value."
+ " Parameter is ignored when a date is supplied.",
)
model: Literal["black_scholes", "bjerk"] = Field(
default="black_scholes",
description="The pricing model to use for options chains data, default is 'black_scholes'."
+ " Parameter is ignored when a date is supplied.",
)
show_extended_price: bool = Field(
default=True,
description="Whether to include OHLC type fields, default is True."
+ " Parameter is ignored when a date is supplied.",
)
include_related_symbols: bool = Field(
default=False,
description="Include related symbols that end in a 1 or 2 because of a corporate action,"
+ " default is False.",
)
@model_validator(mode="after")
@classmethod
def date_not_allowed_with_realtime(cls, values: Any) -> Any:
"""Return an error if the date is supplied when delay is realtime."""
if values.delay != "eod" and values.date:
warn("Date is ignored when accessing realtime or delayed data.")
return values
class IntrinioOptionsChainsData(OptionsChainsData):
"""Intrinio Options Chains Data."""
__doc__ = OptionsChainsData.__doc__
__alias_dict__ = {
"contract_symbol": "code",
"symbol": "ticker",
"eod_date": "date",
"option_type": "type",
"last_trade_time": "last_timestamp",
"last_trade_price": "last",
"last_trade_size": "last_size",
"ask_time": "ask_timestamp",
"bid_time": "bid_timestamp",
"open": "trade_open",
"high": "trade_high",
"low": "trade_low",
"close": "trade_close",
}
@field_validator(
"close_time",
"close_ask_time",
"close_bid_time",
"ask_time",
"bid_time",
"last_trade_time",
mode="before",
check_fields=False,
)
@classmethod
def _date_validate(cls, v):
"""Return the datetime object from the date string."""
# pylint: disable=import-outside-toplevel
from dateutil import parser
from pytz import timezone
if not v:
return None
new_v: list = []
for item in v:
if item:
dt = parser.parse(item)
dt = dt.replace(tzinfo=timezone("UTC"))
dt = dt.astimezone(timezone("America/New_York"))
new_v.append(dt.replace(microsecond=0))
else:
new_v.append(None)
return new_v
@field_validator("volume", "open_interest", mode="before", check_fields=False)
@classmethod
def _volume_oi_validate(cls, v):
"""Return the volume as an integer."""
return [0 if item is None else item for item in v]
class IntrinioOptionsChainsFetcher(
Fetcher[IntrinioOptionsChainsQueryParams, IntrinioOptionsChainsData]
):
"""Intrinio Options Chains Fetcher."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioOptionsChainsQueryParams:
"""Transform the query."""
return IntrinioOptionsChainsQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioOptionsChainsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> dict:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
from datetime import timedelta # noqa
from openbb_core.provider.utils.helpers import (
amake_requests,
get_querystring,
)
from openbb_intrinio.utils.helpers import (
get_data_many,
get_weekday,
response_callback,
)
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/options"
date = query.date if query.date is not None else datetime.now().date()
date = get_weekday(date)
if query.symbol in ["SPX", "^SPX", "^GSPC"]:
query.symbol = "SPX"
warn("For weekly SPX options, use the symbol SPXW instead of SPX.")
async def get_urls(date: str) -> list[str]:
"""Return the urls for the given date."""
date = (datetime.strptime(date, "%Y-%m-%d") - timedelta(days=1)).strftime(
"%Y-%m-%d"
)
url = (
f"{base_url}/expirations/{query.symbol}/"
f"{'eod' if query.delay == 'eod' else 'realtime'}?"
f"{'after=' + date + '&' if query.delay == 'eod' else 'source=' + query.delay + '&'}"
f"api_key={api_key}"
)
expirations = await get_data_many(url, "expirations", **kwargs)
def generate_url(expiration) -> str:
url = f"{base_url}/chain/{query.symbol}/{expiration}/"
if query.date is not None:
query_string = get_querystring(
query.model_dump(exclude_none=True),
[
"symbol",
"date",
"model",
"volume_greater_than",
"volume_less_than",
"moneyness",
"open_interest_greater_than",
"open_interest_less_than",
"show_extended_price",
],
)
url = url + f"eod?date={query.date}&{query_string}"
else:
if query.moneyness:
moneyness = (
"out_of_the_money"
if query.moneyness == "otm"
else "in_the_money" if query.moneyness == "itm" else "all"
)
query_string = get_querystring(
query.model_dump(exclude_none=True),
["symbol", "date", "moneyness"],
)
url = url + f"realtime?{query_string}&moneyness={moneyness}"
return url + f"&api_key={api_key}"
return [generate_url(expiration) for expiration in expirations]
async def callback(response, _) -> list:
"""Return the response."""
response_data = await response_callback(response, _)
return response_data.get("chain", []) # type: ignore
results = await amake_requests(
await get_urls(date.strftime("%Y-%m-%d")), callback, **kwargs
)
# If the EOD chains are not available for the given date, try the previous day
if not results and query.date is not None:
date = get_weekday(date - timedelta(days=1)).strftime("%Y-%m-%d")
urls = await get_urls(date) # type: ignore
results = await amake_requests(urls, response_callback=callback, **kwargs)
if not results:
raise OpenBBError(f"No data found for the given symbol: {query.symbol}")
output: dict = {}
underlying_price: dict = {}
# If the EOD chains are requested, get the underlying price on the given date.
if query.date is not None:
if query.symbol.endswith("W") and query.symbol.startswith("SPX"):
query.symbol = query.symbol[:-1]
temp = None
try:
temp = await IntrinioEquityHistoricalFetcher.fetch_data(
{"symbol": query.symbol, "start_date": date, "end_date": date},
credentials,
)
temp = temp[0] # type: ignore
# If the symbol is SPX, or similar, try to get the underlying price from the index.
except Exception as e:
try:
temp = await IntrinioIndexHistoricalFetcher.fetch_data(
{"symbol": query.symbol, "start_date": date, "end_date": date},
credentials,
)
temp = temp[0] # type: ignore
except Exception:
warn(f"Failed to get underlying price for {query.symbol}: {e}")
if temp:
underlying_price["symbol"] = query.symbol
underlying_price["price"] = temp.close
underlying_price["date"] = temp.date.strftime("%Y-%m-%d")
output = {"underlying": underlying_price, "data": results}
return output
@staticmethod
def transform_data(
query: IntrinioOptionsChainsQueryParams,
data: dict,
**kwargs: Any,
) -> IntrinioOptionsChainsData:
"""Return the transformed data."""
# pylint: disable=import-outside-toplevel
from numpy import nan
from pandas import DataFrame
results: list = []
chains = data.get("data", [])
underlying = data.get("underlying", {})
last_price = underlying.get("price")
if query.date is not None:
for item in chains:
new_item = {**item["option"], **item["prices"]}
new_item["dte"] = (
datetime.strptime(new_item["expiration"], "%Y-%m-%d").date()
- datetime.strptime(new_item["date"], "%Y-%m-%d").date()
).days
if last_price:
new_item["underlying_price"] = last_price
_ = new_item.pop("exercise_style", None)
new_item["underlying_symbol"] = new_item.pop("ticker")
results.append(new_item)
else:
for item in chains:
new_item = {
**item["option"],
**item["price"],
**item["stats"],
**item["extended_price"],
}
dte = (
datetime.strptime(new_item["expiration"], "%Y-%m-%d").date()
- datetime.now().date()
).days
new_item["dte"] = dte
new_item["underlying_symbol"] = new_item.pop(
"underlying_price_ticker", None
)
underlying["date"] = datetime.now().date()
new_item["underlying_price"] = new_item.pop("underlying_price", None)
_ = new_item.pop("ticker", None)
_ = new_item.pop("trade_exchange", None)
_ = new_item.pop("exercise_style", None)
results.append(new_item)
output = DataFrame(results).replace({nan: None}).dropna(how="all", axis=1)
output = output.sort_values(by=["expiration", "strike", "type"])
return IntrinioOptionsChainsData.model_validate(output.to_dict(orient="list"))

View File

@@ -1,337 +0,0 @@
"""Intrinio Options Snapshots Model."""
# pylint: disable=unused-argument
from datetime import (
date as dateType,
datetime,
)
from typing import TYPE_CHECKING, Any
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.options_snapshots import (
OptionsSnapshotsData,
OptionsSnapshotsQueryParams,
)
from pydantic import Field
if TYPE_CHECKING:
from pandas import DataFrame
class IntrinioOptionsSnapshotsQueryParams(OptionsSnapshotsQueryParams):
"""Intrinio Options Snapshots Query.
Source: https://docs.intrinio.com/documentation/web_api/get_options_snapshots_v2
"""
date: dateType | datetime | str | None = Field(
default=None,
description="The date of the data. Can be a datetime or an ISO datetime string."
+ " Data appears to go back to around 2022-06-01"
+ " Example: '2024-03-08T12:15:00+0400'",
)
only_traded: bool = Field(
default=True,
description="Only include options that have been traded during the session, default is True."
+ " Setting to false will dramatically increase the size of the response - use with caution.",
)
class IntrinioOptionsSnapshotsData(OptionsSnapshotsData):
"""Intrinio Options Snapshots Data. Warning: This is a large file."""
bid: list[float | None] = Field(
default_factory=list,
description="The last bid price at the time.",
json_schema_extra={"x-unit_measurement": "currency"},
)
bid_size: list[int | None] = Field(
default_factory=list,
description="The size of the last bid price.",
)
bid_timestamp: list[datetime | None] = Field(
default_factory=list,
description="The timestamp of the last bid price.",
)
ask: list[float | None] = Field(
default_factory=list,
description="The last ask price at the time.",
json_schema_extra={"x-unit_measurement": "currency"},
)
ask_size: list[int | None] = Field(
default_factory=list,
description="The size of the last ask price.",
)
ask_timestamp: list[datetime | None] = Field(
default_factory=list,
description="The timestamp of the last ask price.",
)
total_bid_volume: list[int | None] = Field(
default_factory=list,
description="Total volume of bids.",
)
bid_high: list[float | None] = Field(
default_factory=list,
description="The highest bid price.",
json_schema_extra={"x-unit_measurement": "currency"},
)
bid_low: list[float | None] = Field(
default_factory=list,
description="The lowest bid price.",
json_schema_extra={"x-unit_measurement": "currency"},
)
total_ask_volume: list[int | None] = Field(
default_factory=list,
description="Total volume of asks.",
)
ask_high: list[float | None] = Field(
default_factory=list,
description="The highest ask price.",
json_schema_extra={"x-unit_measurement": "currency"},
)
ask_low: list[float | None] = Field(
default_factory=list,
description="The lowest ask price.",
json_schema_extra={"x-unit_measurement": "currency"},
)
class IntrinioOptionsSnapshotsFetcher(
Fetcher[
IntrinioOptionsSnapshotsQueryParams,
list[IntrinioOptionsSnapshotsData],
]
):
"""Intrinio Options Snapshots Fetcher."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioOptionsSnapshotsQueryParams:
"""Transform the query params."""
# pylint: disable=import-outside-toplevel
from pytz import timezone
transformed_params = params.copy()
if "date" in transformed_params:
if isinstance(transformed_params["date"], datetime):
dt = transformed_params["date"]
dt = dt.astimezone(tz=timezone("America/New_York"))
if isinstance(transformed_params["date"], dateType):
dt = transformed_params["date"] # type: ignore
if isinstance(dt, dateType):
dt = datetime(
dt.year,
dt.month,
dt.day,
16,
15,
0,
0,
tzinfo=timezone("America/New_York"),
)
if isinstance(transformed_params["date"], str):
dt = datetime.fromisoformat(transformed_params["date"])
else:
try:
dt = datetime.fromisoformat(str(transformed_params["date"])) # type: ignore
except ValueError as exc:
raise OpenBBError(
"Invalid date format. Please use '2024-03-08T12:15-0400'."
) from exc
transformed_params["date"] = (
dt.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
.replace("+", "-")
.replace("T00:", "T20:")
if isinstance(dt, datetime)
else dt
)
return IntrinioOptionsSnapshotsQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioOptionsSnapshotsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> "DataFrame":
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
import gzip # noqa
from io import BytesIO # noqa
from openbb_core.provider.utils.helpers import amake_request # noqa
from pandas import DataFrame, read_csv # noqa
api_key = credentials.get("intrinio_api_key") if credentials else ""
# This gets the URL to the actual file.
url = f"https://api-v2.intrinio.com/options/snapshots?api_key={api_key}"
if query.date:
url += f"&at_datetime={query.date}"
try:
response = await amake_request(url, **kwargs)
except Exception as exc:
raise OpenBBError("Could not fetch data from Intrinio.") from exc
if isinstance(response, dict) and "error" in response:
raise OpenBBError(
f"{response.get('error')}. Message: {response.get('message')}"
)
urls = []
# Get the URL to the CSV file.
if response.get("snapshots"): # type: ignore
for d in response["snapshots"]: # type: ignore
if d.get("files"):
for f in d["files"]:
if f.get("url"):
urls.append(f.get("url"))
if not urls:
raise OpenBBError("No snapshots found.")
async def response_callback(response, _):
"""Response Callback."""
return await response.read()
async def get_csv(url) -> DataFrame:
"""Return the CSV data."""
try:
response = await amake_request(
url, response_callback=response_callback, **kwargs
)
df = DataFrame()
if isinstance(response, bytes):
file = gzip.decompress(response)
df = read_csv(BytesIO(file))
return df
except Exception as exc:
try:
df = read_csv(response)
return df
except Exception:
raise OpenBBError("Could not read file from URL.") from exc
# There should only be one URL with this bulk data.
return await get_csv(urls[0])
@staticmethod
def transform_data(
query: IntrinioOptionsSnapshotsQueryParams,
data: "DataFrame",
**kwargs: Any,
) -> list[IntrinioOptionsSnapshotsData]:
"""Return the transformed data."""
# pylint: disable=import-outside-toplevel
import numpy as np
from pandas import NaT, Series, to_datetime
from pytz import timezone
df = data
if df.empty:
raise OpenBBError("Empty CSV file")
COL_MAP = {
"CONTRACT ID": "contract_symbol",
"OPEN INTEREST": "open_interest",
"TRADE PRICE": "last_price",
"TRADE SIZE": "last_size",
"TOTAL TRADE VOLUME": "volume",
"LAST TRADE TIMESTAMP": "last_timestamp",
"TRADE HIGH PRICE": "high",
"TRADE LOW PRICE": "low",
"ASK PRICE": "ask",
"ASK SIZE": "ask_size",
"LAST ASK TIMESTAMP": "ask_timestamp",
"BID PRICE": "bid",
"BID SIZE": "bid_size",
"LAST BID TIMESTAMP": "bid_timestamp",
"TOTAL ASK VOLUME": "total_ask_volume",
"ASK HIGH PRICE": "ask_high",
"ASK LOW PRICE": "ask_low",
"TOTAL BID VOLUME": "total_bid_volume",
"BID HIGH PRICE": "bid_high",
"BID LOW PRICE": "bid_low",
}
df = df.rename(columns=COL_MAP)
to_drop_na = (
["bid_timestamp", "ask_timestamp", "last_timestamp"]
if query.only_traded is True
else ["bid_timestamp", "ask_timestamp"]
)
df = df.dropna(subset=to_drop_na + ["contract_symbol"])
for col in ["last_timestamp", "bid_timestamp", "ask_timestamp"]:
# Convert Unix timestamp to tz-aware datetime
df[col] = (
to_datetime(df[col].replace("", None).astype(float), unit="s")
.dt.tz_localize(timezone("UTC"))
.dt.tz_convert(timezone("America/New_York"))
.dt.floor("s")
)
# Extract the underlying symbol, expiration, option type, and strike.
symbols = Series(df["contract_symbol"].copy())
df["underlying_symbol"] = symbols.str.extract(r"^(?P<underlying_symbol>[^_]*)")
split_symbols = symbols.str.rsplit("_", n=1).str[-1]
df["expiration"] = to_datetime(
[symbol[:6] for symbol in split_symbols],
format="%y%m%d",
)
df["option_type"] = split_symbols.str.extract(
r"^\d*(?P<option_type>\D)"
).replace({"C": "call", "P": "put"})
df["strike"] = [
(
symbol[7:].lstrip("0")[:-3] + "." + symbol[7:].lstrip("0")[-3:]
if "." not in symbol[7:]
else symbol[7:]
)
for symbol in split_symbols
]
def calculate_dte(df):
"""Calculate the DTE."""
new_df = df[
["expiration", "last_timestamp", "bid_timestamp", "ask_timestamp"]
].copy()
conditions = [
new_df["last_timestamp"].notna(),
new_df["bid_timestamp"].notna(),
new_df["ask_timestamp"].notna(),
]
choices = [
(new_df["expiration"].dt.date - new_df["last_timestamp"].dt.date)
.apply(lambda x: x)
.dt.days,
(new_df["expiration"].dt.date - new_df["bid_timestamp"].dt.date)
.apply(lambda x: x)
.dt.days,
(new_df["expiration"].dt.date - new_df["ask_timestamp"].dt.date)
.apply(lambda x: x)
.dt.days,
]
new_df["dte"] = np.select(conditions, choices, default=None)
return new_df["dte"]
df["dte"] = calculate_dte(df)
def apply_contract_symbol(x):
"""Construct the OCC Contract Symbol."""
symbol = x.split("_")[0].replace("_", "")
exp = x.rsplit("_")[-1][:6]
cp = x.rsplit("_")[-1][6]
strike = x.rsplit("_")[-1][7:]
_strike = strike.split(".")
front = "0" * (5 - len(_strike[0]))
back = "0" * (3 - len(_strike[1]))
strike = f"{front}{_strike[0]}{_strike[1]}{back}"
return symbol + exp + cp + strike
if symbols.str.contains(r"\.").any(): # noqa # pylint: disable=W1401
df["contract_symbol"] = df["contract_symbol"].apply(apply_contract_symbol)
else:
df["contract_symbol"] = symbols.str.replace("_", "")
df = df.replace({NaT: None, np.nan: None})
df = df.sort_values(by="volume", ascending=False)
return [IntrinioOptionsSnapshotsData.model_validate(df.to_dict(orient="list"))]

View File

@@ -1,290 +0,0 @@
"""Intrinio Unusual Options Model."""
# pylint: disable = unused-argument
from datetime import (
date as dateType,
datetime,
timedelta,
)
from typing import Any, Literal
from dateutil.parser import parse
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.options_unusual import (
OptionsUnusualData,
OptionsUnusualQueryParams,
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_request,
get_querystring,
)
from pydantic import Field, field_validator, model_validator
from pytz import timezone
class IntrinioOptionsUnusualQueryParams(OptionsUnusualQueryParams):
"""Intrinio Unusual Options Query.
source: https://docs.intrinio.com/documentation/web_api/get_unusual_activity_v2
"""
__alias_dict__ = {
"min_value": "minimum_total_value",
"max_value": "maximum_total_value",
"trade_type": "activity_type",
}
start_date: dateType | None = Field(
description=QUERY_DESCRIPTIONS.get("start_date", "")
+ " If no symbol is supplied, requests are only allowed for a single date."
+ " Use the start_date for the target date."
+ " Intrinio appears to have data beginning Feb/2022,"
+ " but is unclear when it actually began.",
default=None,
)
end_date: dateType | None = Field(
description=QUERY_DESCRIPTIONS.get("end_date", "")
+ " If a symbol is not supplied, do not include an end date.",
default=None,
)
trade_type: Literal["block", "sweep", "large"] | None = Field(
description="The type of unusual activity to query for.",
default=None,
)
sentiment: Literal["bullish", "bearish", "neutral"] | None = Field(
description="The sentiment type to query for.",
default=None,
)
min_value: int | float | None = Field(
description="The inclusive minimum total value for the unusual activity.",
default=None,
)
max_value: int | float | None = Field(
description="The inclusive maximum total value for the unusual activity.",
default=None,
)
limit: int = Field(
description=QUERY_DESCRIPTIONS.get("limit", "")
+ " A typical day for all symbols will yield 50-80K records."
+ " The API will paginate at 1000 records."
+ " The high default limit (100K) is to be able to reliably capture the most days."
+ " The high absolute limit (1.25M) is to allow for outlier days."
+ " Queries at the absolute limit will take a long time, and might be unreliable."
+ " Apply filters to improve performance.",
default=100000,
lt=1250000,
)
source: Literal["delayed", "realtime"] = Field(
default="delayed",
description="The source of the data." + " Either realtime or delayed.",
)
@model_validator(mode="before")
@classmethod
def validate_params(cls, params):
"""Validate the query parameters."""
if params.get("start_date") is None:
# If the symbol is provided, there will be considerably less results.
# Broad market data needs to be confined to a single date.
params["start_date"] = (
dateType.today() - timedelta(days=10)
if params.get("symbol") is not None
else dateType.today()
)
# Ensure the start date is not on a weekend.
if params.get("start_date").weekday() > 4: # type: ignore
params["start_date"] = params.get("start_date") + timedelta(days=4 - params.get("start_date").weekday()) # type: ignore
# If the end date is not provided, set it to the start date.
if params.get("end_date") is None:
params["end_date"] = params.get("start_date")
# Ensure the start date is before the end date.
if params.get("start_date") > params.get("end_date"): # type: ignore
params["start_date"], params["end_date"] = (
params["end_date"],
params["start_date"],
)
# Ensure we are not overloading API.
if (
params.get("symbol") is None
and (params.get("end_date") - params.get("start_date")).days >= 1
):
raise OpenBBError(
"When no symbol is supplied, queries are not allowed if"
+ " the date range covers more than one trading day."
+ " Supply only the start_date for queries with no symbol."
)
# Ensure the end date is not on a weekend.
if params.get("end_date").weekday() > 4: # type: ignore
params["end_date"] = params.get("end_date") + timedelta(days=7 - params.get("end_date").weekday()) # type: ignore
# Intrinio appears to make the end date not inclusive.
# It doesn't want the start/end dates to be the same, set the end date to the next day.
if params.get("end_date") is not None or params.get("start_date") == params.get(
"end_date"
):
params["end_date"] = params.get("end_date") + timedelta(days=1) # type: ignore
return params
class IntrinioOptionsUnusualData(OptionsUnusualData):
"""Intrinio Unusual Options Data."""
__alias_dict__ = {
"contract_symbol": "contract",
"underlying_symbol": "symbol",
"trade_type": "type",
"trade_timestamp": "timestamp",
}
trade_timestamp: datetime = Field(description="The datetime of order placement.")
trade_type: Literal["block", "sweep", "large", "sweep"] = Field(
description="The type of unusual trade."
)
sentiment: Literal["bullish", "bearish", "neutral"] = Field(
description=(
"Bullish, Bearish, or Neutral Sentiment is estimated based on whether"
+ " the trade was executed at the bid, ask, or mark price."
)
)
bid_at_execution: float = Field(description="Bid price at execution.")
ask_at_execution: float = Field(description="Ask price at execution.")
average_price: float = Field(
description="The average premium paid per option contract."
)
underlying_price_at_execution: float | None = Field(
default=None,
description="Price of the underlying security at execution of trade.",
)
total_size: int = Field(
description="The total number of contracts involved in a single transaction."
)
total_value: int | float = Field(
description="The aggregated value of all option contract premiums included in the trade."
)
@field_validator("trade_timestamp", mode="before", check_fields=False)
@classmethod
def validate_timestamp(cls, v):
"""Convert the timestamp string to a datetime object."""
if v:
v = parse(v)
v = v.replace(microsecond=0)
v = v.astimezone(timezone("America/New_York"))
return v
return None
@field_validator("contract_symbol", mode="before", check_fields=False)
@classmethod
def validate_contract_symbol(cls, v):
"""Return the symbol as the OCC standard format."""
return v.replace("_", "") if v else None
@field_validator("trade_type", mode="before", check_fields=False)
@classmethod
def validate_trade_type(cls, v):
"""Validate the trade type."""
if v and "_" in v:
v = v.split("_")[-1]
return v.lower()
@field_validator("underlying_price_at_execution", mode="before", check_fields=False)
@classmethod
def replace_zero(cls, v):
"""Replace a 0 with None."""
if v:
return None if v == 0 else v
return None
class IntrinioOptionsUnusualFetcher(
Fetcher[IntrinioOptionsUnusualQueryParams, list[IntrinioOptionsUnusualData]]
):
"""Intrinio Unusual Options Fetcher."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioOptionsUnusualQueryParams:
"""Transform the query."""
return IntrinioOptionsUnusualQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioOptionsUnusualQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
data: list = []
base_url = "https://api-v2.intrinio.com/options/unusual_activity"
query_str = get_querystring(query.model_dump(), ["symbol", "limit"])
# Page size is capped at 1000 for this endpoint. They don't tell you though.
url = (
base_url
+ f"/{query.symbol}/intraday?{query_str}&page_size=1000&api_key={api_key}"
if query.symbol
else base_url + f"/intraday?{query_str}&page_size=1000&api_key={api_key}"
)
data = []
async def response_callback(response: ClientResponse, session: ClientSession):
"""Async response callback."""
results = await response.json()
if "trades" in results and len(results.get("trades")) > 0: # type: ignore
data.extend(
sorted(
results["trades"], # type: ignore
key=lambda x: x["timestamp"],
reverse=True,
)
)
records = len(data)
while (
"next_page" in results
and results.get("next_page") is not None # type: ignore
and records < query.limit
):
next_page = results["next_page"] # type: ignore
next_url = f"{url}&next_page={next_page}"
results = await amake_request(next_url, session=session, **kwargs)
if "trades" in results and len(results.get("trades")) > 0: # type: ignore
data.extend(
sorted(
results["trades"], # type: ignore
key=lambda x: x["timestamp"],
reverse=True,
)
)
records = len(data)
return data
return await amake_request(url, response_callback=response_callback, **kwargs) # type: ignore
@staticmethod
def transform_data(
query: IntrinioOptionsUnusualQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioOptionsUnusualData]:
"""Return the transformed data."""
if not data:
raise EmptyDataError()
return [
IntrinioOptionsUnusualData.model_validate(d) for d in data[: query.limit]
]

View File

@@ -1,178 +0,0 @@
"""Intrinio Price Target Consensus Model."""
# pylint: disable=unused-argument
import asyncio
from datetime import date as dateType
from typing import Any
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.price_target_consensus import (
PriceTargetConsensusData,
PriceTargetConsensusQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import (
amake_request,
get_querystring,
)
from openbb_intrinio.utils.helpers import response_callback
from pydantic import Field
class IntrinioPriceTargetConsensusQueryParams(PriceTargetConsensusQueryParams):
"""Intrinio Price Target Consensus Query.
https://docs.intrinio.com/documentation/web_api/get_zacks_sales__v2
"""
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
industry_group_number: int | None = Field(
default=None,
description="The Zacks industry group number.",
)
class IntrinioPriceTargetConsensusData(PriceTargetConsensusData):
"""Intrinio Price Target Consensus Data."""
__alias_dict__ = {
"symbol": "ticker",
"name": "company_name",
"target_high": "high",
"target_low": "low",
"target_consensus": "mean",
"target_median": "median",
}
standard_deviation: float | None = Field(
default=None,
description="The standard deviation of target price estimates.",
)
total_analysts: int | None = Field(
default=None,
description="The total number of target price estimates in consensus.",
)
raised: int | None = Field(
default=None,
description="The number of analysts that have raised their target price estimates.",
)
lowered: int | None = Field(
default=None,
description="The number of analysts that have lowered their target price estimates.",
)
most_recent_date: dateType | None = Field(
default=None,
description="The date of the most recent estimate.",
)
industry_group_number: int | None = Field(
default=None,
description="The Zacks industry group number.",
)
class IntrinioPriceTargetConsensusFetcher(
Fetcher[
IntrinioPriceTargetConsensusQueryParams, list[IntrinioPriceTargetConsensusData]
]
):
"""Intrinio Price Target Consensus Fetcher."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioPriceTargetConsensusQueryParams:
"""Transform the query params."""
return IntrinioPriceTargetConsensusQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioPriceTargetConsensusQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
BASE_URL = (
"https://api-v2.intrinio.com/zacks/target_price_consensuses?page_size=10000"
)
symbols = query.symbol.split(",") if query.symbol else None
query_str = get_querystring(query.model_dump(by_alias=True), ["symbol"])
results: list[dict] = []
async def get_one(symbol):
"""Get the data for one symbol."""
url = f"{BASE_URL}&identifier={symbol}&{query_str}&api_key={api_key}"
new_data: list[dict] = []
data = await amake_request(
url, response_callback=response_callback, **kwargs
)
if (
not data
or not isinstance(data, dict)
or not data.get("target_price_consensuses")
):
warn(f"Symbol Error: No data found for {symbol}")
if isinstance(data, dict) and data.get("target_price_consensuses"):
new_data = data.get("target_price_consensuses") # type: ignore
if new_data:
results.extend(new_data)
if symbols:
await asyncio.gather(*[get_one(symbol) for symbol in symbols])
return results
async def fetch_callback(response, session):
"""Use callback for pagination."""
data = await response.json()
messages = data.get("messages")
if messages:
raise OpenBBError(str(messages))
_data = data.get("target_price_consensuses")
if _data and len(_data) > 0:
results.extend(_data) # type: ignore
while data.get("next_page"): # type: ignore
next_page = data["next_page"] # type: ignore
next_url = f"{url}&next_page={next_page}"
data = await amake_request(next_url, session=session, **kwargs)
if "" in data and len(data.get("target_price_consensuses")) > 0: # type: ignore
results.extend(data.get("target_price_consensuses")) # type: ignore
return results
url = f"{BASE_URL}&{query_str}&api_key={api_key}"
results = await amake_request(url, response_callback=fetch_callback, **kwargs) # type: ignore
if not results:
raise EmptyDataError("The request was successful but was returned empty.")
return results
@staticmethod
def transform_data(
query: IntrinioPriceTargetConsensusQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioPriceTargetConsensusData]:
"""Transform the raw data into the standard format."""
symbols = query.symbol.split(",") if query.symbol else []
results: list[IntrinioPriceTargetConsensusData] = []
for item in sorted( # type: ignore
sorted( # type: ignore
data,
key=lambda item: item.get("most_recent_date"), # type: ignore
reverse=True,
),
key=lambda item: (
symbols.index(item.get("symbol")) if item.get("symbol") in symbols else len(symbols) # type: ignore
),
):
_ = item.pop("company")
results.append(IntrinioPriceTargetConsensusData.model_validate(item))
return results

View File

@@ -1,147 +0,0 @@
"""Intrinio Reported Financials Model."""
# pylint: disable=unused-argument
from typing import Any, Literal
from warnings import warn
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.reported_financials import (
ReportedFinancialsData,
ReportedFinancialsQueryParams,
)
from pydantic import Field
STATEMENT_DICT = {
"balance": "balance_sheet_statement",
"income": "income_statement",
"cash": "cash_flow_statement",
}
class IntrinioReportedFinancialsQueryParams(ReportedFinancialsQueryParams):
"""Intrinio Reported Financials Query.
Source: https://docs.intrinio.com/documentation/web_api/get_company_fundamentals_v2
Source: https://docs.intrinio.com/documentation/web_api/get_fundamental_reported_financials_v2
"""
statement_type: Literal["balance", "income", "cash"] = Field(
default="income",
description="Cash flow statements are reported as YTD, Q4 is the same as FY.",
)
period: Literal["annual", "quarter"] = Field(default="annual")
fiscal_year: int | None = Field(
default=None,
description="The specific fiscal year. Reports do not go beyond 2008.",
)
class IntrinioReportedFinancialsData(ReportedFinancialsData):
"""
Intrinio Reported Financials Data.
The fields for this model are generated dynamically from the XBRL tags in the Intrinio response.
"""
class IntrinioReportedFinancialsFetcher(
Fetcher[
IntrinioReportedFinancialsQueryParams,
list[IntrinioReportedFinancialsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(
params: dict[str, Any],
) -> IntrinioReportedFinancialsQueryParams:
"""Transform the query params."""
return IntrinioReportedFinancialsQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioReportedFinancialsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
from openbb_core.provider.utils.helpers import (
ClientResponse,
amake_requests,
)
from openbb_intrinio.utils.helpers import get_data_one
from pandas import DataFrame
period_type = ""
api_key = credentials.get("intrinio_api_key") if credentials else ""
statement_code = STATEMENT_DICT[query.statement_type]
period_type = "FY" if query.period == "annual" else "Q"
ids = []
ids_url = f"https://api-v2.intrinio.com/companies/{query.symbol}/fundamentals?reported_only=true&statement_code={statement_code}"
if query.fiscal_year is not None:
if query.fiscal_year < 2008:
warn("Financials data is only available from 2008 and later.")
query.fiscal_year = 2008
ids_url = ids_url + f"&fiscal_year={query.fiscal_year}"
ids_url = ids_url + f"&page_size=10000&api_key={api_key}"
fundamentals_ids = await get_data_one(ids_url, **kwargs)
filings = DataFrame(fundamentals_ids["fundamentals"])
_period = "" if query.period is None else period_type
_statement = "" if statement_code is None else statement_code
if len(filings) > 0:
filings = filings[filings["statement_code"].str.contains(_statement)]
if query.period == "annual":
filings = filings[filings["fiscal_period"].str.contains(_period)]
ids = filings.iloc[: query.limit]["id"].to_list()
if ids == []:
raise OpenBBError("No reports found.")
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
statement_data = await response.json()
return {
"period_ending": statement_data["fundamental"]["end_date"], # type: ignore
"fiscal_year": statement_data["fundamental"]["fiscal_year"], # type: ignore
"fiscal_period": statement_data["fundamental"]["fiscal_period"], # type: ignore
"financials": statement_data["reported_financials"], # type: ignore
}
urls = [
f"https://api-v2.intrinio.com/fundamentals/{id}/reported_financials?api_key={api_key}"
for id in ids
]
return await amake_requests(urls, callback, **kwargs)
@staticmethod
def transform_data(
query: IntrinioReportedFinancialsQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioReportedFinancialsData]:
"""Return the transformed data."""
# pylint: disable=import-outside-toplevel
from openbb_core.provider.utils.helpers import to_snake_case
transformed_data: list[IntrinioReportedFinancialsData] = []
data_tag = "xbrl_tag"
for item in data:
sub_dict: dict[str, Any] = {}
for sub_item in item["financials"]:
field_name = to_snake_case(sub_item[data_tag]["tag"])
if sub_item["value"] and sub_item["value"] != 0:
sub_dict[field_name] = float(sub_item["value"])
sub_dict["period_ending"] = item["period_ending"]
sub_dict["fiscal_year"] = item["fiscal_year"]
sub_dict["fiscal_period"] = item["fiscal_period"]
transformed_data.append(IntrinioReportedFinancialsData(**sub_dict))
return transformed_data

View File

@@ -1,75 +0,0 @@
"""Intrinio Search Attributes Model."""
# pylint: disable=unused-argument
from typing import Any
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.search_attributes import (
SearchAttributesData,
SearchAttributesQueryParams,
)
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_one
class IntrinioSearchAttributesQueryParams(SearchAttributesQueryParams):
"""Intrinio Search Attributes Query.
Source: https://docs.intrinio.com/documentation/web_api/search_data_tags_v2
"""
__alias_dict__ = {"limit": "page_size"}
class IntrinioSearchAttributesData(SearchAttributesData):
"""Intrinio Search Attributes Data."""
__alias_dict__ = {
"parent_name": "parent",
"transaction": "balance",
}
class IntrinioSearchAttributesFetcher(
Fetcher[
IntrinioSearchAttributesQueryParams,
list[IntrinioSearchAttributesData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioSearchAttributesQueryParams:
"""Transform the query params."""
return IntrinioSearchAttributesQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioSearchAttributesQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com"
query_str = get_querystring(query.model_dump(by_alias=True), [])
url = f"{base_url}/data_tags/search?{query_str}&api_key={api_key}"
data = await get_data_one(url, **kwargs)
# Intrinio doesn't return the correct number of results when using the limit parameter
# Temporary fix until they fix it
data = data.get("tags", [])[: query.limit]
return data
@staticmethod
def transform_data(
query: IntrinioSearchAttributesQueryParams,
data: list[dict],
**kwargs: Any,
) -> list[IntrinioSearchAttributesData]:
"""Return the transformed data."""
return [IntrinioSearchAttributesData.model_validate(item) for item in data]

View File

@@ -1,95 +0,0 @@
"""Intrinio Share Statistics Model."""
# pylint: disable=unused-argument
from datetime import datetime
from typing import Any
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.share_statistics import (
ShareStatisticsData,
ShareStatisticsQueryParams,
)
from openbb_core.provider.utils.helpers import (
ClientResponse,
amake_requests,
)
from pydantic import Field
class IntrinioShareStatisticsQueryParams(ShareStatisticsQueryParams):
"""Intrinio Share Statistics Query.
Source: https://data.intrinio.com/data-tag/adjweightedavebasicdilutedsharesos
https://data.intrinio.com/data-tag/weightedavebasicdilutedsharesos
https://data.intrinio.com/data-tag/public_float
"""
class IntrinioShareStatisticsData(ShareStatisticsData):
"""Intrinio Share Statistics Data."""
__alias_dict__ = {
"outstanding_shares": "weightedavebasicdilutedsharesos",
"adjusted_outstanding_shares": "adjweightedavebasicdilutedsharesos",
}
adjusted_outstanding_shares: float | None = Field(
default=None,
description="Total number of shares of a publicly-traded company, adjusted for splits.",
)
public_float: float | None = Field(
default=None,
description="Aggregate market value of the shares of a publicly-traded company.",
)
class IntrinioShareStatisticsFetcher(
Fetcher[
IntrinioShareStatisticsQueryParams,
list[IntrinioShareStatisticsData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioShareStatisticsQueryParams:
"""Transform the query params."""
return IntrinioShareStatisticsQueryParams(**params)
@staticmethod
async def aextract_data(
query: IntrinioShareStatisticsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
data = {"symbol": query.symbol, "date": datetime.now().date()}
tags = [
"public_float",
"weightedavebasicdilutedsharesos",
"adjweightedavebasicdilutedsharesos",
]
urls = [
f"https://api-v2.intrinio.com/companies/{query.symbol}/data_point/{tag}/number?api_key={api_key}"
for tag in tags
]
async def callback(response: ClientResponse, _: Any) -> dict:
"""Return the response."""
return {response.url.parts[-2]: await response.json()}
for result in await amake_requests(urls, callback, **kwargs):
data.update(result)
return [data]
@staticmethod
def transform_data(
query: IntrinioShareStatisticsQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioShareStatisticsData]:
"""Return the transformed data."""
return [IntrinioShareStatisticsData.model_validate(d) for d in data]

View File

@@ -1,254 +0,0 @@
"""Intrinio World News Model."""
# pylint: disable=unused-argument
from datetime import datetime, timedelta
from typing import Any, Literal
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.world_news import (
WorldNewsData,
WorldNewsQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError, UnauthorizedError
from openbb_intrinio.utils.references import IntrinioCompany, IntrinioSecurity
from pydantic import Field, field_validator
class IntrinioWorldNewsQueryParams(WorldNewsQueryParams):
"""Intrinio World News Query.
Source: https://docs.intrinio.com/documentation/web_api/get_all_company_news_v2
"""
__alias_dict__ = {
"source": "specific_source",
"limit": "page_size",
}
source: (
Literal["yahoo", "moody", "moody_us_news", "moody_us_press_releases"] | None
) = Field(
default=None,
description="The source of the news article.",
)
sentiment: None | Literal["positive", "neutral", "negative"] = Field(
default=None,
description="Return news only from this source.",
)
language: str | None = Field(
default=None,
description="Filter by language. Unsupported for yahoo source.",
)
topic: str | None = Field(
default=None,
description="Filter by topic. Unsupported for yahoo source.",
)
word_count_greater_than: int | None = Field(
default=None,
description="News stories will have a word count greater than this value."
+ " Unsupported for yahoo source.",
)
word_count_less_than: int | None = Field(
default=None,
description="News stories will have a word count less than this value."
+ " Unsupported for yahoo source.",
)
is_spam: bool | None = Field(
default=None,
description="Filter whether it is marked as spam or not."
+ " Unsupported for yahoo source.",
)
business_relevance_greater_than: float | None = Field(
default=None,
ge=0,
le=1,
description="News stories will have a business relevance score more than this value."
+ " Unsupported for yahoo source. Value is a decimal between 0 and 1.",
)
business_relevance_less_than: float | None = Field(
default=None,
ge=0,
le=1,
description="News stories will have a business relevance score less than this value."
+ " Unsupported for yahoo source. Value is a decimal between 0 and 1.",
)
class IntrinioWorldNewsData(WorldNewsData):
"""Intrinio World News Data."""
__alias_dict__ = {
"date": "publication_date",
"sentiment": "article_sentiment",
"sentiment_confidence": "article_sentiment_confidence",
}
source: str | None = Field(
default=None,
description="The source of the news article.",
)
summary: str | None = Field(
default=None,
description="The summary of the news article.",
)
topics: str | None = Field(
default=None,
description="The topics related to the news article.",
)
word_count: int | None = Field(
default=None,
description="The word count of the news article.",
)
business_relevance: float | None = Field(
default=None,
description=" How strongly correlated the news article is to the business",
)
sentiment: str | None = Field(
default=None,
description="The sentiment of the news article - i.e, negative, positive.",
)
sentiment_confidence: float | None = Field(
default=None,
description="The confidence score of the sentiment rating.",
)
language: str | None = Field(
default=None,
description="The language of the news article.",
)
spam: bool | None = Field(
default=None,
description="Whether the news article is spam.",
)
copyright: str | None = Field(
default=None,
description="The copyright notice of the news article.",
)
id: str = Field(description="Article ID.")
company: IntrinioCompany | None = Field(
default=None,
description="The Intrinio Company object. Contains details company reference data.",
)
security: IntrinioSecurity | None = Field(
default=None,
description="The Intrinio Security object. Contains the security details related to the news article.",
)
@field_validator("publication_date", mode="before", check_fields=False)
@classmethod
def date_validate(cls, v):
"""Return the date as a datetime object."""
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S.000Z")
@field_validator("topics", mode="before", check_fields=False)
@classmethod
def topics_validate(cls, v):
""" "Parse the topics as a string."""
if v:
topics = [t.get("name") for t in v if t and t not in ["", " "]]
return ", ".join(topics)
return None
@field_validator("copyright", mode="before", check_fields=False)
@classmethod
def copyright_validate(cls, v):
"""Clean empty strings"""
return None if v in ["", " "] else v
class IntrinioWorldNewsFetcher(
Fetcher[
IntrinioWorldNewsQueryParams,
list[IntrinioWorldNewsData],
]
):
"""Intrinio World News Fetcher."""
@staticmethod
def transform_query(params: dict[str, Any]) -> IntrinioWorldNewsQueryParams:
"""Transform the query params."""
transformed_params = params
if not transformed_params.get("start_date"):
transformed_params["start_date"] = datetime.now().date()
if not transformed_params.get("end_date"):
transformed_params["end_date"] = (datetime.now() + timedelta(days=1)).date()
if transformed_params["start_date"] == transformed_params["end_date"]:
transformed_params["end_date"] = (
transformed_params["end_date"] + timedelta(days=1)
).date()
return IntrinioWorldNewsQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: IntrinioWorldNewsQueryParams,
credentials: dict[str, str] | None,
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
from openbb_core.provider.utils.helpers import amake_request, get_querystring
from openbb_intrinio.utils.helpers import get_data
api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/companies"
ignore = (
["symbol", "page_size", "is_spam"]
if not query.source or query.source == "yahoo"
else ["symbol", "page_size"]
)
query_str = get_querystring(query.model_dump(by_alias=True), ignore)
url = f"{base_url}/news?{query_str}&page_size={query.limit}&api_key={api_key}"
seen = set()
async def callback(response, session):
"""Response callback."""
result = await response.json()
if isinstance(result, dict) and "error" in result:
if "api key" in result.get("message", "").lower():
raise UnauthorizedError(
f"Unauthorized Intrinio request -> {result.get('message')}"
)
raise OpenBBError(f"Error in Intrinio request -> {result}")
_data = result.get("news", [])
data = []
data.extend([x for x in _data if not (x["url"] in seen or seen.add(x["url"]))]) # type: ignore
articles = len(data)
next_page = result.get("next_page")
while next_page and articles < query.limit:
url = f"{base_url}/news?{query_str}&page_size={query.limit}&api_key={api_key}&next_page={next_page}"
result = await get_data(url, session=session, **kwargs)
_data = result.get("news", [])
if _data:
# Remove duplicates based on URL
data.extend([x for x in _data if not (x["url"] in seen or seen.add(x["url"]))]) # type: ignore
articles = len(data)
next_page = result.get("next_page")
return sorted(data, key=lambda x: x["publication_date"], reverse=True)[
: query.limit
]
return await amake_request(url, response_callback=callback, **kwargs) # type: ignore
@staticmethod
def transform_data(
query: IntrinioWorldNewsQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioWorldNewsData]:
"""Return the transformed data."""
if not data:
raise EmptyDataError(
"Error: The request was returned as empty."
+ " Try adjusting the requested date ranges, if applicable."
)
results: list[IntrinioWorldNewsData] = []
for item in data:
body = item.get("body", {})
if not body:
item["text"] = item.pop("summary")
if body:
_ = item.pop("body")
item["publication_date"] = body.get("publication_date", None)
item["text"] = body.get("body", None)
results.append(IntrinioWorldNewsData.model_validate(item))
return results

View File

@@ -1 +0,0 @@
"""Intrinio utils directory."""

View File

@@ -1,153 +0,0 @@
"""Intrinio Helpers Module."""
import asyncio
import json
from datetime import (
date as dateType,
timedelta,
)
from io import StringIO
from typing import Any, TypeVar
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.utils.errors import EmptyDataError, UnauthorizedError
from openbb_core.provider.utils.helpers import (
ClientResponse,
ClientSession,
amake_request,
)
from pydantic import BaseModel
T = TypeVar("T", bound=BaseModel)
class BasicResponse:
"""Basic Response class."""
def __init__(self, response: StringIO):
"""Initialize the BasicResponse class."""
# Find a way to get the status code
self.status_code = 200
response.seek(0)
self.text = response.read()
def json(self) -> dict:
"""Return the response as a dictionary."""
return json.loads(self.text)
def request(url: str) -> BasicResponse:
"""
Request function for PyScript. Pass in Method and make sure to await.
Parameters
----------
url: str
URL to make request to
Return:
-------
response: BasicRequest
BasicRequest object with status_code and text attributes
"""
# pylint: disable=import-outside-toplevel
from pyodide.http import open_url # type: ignore
response = open_url(url)
return BasicResponse(response)
async def response_callback(
response: ClientResponse, _: ClientSession
) -> dict | list[dict]:
"""Use callback for async_request."""
data = await response.json()
if isinstance(data, dict) and "error" in data:
message = data.get("message", "")
error = data.get("error", "")
if "api key" in message.lower() or error.startswith(
"You do not have sufficient access to view this data"
):
raise UnauthorizedError(
f"Unauthorized Intrinio request -> {message} -> {error}"
)
raise OpenBBError(f"Error in Intrinio request -> {message} -> {error}")
if isinstance(data, (str, float)):
data = {"value": data}
if isinstance(data, list) and len(data) == 0:
raise EmptyDataError()
return data
async def get_data(url: str, **kwargs: Any) -> list | dict:
"""Get data from Intrinio endpoint."""
return await amake_request(url, response_callback=response_callback, **kwargs)
async def get_data_many(
url: str, sub_dict: str | None = None, **kwargs: Any
) -> list[dict]:
"""Get data from Intrinio endpoint and convert to list of schemas.
Parameters
----------
url: str
The URL to get the data from.
sub_dict: Optional[str]
The sub-dictionary to use.
Returns
-------
List[dict]
Dictionary of data.
"""
data = await get_data(url, **kwargs)
if sub_dict and isinstance(data, dict):
data = data.get(sub_dict, [])
if isinstance(data, dict):
raise ValueError("Expected list of dicts, got dict")
return data
async def get_data_one(url: str, **kwargs: Any) -> dict[str, Any]:
"""Get data from Intrinio endpoint and convert to schema."""
data = await get_data(url, **kwargs)
if isinstance(data, list):
if len(data) == 0:
raise ValueError("Expected dict, got empty list")
try:
data = {i: data[i] for i in range(len(data))} if len(data) > 1 else data[0]
except TypeError as e:
raise ValueError("Expected dict, got list of dicts") from e
return data
def get_weekday(date: dateType) -> dateType:
"""Return the weekday date."""
if date.weekday() in [5, 6]:
return date - timedelta(days=date.weekday() - 4)
return date
async def async_get_data_one(
url: str, limit: int = 1, sleep: float = 1, **kwargs: Any
) -> list | dict:
"""Get data from Intrinio endpoint and convert to schema."""
if limit > 100:
await asyncio.sleep(sleep)
try:
data = await get_data(url, **kwargs)
except Exception as e:
if "limit" not in str(e):
raise e
return await async_get_data_one(url, limit, sleep, **kwargs)
return data

View File

@@ -1,155 +0,0 @@
"""Intrinio References Helpers."""
from typing import Literal
from openbb_core.provider.abstract.data import Data
from pydantic import Field
SOURCES = Literal[
"iex",
"bats",
"bats_delayed",
"utp_delayed",
"cta_a_delayed",
"cta_b_delayed",
"intrinio_mx",
"intrinio_mx_plus",
"delayed_sip",
]
VENUES = {
"A": "NYSE MKT LLC",
"B": "NASDAQ OMX BX, Inc.",
"C": "National Stock Exchange Inc. (NSX)",
"D": "FINRA ADF",
"I": "International Securities Exchange, LLC",
"J": "Bats EDGA Exchange, INC",
"K": "Bats EDGX Exchange, Inc.",
"M": "Chicago Stock Exchange, Inc. (CHX)",
"N": "New York Stock Exchange LLC",
"P": "NYSE Arca, Inc.",
"S": "Consolidated Tape System",
"T": "NASDAQ (Tape A, B securities)",
"Q": "NASDAQ (Tape C securities)",
"V": "The Investors' Exchange, LLC (IEX)",
"W": "Chicago Broad Options Exchange, Inc. (CBOE)",
"X": "NASDAQ OMX PSX, Inc. LLC",
"Y": "Bats BYX Exchange, Inc.",
"Z": "Bats BZX Exchange, Inc.",
"u": "Other OTC Markets",
}
ETF_EXCHANGES = Literal[
"xnas",
"arcx",
"bats",
"xnys",
"bvmf",
"xshg",
"xshe",
"xhkg",
"xbom",
"xnse",
"xidx",
"tase",
"xkrx",
"xkls",
"xmex",
"xses",
"roco",
"xtai",
"xbkk",
"xist",
]
ETF_PERFORMANCE_MAP = {
"trailing_one_month_return_split_and_dividend": "one_month",
"trailing_one_month_return_split_only": "one_month",
"trailing_one_year_return_split_and_dividend": "one_year",
"trailing_one_year_return_split_only": "one_year",
"trailing_one_year_volatility_annualized": "volatility_one_year",
"trailing_three_year_annualized_return_split_and_dividend": "three_year",
"trailing_three_year_annualized_return_split_only": "three_year",
"trailing_three_year_volatility_annualized": "volatility_three_year",
"trailing_five_year_annualized_return_split_and_dividend": "five_year",
"trailing_five_year_annualized_return_split_only": "five_year",
"trailing_five_year_volatility_annualized": "volatility_five_year",
"trailing_ten_year_annualized_return_split_and_dividend": "ten_year",
"trailing_ten_year_annualized_return_split_only": "ten_year",
"inception_annualized_return_split_and_dividend": "max_annualized",
"inception_annualized_return_split_only": "max_annualized",
"calendar_year_5_return_split_and_dividend": "five_year",
"calendar_year_5_return_split_only": "five_year",
"calendar_year_4_return_split_and_dividend": "four_year",
"calendar_year_4_return_split_only": "four_year",
"calendar_year_3_return_split_and_dividend": "three_year",
"calendar_year_3_return_split_only": "three_year",
"calendar_year_2_return_split_and_dividend": "two_year",
"calendar_year_2_return_split_only": "two_year",
"calendar_year_1_return_split_and_dividend": "one_year",
"calendar_year_1_return_split_only": "one_year",
"calendar_year_to_date_return_split_and_dividend": "ytd",
"calendar_year_to_date_return_split_only": "ytd",
"net_asset_value": "nav",
"beta_vs_spy": "beta",
}
class IntrinioCompany(Data):
"""Intrinio Company Data."""
id: str = Field(description="The Intrinio ID of the Company.")
ticker: str | None = Field(
description="The stock market ticker symbol associated with the company's common stock securities",
default=None,
)
name: str | None = Field(description="The company's common name.", default=None)
lei: str | None = Field(
description="The Legal Entity Identifier (LEI) of the company.", default=None
)
cik: str | None = Field(
description="The Central Index Key (CIK) of the company.",
)
class IntrinioSecurity(Data):
"""Intrinio Security Data."""
id: str = Field(description="The Intrinio ID for Security.")
company_id: str | None = Field(
description="The Intrinio ID for the company for which the Security is issued.",
default=None,
)
name: str | None = Field(description="Name of the Security.", default=None)
code: str | None = Field(
description="""
A 2-3 digit code classifying the Security.
Reference: https://docs.intrinio.com/documentation/security_codes
""",
default=None,
)
currency: str | None = Field(
description="The currency in which the Security is traded.", default=None
)
ticker: str | None = Field(
description="The common/local ticker of the Security.", default=None
)
composite_ticker: str | None = Field(
description="The country-composite ticker of the Security.", default=None
)
figi: str | None = Field(description="The OpenFIGI identifier.", default=None)
composite_figi: str | None = Field(
description="The country-composite OpenFIGI identifier.", default=None
)
share_class_figi: str | None = Field(
description="The global-composite OpenFIGI identifier.", default=None
)
primary_listing: bool | None = Field(
description="""
If true, the Security is the primary issue for the company,
otherwise it is a secondary issue on a secondary stock exchange,
""",
default=None,
)

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +0,0 @@
[tool.poetry]
name = "openbb-intrinio"
version = "1.6.1"
description = "Intrinio extension for OpenBB"
authors = ["OpenBB Team <hello@openbb.co>"]
license = "AGPL-3.0-only"
readme = "README.md"
packages = [{ include = "openbb_intrinio" }]
[tool.poetry.dependencies]
python = ">=3.10,<4"
requests-cache = "^1.1.0"
openbb-core = "^1.6.10"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.plugins."openbb_provider_extension"]
intrinio = "openbb_intrinio:intrinio_provider"

View File

@@ -1 +0,0 @@
"""Intrinio tests."""

View File

@@ -1,321 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/fundamentals?api_key=MOCK_API_KEY&statement_code=balance_sheet_statement&type=FY
response:
body:
string: !!binary |
H4sIAGM7fWYAA6zXS3PaMBAA4L/S0Rl7diU/JN2SKaElIQWGDCGdjscBp3VjzMukQzP57125kKYO
viAfJUt+fKx2l2f2sM1n8TzJizjbMP31maUzps1sNMnhfJyzFtsUcZGYJdF0MUvo6n2cxfk0iTY/
kqSIXi/T0od0M42zaJfEa6Y5cPE6tUzW6cLc+mJC64rd0txonZSbZ38fsi6iGY2YzrdZ1mJJPtuP
mbmTA8oRUD4jS/Pvby55DvgO8BHnGjzNfRcA7mhhuokyWrQpmC7W26TFtkuzafb/1sBBPkJPe6gF
d0MV3rGX1huG1XAc470dA2+MgRsG7h1jEA7igUFqHp7MgIGLvqgw+KrdX4EdAzbGgCWDf4yBOwgO
D0sG+hbvZAZPuCCCCsNVF3vnH+0YoDEGKBmCYwxYMsjDoZCnRwNtRVlhmK8mg3HXigFVUwyoSgZ5
jAFKBlUyBDa5AUNXhqrCsMN4cNm3Y5CNMciSQR1hICFiEGAYkGsRnJ4ilRsG73PDJG9f2zGEjTGE
tZWChEyK9EcoTG7wwIqBV6MB20GvbxkNQWMMQW2lICHDIEZYpkhhUSkkMUCFoZeM+VNox+A3xuDX
pkgSMrkhGHHQHjdVzyI3hFitFEGnf9X9ZcfgNcbglQzhMQb/UClAC9SgTi+YnuvLam7wBp5aDu0Y
GusiUdRWChLa9w30e6L2LbpIOhSqytAfrETHrpnGxrpI5PWVQuwrBVA0SJu+gVJk8C4aruUi7yo7
hsa6SMT6FFl2kQJNNECo0epQCO5XGOKs3Y4DO4bGukiE2mYa8V+KFL5N+0QMGFYrhZTeE8+sGKCx
LhJUfaWAQ24gBuoi0YYBVDUaVkP8Obb7hwmNdZEg6ysFBQpSoJhDwX3t2+UGH4nhW4tNF/NlnO+Y
3ovQOLq+DTq/v5jXT6ePCX0hOzvrX9E4j+fmhmfLZZZ8+JxPXZrLkpSmPo1v+pdD6PW/3MiLzu35
SChzsKfpI12k9wRh2mDBXl7+AAAA//8DAHuz76T0EAAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:55 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-balance_sheet_statement-2022-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGM7fWYAA6yZW3OqSBDHv4rFy+7Wapa7YNU+mMvJbuJRY3ISc3a3rBEmyAYHAoMnmMp33x5v
DAKi1OZJp0fo33T3vxvyIUQUERuFtrvE9uTFJYhYLvIiofPXh2AjiiYUOULnQ3BtoSPA50l/rF9f
L4WmQNAcw9oFimaNv2NRlPXG1VvsLpCHCY1gw+qXggV2uAXOmAIUwid2RZ8iz4pD9hVFEV5ZI9iM
iQVXl5rCC7KoH8LWX8EyRR5aGQQbT10KKzFx2XXiyBY+mwLcIQarrOiqLq7+zsTPZgmJOO7dXCYp
yf3MD2nrAYfzxp9kgSM6z4BEzEzB6maMx6IoNVFUXTMqUR7HT4ObcYrS9yneBqWHUYQbI2xhCMDU
wzsgAptCfvlYFLUeiiK31WqUvvNMrjmUrmX5MRx1EQHa2GpRaDUDYkiGegTF8G7BUbCEInAvF0fN
BsE0DQKm7saWnOC8Xs951TyiLuzxILx1Ut8HdIbDxsXal0Z368zaf58Z9/08lsKsGQJJlpVKDLK8
mfY5oXpgvpRhFDqaxSiSp5r6JCmaKmqVBMMkGH3nkmgIF6fNxjD0AxzSpMnLbsD0KJdaQZCviCKO
mhWtypLUrsR4d96fnziMnk+ccpn1wFqlssQnB3pGzcKWZNE4IiiviffDXu5XR3/nUWMAwUFQ1E5h
qRS4fgKbXDPhNFWVq6X332S08JL9iuHQioqmEqgIo2YzlNqarFRXvuj0jbdc5Rc5n3OZxJ6X8ZRP
pt9P6HWa3Naqk0lL7NsbzlNuBLnE07SUd7OHvV4tFFjPRVPXcyn0mOxplzcLK8T2IZ2VJLGS4Ty5
fV1wWbNr2EOUFHbrYLd+Gka7JoauSlJ1KMwx+uFzGNtGcYlfMHyyYf6ANh2nOBt37Y093JlPolLK
K/owVdsEwaqCulsaxjQnVlu0XsanfD/P+nwaVrkIVwRLNNSjguXpzn6FH+IqdzrLVQpUN/skTTGN
6kiNlvO3LheptElmhGDbHQt1IJXiUgqjJoVpmJpZPfWOifeY7KdbYW8szb0yiFNR1fKZ5jCqakpq
dbzkpal5uR7DoZYm4XGApVh1xVxSDUmUKrkuHVnDuRmgFOZIhM0LAJpkWerWlCLCrFY9B1w5XaRx
KnHhz+fueqTcjs4XPmHpCP7waFa6ETy39vacSlm35g4ODuP2bX+cRfNJ45761msGwyc7l/YEPGvk
novrdiRdNdRqjXhzsM8/lo0wRS6B/nqFQgLHnEYh3FhwajgWQa6J0FJEvXpOFpPpU5vLK5h44nns
IQoUmw7rz4MQzzCJ3AWGxxzwFDd+a/zc86Pol3Qg8i33BKi6gtZiY1x1YN6dO8PMVf4msa62/vDd
9FB6FQHUlS5N1NvVihw6ojLP+T8Mt/PbruJLgQ6iQHEz5QYtCH0oeuK4hL0+i/bfKtXVtOMgA+fx
PD/4rGG2hP2Mm5B9qZ852INUJwqdVv465/9A74/1u+scOteZtvz3M/B75ns2DqOfCgNdglL2EKiL
pQ+BFX0q+xT4D1wmJjZijQV5OzhYm7yNnpA0ZcdJQUbYhonl2+wOm3tNohnGdLIzw9YXN7KQN0lA
H+HpSJTl3RJMWa7PLv3lmYEnAV7J6erH9vomIZ3AKeMtLCb25rvArtQSzZasru7BkoIzKaAmLVF+
kOWOaMAz2RmgfYeNbjRhAhjBIdAwxnAgAfsRf1W1JeotSX6Q1I4qdST9DEZj9lPQkQCRZHce8H31
X4blgDnvWq+YnXu3O+xxkhsE3kpYz2DNwy4s/fH0bXg7Er8OB9+ML9fj8wfFZASW+wpGFgFFFiVT
ET4/P/8DAAD//wMApZ0t//cYAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:55 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-balance_sheet_statement-2019-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGM7fWYAA6yZXXOrNhCG/wrDTdupnYIAA5npRb5O2iTHcZycxDltxyODgmmwwCBygjP57135
C2GDsZnmytbKYh9p990V+ZAThqmLY9efEXf44lNMHR8HiXz814fsYoaHDHvy8Yfsu/KxDJ+H3UHn
8nImt2SKJwTGznAylv5OFQV1pItp6r/hgFCWwIT5L2UH7PAIUjBFOIZPfMWQ4cBJY/4VJwmZWxOY
TKgDq6st+QU7LIxh6q9gGeEAzw2yS0Y+g5GU+nydNHHlz5YMT0jBqluWrivzvyPls1VBogxurs6z
nOR+HMas/UDiifQnfSMJmxRAEm5mYPULxn1RtGYohmqqWi3K4+Dp9mqQo3RDRlaHckNwQqQ+cQgc
wCggayAKk2JxeF8UvRkKQpZp1aJ0vWd6KaCcOE6YwlaXEeClrRGF0ZTCRp09KHp3bwIFDygKz/JJ
0pIoYfkhEOYvbdkBzncaJoaq1PvuDm7jay/3/ZaNSSydLXyRTlbOLPwPuXHTz30p7GYUKtIMVItB
Z1ejriBUD9yXKoxSR4sYZfLUUJ/UDrJUu5ZgNJv2I0GgerA4a0m9OIxIzDJRdSMuRy3Ji8Mkh5p/
i6JCUkC8LUYECtSMQjO1PfK5l0X974NKiFYJxUZ+bBBUHkZDWdoP4917f34SMG5C6lXXigCsdaWC
hnRH4WuoTqpiaJDkdTSvWfDDnW2meHftkXQLh4NBmbzSfC9x/QA21DBrNGTvcVD/Zv23INtMewGt
LPNrgcowGlZ0VbO0PZJf8brWdEu+ypzfcpmmQVDwVAym3w/YcM0y1Pp6YWTu9ZXgqdBHnZNRnsrr
BspdjJZWicDHIz/wGRTK4m5XVzwnJu5OrV22grsYTrPr1zchatZdRw9npS1HtB4/DMNsiKF3kFZ/
FPYA/wgFjFW1OycvBD650ERBr5HmOEt33aU9XpsPotKqM3o3lWGg+kJ+N7Os0ZZYrdBuCj5tNyVF
nw/Dqhbh3ViaaaL6mIPDCjreZobv4qp2ushVCdQ0+qCsmGq99vZnk+mJcFJ5kSwIwao6lupALsWV
FFZDChsQzPrWfUCDx2wz3EprY2XsVUEciqpX9zQ1iaUYSv21Ec1sI9iqMQJqZRDuB1iJ1VjMdaSp
9Zl17iGDbPUAlTB7IizfYrCsyNI0p5BuKag+py68E2wIKnEWTib+oqVctc5nIeXhCP6IaE4+ETx3
NuYcStk053Y2DgPzujsoooVUumeh81rACOnapQ0BLxqFy33TiqQbqln/6mjqkVC8W/YJwz6F+nqB
YwrbnJ9CvLSQ3LAvQvW1rA7BsuvjSslGT6YQV9DxpJM0wAwolhU2nEQxGROa+G8ErjngKZF+k36+
gVvlL3lDFDr+AVBNBa1tWPXH8u7dWfZW3i/D6mLljVhLdwVXmftNhctWdKv+TGJP0SZb/vfiVfe2
zvdKoJ0okNpct0EJ4hBSnno+5W8Ak80XY00VbT/IyHs83W57FjArwm7BTYi93M8t2J1UB8qcUf1G
6v9A7w46d5db6EJdWvHfj8HvcRi4JE5+Kj3oCpSqK2BHqbwC1rSyxTvgP7BMSl3MywoO1nAwNpxM
n++ervh2MhARPmHohC5/wvJZw2RMCBuuzTD1xU8cHAwzUEcoiIpqr4egx/JDvvSXZw6eRWQupvMf
u4uHxGwIu0xWsIS6y+8yX6mt2G1kzZ/BgyI3IaWtKm1kPyB0rHTgcnwEaN9hop8MufwlsAksTgls
SMR/JKyK9LbSaavoQdWPdfVYNY8s0+Y/BR2JMM3W+wHf5/8omd1y533nlfB9Pznp3QiCG0XBXFaP
YCwgPgz98fStd91XvvZuv1lfLgenD5qt89X9VzDyE9A4mSZ/fn7+BwAA//8DAK72yG+6GQAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:55 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-balance_sheet_statement-2020-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGM7fWYAA6yZa3OjNhSG/4qHL22ndgriYvBMP+S2aROv4zjZxLttxyODgmmwICCyizP57z3y
DWHA2EzzydYR4n0knfdIzrsUM0wdHDnegjiTZ49ianvYj6XeX++SgxmeMOxKvXfJc6SeBJ8ng7Fx
dbWQ2hLFcwJt5zietf5OZBkZrcvXxHvDPqEshg7LJyUb4vAKkguFOIJPfMSAYd9OIv4VxzFZRmPo
TKgNoytt6RnbLIig668QmWIfLwOSQ6Yeg5aEenycJHakj7YEb0ggqpqyYsjLvxP5o11BIo/71xdp
RnI/CyLWeSDRvPUnfSMxm+dAYh5mEPVywUNR1GYoOrJQtxblcfx0ez3OUAYBI5tF6RMck9aI2AQW
YOqTLRCFTpHYfCiK1gwFKSrSa1EG7ld6JaCc2naQwFSXEeB1rBGF3oxCMRQkH0AxvHsTKPiGovAu
j8TtFiUsWwTCvHUsPUK80Uy8JhtKrXZnfBvduJn2WzYjUet8paV1uhGz0h/w4K7OQymshkugIEOr
xaCL6+lAMKoHrqUKo1RoHqPMnhr6k6KpXUWtJRim4eibsImGMDhrt4ZREJKIpW3RdkPuR4WtFYbF
jCjjaJjRqtE16n32h/vj65OA0Q+oW22zPkTrXJYGdE/NaJrYsmya9Vb7kvrfncVudgy2ilq3sDgY
ktotTZUS6UewoYYbTkM6QrVo/6ajNz/dzRgBrSxpaoHKMBoWQ8gbTbbqC7s7MF8LmV8mviCZJr6f
Uypupt+PyAykmqZZq1RPnZtrQalwBLkg0yyVt2cPZ9VaarC+h6ee7zGoMfnZri4WdkScPdOtdo36
2T5Lb17ehF2zLdhDnJZW63DbfhxGtyGGhpBV71LWGH8PBIxNobggzwQ+OXD+gDKdZDhruc46Hm3D
R1Gp1Rm9n8owtPoKcrcwzWnBrDZo/ZymYj3Paz4Oq9qE6xbLMOtrOyyWb7i7Gb6Pq1p0nqsSqOnu
U2Rdteq9d7SYv54KK5UVyZwRbKpjqQ9kVlxJYTaksEzDqK+NgzH1H9Pd7VZaGyv3XhXEsaha9Zlm
P6quaVb9AR8tLN0v1BgBtXITHgZYidXYzHVV0euX8MJFOimcASphDkRY/wDA0jxL05xCuqlr9ZXp
0j3FuuAS58F87q2OlJuj83lA+XYEPSKanXUE5fZOn2Mpm+bc3oPDuHszGOfRAtq6Z4H9ksMI6FbS
joHng8K9uGlF0uVut35RXl0SiNeyEWHYo1BfL3FEYZqzVYjWEZIFDkVATZNEsw640Mjp9Kkr7Cs4
8STzxMcMKNYVNpiHEZkRGntvBK45oJS0fmv93A/i+JfsQBTY3hFQTQ2tA7f+Ay5pd6ZVyPv1trrc
qBFr6b7NVSa/qXEZuqrWb6vIldV5Qf8w2pzetvleCbQXBVKb+zY4QRRAylPXo/zHs3j3N6WmjnYY
ZOg+nhWPPSuYDeEgJxP2XqazALuX6kib06t/zPk/0Adj4+6qgC7UpQ3//Qx0zwLfIVH8U+lCV6BU
XQENufIKuB9s5w74DwyTUAfzsoL9LRy0TfrXyuezCz6dDEyEd5jYgcPfsH7XJJ4RwibbMHR99mIb
+5MU3BEKoozkbROcsbyAD/3pKwdPQ7I00+XDzuolEZvALJMNLKHO+rvER+rIVgcZy3fwTSGElI4i
d5D5gFBP1nrIPAG0b9DRiyfc/mKYBBYlBCYk5A+Jo2od2ego6EHReprSU+BRxeSPgo+EmKbb+YDv
y/8xLG65eM9+IXzeT0+HfcFww9Bf2uoJtPnEg6Y/nr4Mb0by5+HtF/PT1fjsQbU0Prr3AkG+AiqS
FUuVPj4+/gMAAP//AwCX2hTa9RgAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:55 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-balance_sheet_statement-2023-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGM7fWYAA6yZa3OqRhjHv4rDm7ZTTbkLzvSFuZy0iUeNyUnMaTvOChvcBhcCiyeYyXfvs94A
AVGmeaX7LMv/t/vc1nwIIUPURoFNltievBCKqEWQGwqdvz4EGzE0YcgROh8CsYWOAJ8n/bF+fb0U
mgJFcwxjFyicNf6ORFHWG1dvEVkgF1MWwoTVk4IFdngFzph8FMAnvqLHkGtFAf+KwhCvrCFMxtSC
1aWm8IIs5gUw9VewTJGLVgbBxlPCYCSihK8Thbbw2RTgDRFYZdPUNXH1dyZ+NktIxHHv5jJOSO5n
XsBaDziYN/6kCxyyeQYk5GYGVpIxHoui1ENRJM0UK1Eex0+Dm3GC0vcY3h5KD6MQN0bYwnAAUxfv
gChMCtLDx6KodVHUdrsSpe880+sUSteyvAi2uogAbWy1KLS6vqWJxhEUw7tFioI7FIV3ERw2GxSz
5BAwIxtbfIJ4vZ54XVGkSu32eBDcOon2AZvhoHGx1tLobsWs9XvcuK/zWAqzHoWk6mZ1eNPlzbSf
SlQPXEsZRqHQLEZReqqZnyRV0XS9kmAY+6PvKScawuKs2RgGno8DFjfTadfn+SjnWr6fj4gijpoR
rSptqfog3p3356cURs+jTnmadcFalWWpRw/UjJqBDYGhqWolzWvs/rCX+9HR3ylqDOBwEAS1Uxgq
BdJPYJNrOpyutrXqpPVvPFq48X7EpNCKgqYSqAijZjGUdE0R5erC7vSNt1zkF4nPSaaR62aUpp3p
9xNqnSZrhlKpVIvt25uU0lQLcomnSSjveg97PVqYYF2CpsQlDGpMdrfLi4UVYPvAdoPPVBfs8/j2
dZHyml3BHqK4sFr7u/HTMNo1MXRZl6qrnjlGP7wUxrZQXOIXDJ9s6D+gTEcJzkauvbEHO/NJVEp5
RB+mMkS9GupuaRjTXLLaovUymvL1PKv5NKzyJHwYSzMM2TzmsFzd2Y/wQ1zlorNcpUB1vU9SIWdV
597Rcv7WTZ1UUiQziWBbHQvzQJKKSymMmhSmJhvV7tYfU/cx3ne3wtpY6ntlEKeiquU9zWFU1TTU
6vOSl6bm5mpMCrXUCY8DLMWqncxVTToisi4dWcO5HqAU5kiEzQ8ALM6y1I0p4IDWs5LlyukiLZUl
Lrz5nKxbym3rfOFR7o6gJ41mJRNBubU351TKujF3sHEYt2/74yyaRxv3zLNeMxge3UnaS+BZY+pe
XLcitRVDqm7O3hzspa9lI8wQoVBfr1BAYZuTUwg2FpwYjkWQayK0ZKn6BiDG06d2yq2g4YnmkYsY
QGwKrDf3AzzDNCQLDLccEIobvzV+7nlh+EvSD3kWOYGpbj5rSRD61efy7twZZi7wN351tdWTLqaH
vKsIoG7m0uFQqi/LgSMq85z+YbBt33YBXwp0EAVimyduSAWBBzFPHUL5r2fh/o9K9ZvUYyB95/E8
3/esYbaE/YxM8L5EZw72INWJeU4r/zXn/0Dvj/W76xx6qjBt+e9noHvmuTYOwp8KD7oEpewOqIul
d8DDYHuXwH9gmYjaiNcV5O7gYGzyTMXzJ8q3k0Ea4RMmlmfzN2zeNQlnGLPJzgxTX0hoIXcSQ3qE
iiiu7tTrIWiyiMeX/vLMwWMfr7Lp6mF7/ZKATWCX8RYWU3vzXeArtUSzpYird3CnSJnUlqi1RPlB
ljuiCrfjM0D7DhNJOOEJMIRNYEGEYUN8/pCdfVRvSfKDpHZUqaPIZ22zzR+FPOIjGu/2A76v/smw
HHDxxHrFfN+73WEvlXJ9310l1jMYczGBoT+evg1vR+LX4eCb8eV6fP6gmCpfnbyCkZ+AIouSqQif
n5//AQAA//8DAPrFqvz2GAAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:55 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-balance_sheet_statement-2021-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGM7fWYAA6yZ23KrNhSGX8XDTdupnXI+eKYXzmGnTbwdx8lOnN12PDIomAYLAiI7OJN375JP
CAPGZpormyWL/5PW+pcgH0JMEXFQ5HgL7EyePYKI7SE/Frp/fQgOomhCkSt0PwTPEboCfJ4Mxvrl
5UJoCwTNMVw7Q/Gs9XciirLeunhNvDfkY0JjGLD8pWBDHG6Bc6EQRfCJzRhQ5NtJxL6iOMbLaAyD
MbFhdqktPCObBhEM/RUiU+SjZUBw8NSjcCUhHpsniR3hsy3AHRKIKqqliqu/E/GzXUEijvtX52lG
cjcLItq5x9G89Sd5wzGd50BiFqYQ9XLBQ1GUZiiyoVtWLcrD+PHmapyhDAKKN5vSxyjGrRG2MWzA
1MdbIAKDIv7yoShqQxRNls1alIH7RC45lJ5tBwksdRkBWscaUWgNKXTZOIRiePvGUbCEInAvD8ft
FsE02wRMvXUsPUK83ky8rpn1deGMb6JrN9N+Q2c4ap2ttLR6GzEr/QEL7uo8lMJqRiGpkiTVYpDF
1XTAGdU901KFUSo0j1FmTw39SVJUU9FrCYZpOPrOJdEQJqft1jAKQhzRtM3bbsj8qJBaYVisiDKO
hhWtWOoBPvvuvj89chj9gLjVNutDtM5lSUD29IyGhS1BXRtGLc1L6v9wFrvVMdgqat3A5iAoare0
VEqkH8EmN0w41TTV+i7ybzp689PdiuHQyoqmFqgMo2EzlAzdkOvrRnQH5muh8svEFySTxPdzSvlk
+v2IytDAoORapVrqXF9xSrkjyDmeZqW8PXs4q6ulBut7aOr5HoUek1/t6mZhR9jZs9yaLim1DKfp
9csblzXbhj1EaWm3DrfXj8MwGmJoqqHXY1hj9CPgMDaN4hw/Y/jkwPkD2nSS4azlOut4tA0fRaVU
V/R+KkOX6vPrdmGa04JZbdD6OU3Ffp7XfBxWtQnvx1IN1Tpos3zd3a3wfVzVovNclUBNs0+SNdWs
P62MFvPXHrdTWZPMGcGmO5b6QGbFlRRmUwrRksR65x2Mif+Q7uZbaXOsTL4qimNZ1epDTY1fKIqs
1aLKC0vzC02GQ63MwsMAK7Eau7kuq0p9Ip67soYLh4BKmAMR1m8AaJpnaVpUsmlYB9jfhdtDGmcT
Z8F87q3OlJuz81lAWDqCHh7NzgaCcntnzLGUTYtu78lhbFwPxnm0gLTuaGC/5DACspW04+D5IPdg
3LQlaYai1xfOq4sD/rlshCnyCDTYCxQRWOZsF6J1BGeBQxHkpgiaXp9WYjp9NLi0ghNPMk98RAFi
3WGDeRjhGSax94bhMQeE4tZvrZ/7QRz/kh2IAts7gqmpn0kHnH7e3VvTKlT9OqkuNmL4VrovtcrU
N7UtEG/VP2NGrqjMC/qH0ebwtq32SqC9KFDYzLXBB6IACp64HmHvzuLdV0pN/ewwyNB9OC2eelYw
G8JBTiakXqazALuX6kiT06rf5fwf6IOxfntZQOe60ob/bga6Z4Hv4Cj+qXSjK1CqngB1sfIJcD/Y
ziPgPzBNQhzEmgryt3BwbaJZF8NXkS0nBQ9hAyZ24LA7rO81iWcY08k2DEOfvdhG/iQFb4R2KC5f
DKwuwQnLC9jUX54YeBripZUuf+ysbhLRCawy3sBi4qy/C2ymjmh1ZG15D5YUXEjuSGJHNu5luStK
XUk9AbTvMNCLJ8z9YlgEGiUYFiRkP+JnVTui3pHke0ntqlJXVU5ERWc/BR8JEUm36wHfl/9iWNww
8Z79gtm693rDPue3YegvXfUErvnYg0t/PH4bXo/Er8Obb+aXy/HpvWKpbHbvBYJsBxRZlCxF+Pz8
/A8AAP//AwB4qViN9BgAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:55 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,72 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/ipos?api_key=MOCK_API_KEY&page_size=100&status=upcoming
response:
body:
string: !!binary |
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
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:00 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,315 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/fundamentals?api_key=MOCK_API_KEY&statement_code=cash_flow_statement&type=FY
response:
body:
string: !!binary |
H4sIAGQ7fWYAA7TXWU/bQBAA4L9S+TmxZi8f+xaEoE1pCCgcaVVZJjGti+MYJyQc4r931rgp+BDS
WDx6d73JfpqdGT9Z13fpPFxE6TpMVpb+8WTFc0ub0eD8arOXpFbPWq3DdWSWBLPlPMLZWbj6HVwn
y22wm8Jl1/FqFibBQxTmlubAxW4oi/J4abY9mOK69UNmNsmjbJmvo/nLD+TrYI5b4Ti+yfvg97nC
mSidvxoXZlxA8VtJnP56M8VYH/iEcw2e5q4NAN9xYbwKEly0Wlt6nd9FPesuMy+93lX2wekzPmFS
S6Yl2I7AV597ryicw9HJOKNT8PcoipebKFhB4dQoXojkx1IoG1SVYnO/HMmQTsHIFFAc2a1RsF20
fBwF82zwWY3ixk2ndAqgUjC/OLJfo4BdtNQoeJ8B6hUUeB5Jjwpp+16VYnyyPRptyBTMJ1N4u5zw
hqIk8pooWEHhFRRSc48eFa7t13KFPLkF/4pO4ZEpXHMuYDUKbxctNQooKPyCwtFcdaFgUlYoHpVk
4YhO4ZIpnOYKgkRtFQQDBikEGArGtXDoF0TYXLi1XCE9twOFQ6ZQzWmzJGqqIBgwJm2qCRMmV2BF
7BIVICoUyp9uhh0oFJlC7nLCWwrVmjbNnUIKMWFF2hT0CoIBpdzqBcmH+xvnlE4hyRSiuYKURG4T
hVPkCmfCQUu8I50uiMOrUXFxLE7Gf+gU73abrRS8pYKI1gqCAVNWENCCafA7RYXwKxSD0N38GdIp
yN0mYy1pk7dWEAyYsq/A2860olcQIWzJqhdkmURDdk+nIHebDJob75KoMW2KsoIARoXXpa9ACu5W
K8j2Qu5POZ2C3G2C31JBoLXxZkW3KZiJCnA1o18Q7DZ5rYKkyWh0dE6mAHK3CV5zBSmJGisI+582
herYYoFbpVjc5n62oFOQu01wm9NmSdRYQeBfrkAK7DZZl490BapCkWzFrUf/MgVytwlOc+P9QtSc
Ns16vDvmgnClVadvEJAmKn72rNlykYXpg6VLFXwORpfO4eOxOUY8u4nwpNZgMD7C5zRcmA0HWZZE
n76kMxvHkijGoc8XZ+Ovp/BtfHzmHRxe7k2Eb/LdLL7BSfyfIEy7LKzn578AAAD//wMAcJ/knD8S
AAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:56 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-cash_flow_statement-2019-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGU7fWYAA7SY21LjOBCGX8Xlq51awvgUx6ZqLwinZQkksAyT2UOlhK0YDY5sLBlwKN59W05w
lMGOvQ7DDYm6rfTX3dIv+UVlHFEfJT6ZY38yJRRRj6CQqXt/v6g+4mjCUaDuvajEV/dU+Dy5CL5F
J3N1R6VohmHsIKIsCgn4Yl+5wFw5pV40w8pn5ZdBxNgn8MynUCnmJDfBSIwSTLk86EUUPqWEBmBm
+CHF1IPp9R11ijweJeD7K1huUYhyg+ol2CcchlJKxEwp89XXHfURhSmYu12ja2v53672ulPB8jA/
Ou9LLCXhKwdFYMowxgniBIDfQ63FL+N5iN1Nk2i2cogW09AAwMgj4QSzNWbzpzL74yE+y1bMhzhO
MNRccClHzzGmDBd4vmTEhW07PKsSz8e31XS60bV6tXS38wcUyxWNaOcAQlT2/e8p4zOImynXkXIl
CuaREEstuyoqmOAZtHqER1Xd+//57Xb8XUuvL24c3PSNQFqcd4gGmCmEvjUvtPE+YxiyAOteGRB0
S8I8xh0FaIoUAGuCEcM+XvwntMDyUEw4CrfOQ69dHjqmYzi1ibgY25coWF/ZeR8cQ4wla1qkRQ6z
WN1NucpyUZcBp10GbNd09doMaOPBlZ9VZaApdgPYvMVIvmLWt27tZ+LdjL+e2xLeKE0gEoaVaKqM
EhE2z3aUEfwiV/5JNc2wlaOHlMRiOReg8fKhaBoLx3j5HKwMLPlubnNCHzHbUGS9WsI297muWW63
vtFBjm+kDW/fg8gZWVcptD64JZDREsg2rAY4oxs0Ly/raR5Yvh+XVJCsWbdErJbgzYiWZpv1vXs4
Bx2RNqc/EegQNN3nKFHOEU8TwrMqYAa+HwzbUpBcp9egoHT+R9+WCjrkdzhZkq1vP+sCFAm/ktAX
PlsSt5UeXevVS484gvx4qCyVnrIkbJaecrCyZNSmoKX2WF3HrT+GjLJ4OKhMQVPuBrRV2mO01J5m
eM/B87kzXuFd4RhlYjGKRXuIb1ddnLxZoqm/GN/cucsLWGXZjNZiYjlO/ekZBd/D3nwNTNp/D6LZ
TNwRQEt4JiMWe7CXe+A3hy1Z227Ctu249az3WXhvyUojlRDC8TH1JZkpqiiZtsRreQ+CUuq6W4v3
lJmXN1KPnjKWiunftShZGj6qQ7ttT322WX+mDS4uH7NyqPLuXNF9bG+2VJCeU3866Ga+O5BOBwvF
PH6LaLNilgTeRDFreVvKRcdw9Pql2M/OoufKq4qkmGVJ2KyY5WBlyahNgdsyBa7m9uo15XLu9P3K
C2tT8Aa4VZJptpWWZnxX81k4HP/Al8ciXk7kpNI1DeZeO/W+D/yNiaZhuIYhb6u/NccwLFOvX5tG
0L99kt+viLhPKccJnFSUEQLHt5BFnGRpiReGypi7VTEvPEsDNi2jfsM8Cqxzd/wu3vwN5zV6xqws
ZmHlwlgXdq9F2HrXkDb6f2GGlPpIiCsKi9BhbDK6fBpcPIoW5Yhj4TDxIh8vo5xMw+hpUpjAbUqY
h8JJhlEizn+6WwzBnZ5EYtrjb4I0i3F+bMkf9hc/kPCJeIEN4/Ck09HcjqmBBYReGnfFuOHkvxXC
GluZDB2uBmC6Now9zYLdchfw/gJHwiYhODHIA09SDDmJ8xfl0qNWR7M7unGtW3uWDleTXdfMH4Uq
xIhmRU7gu3irdTIfCgji3WOR9v390UC6/Mcx3CShvrswFmICQ79//TI6u9LOR8MvzvHJuH9tupaY
ndyDUVTBFGSm+vr6+h8AAAD//wMA7P1b5g0YAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:57 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-cash_flow_statement-2020-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGU7fWYAA7RY23LiOBD9FZefdmsh4xsGU7UPIbfNBgLJZjLMXopSbOHRxMiOJSeYVP59WwaM
mNiYMTN5CXS3xTndrT6SX1XGEfVQ7JEF9iZTQhF1CQqY2v3nVfUQRxOOfLX7qhJP7arweXLtfw4v
FmpDpWiGwXYSUhYGBGKxp1xjrlxSN5xh5YPySz9k7FeIzJZQKeYkc4ElQjGmXDa6IYVPCaE+uBl+
SjB1YXm9oU6Ry8MYYn8DzwMKUOZQ3Rh7hIMpoUSslDBPfWuozyhIwN1qW7quZX9H2lujhMvT4mzQ
k7gUwFdOcmDKMMIx4gQIvye1hV+m5yL2ZRqHs01AuFyG+kCMPBNOMNvibP5Uzt54iK/SDedTHMUY
ai54KWfzCFOGc3qe5MS57zB6Vik9Dz+UswNqLbuS3cPiCUVyRUPaPAGIyrH3NWF8BriZchcqt6Jg
Lgmw1LKbooILnkGbR3hY1r3fz9+ux99um0Yl/ci/7xm+tDm/IOpjphC6bl5o42PGMGQB9r3SJ+iB
BBnGhgJs8hQA1xgjhj28/E9oTstFEeEoODgP7Xp5aFntVmUersf2DfK3N3bWBucAsWBLi6zIKPPN
vS+tolRUJaBTLwEdzW5blRnQxv1bLy3LwL609yCbdRjJNsz25NZ+Jr378aeBLdEbJTEgYVgJp8oo
FrB52lBG8Itc+TfRNMNWzp4SEondnBONVg+F00gERqvnYGNgKXZ3lxP6jNmOIuvlCrYzDc22qTnV
fQ5ifC+Nu2MXgDOyrVFo23ggH6MmH71lVJf12h/do0VxWS8zZNk4Lqgg2fIeyLFcgSs46pZjdipZ
ni5AR6Tp9BcCHYKu+xDGygDxJCY8LWPMIPYHs60pSLqhmU71eYMu/uzZUkmH/AuOV9S2B9C2AoUi
rgD7MuZAyjW1p+nssSfFEeTbQ2Wh9hTlYLf2FPMqykVlBmqKT9MyOtUpGKXRsF+agn1578G2THyM
muKzH725Px90xht6tzhCqdiMYtOe4odNE8drTzj1lvbdjbu6gJWWzairJrre2ePYhPyvQXuxRUwa
wCfhbCbuCKAmPJUp5kPYzSLwOuBArnWncNswW9VD+DENHi1ZaqQSAhwPU0/SmbyKkutAejXvQU3d
0jrVY/clNW/upR69ZCwRy79rUbJy/KgObdVUk5ZuVBetlXpOX1LOpZicrzHtFpMC6PuISSXjuqPU
tM3qE1EvvQrnped4SU2KkrBbTYqJFSWjMgVOzRR07M7qUrsrBzeLTs8rvc3tS3wPumVyYtYdu/vx
u13MguH4G34ZFnFxz5hKdxhYe+tE+B74mhNNgmCLhjxyfv+ekaNZZrV6GH7v4UV++SCAX1KOY5Bx
ZYQgcI1ZACUrT7R0lIJulYFeRhYiNiFblXjPfGvgjN/hzV7/3aE5ZkWYhZcLZxXsdg3YTkvbTPb/
YIGEekgIDwpy5GCbPM8f2/SzaFGOOBYBEzf08ArkZBqEL5PcBWFTwlwUTFKMYnE2yk5HSxNceEko
lj0Xy/E0wpmkZw97yx+I+US83AW7oelOU3OahgMeEMGN3dAyu539VgB7THIZ0D5No31nGF1N7+rW
EdD7GwIJmwQQxCANPE4wpCTKXiJLj1pNzW7qxp1udS29a1lHTkcXj0IRIkTTPCfwXbzyuVgMBQni
PmKR9ePjUV+6GkcR3LKgvEdgCzAB0x+fPo6ubrXBaPixc34x7t2ZjiVWJ4/gFFUwBWNTfXt7+x8A
AP//AwCsDHxCKRcAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:57 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-cash_flow_statement-2021-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGU7fWYAA7SYW3OiSBSA/wrF026tZgABxap9iLltNhpNNpNx9lJWCy3TE2wI3SRiKv99T6Ni
OwFxyExeon0O7fnOtZsXlXFEPRR7ZIm9yYxQRF2CAqZ2/3lRPcTRhCNf7b6oxFO7KnyeXPufw4ul
2lApmmNYOwkpCwMCuthTrjFXLqkbzrHyQfmlHzL2K2hmW6gUc5KJYCVCMaZcXnRDCp8SQn0QM/yY
YOrC9npDnSGXhzHo/gaSKQpQJlDdGHuEw1JCidgpYZ762lCfUJCA2DHtjrb6O9JeGyUsj8uzQU9i
KTBfOckNU4YRjhEnAPwWasd+Gc9F7MssDudbhXC1DfUBjDwRTjDbYW79VGZvPMRX6Zb5FEcxhpgL
LuVsEWHKcI7nSUKcy96HZ5bieXhaTqfrRsespJsuH1EkRzSkzRMwUTn2viaMz8FuptyFyq0ImEsC
LKXsNqgggmfQ9hEelmXv9/Pb9fgNp2NV4kf+fc/wpeL8gqiPmULoJnkhjY8Zw+AFqHulT9CUBJmN
DQVochcAa4wRwx5e/Sc0x3JRRDgK3u2Hdj0/NE1H1ysdcT22b5C/W9lZHpyDjQU1Ldwim5lX96Fc
Rb6o8kCnZiVoptbqVLpAG/dvvbTMBYdyH0Cb5RjJSma3d2s/le9+/GlgS3yjJAZTGFbCmTKKhd08
bSgj+Emu/JtommErZ48JiURB56TR+qFwFgnFaP0c1AaWdPcnOqFPmO0Js14+xPZnOuT5ATV/7Y/u
0bLYD5eZaVkLK0AmO9J3QpZPrQpIzbGs6mifLqH3SgX9F4LeDWH6EMbKAPEkJjwtI2ag+4NpazZx
XbPNTqsSli7/7NlSSIf8C47XaLslu9u1Q6FXYPtK553Idft164AcFmP724NYYbsu8sH+dl3MVeSL
Sg/U7NdN3bTMah+M0mjYL/XBoeAH4Jb1a6Nmvz6Qb+EvBp3xlu8WRygV5SjK9hRPt2kcbyThzFut
70/d9bWlNHBG3Qbcbrerj5zI/xq0lztcUgc+CedzcbCGacJTmTDvwm6mgTcK70St24Y7ltOuPlY9
pMGDKc8aKYJgjoepJw2aPIiS6J14NS8PkKKm3a7Ee05bN/dSil4ylojt32QoWQt+VIJaNe8EuqlX
F56Vek5fGp2raXK+sWn/NCkw/ZBpUklct5falmVXEvfSq3BRevSVxkmRE/aPk2KwImdUusCp6QKn
1bKqzxA3y07PK70BHQp+AG7ZOGnV7bqH8d0u58Fw/A1fZou47Wak0qkf9t45Er41fMNEkyDYwZBb
zu/fde6xq9/GGH5v+ixf2IXdl5TjGKa4MkKguDFZ2EnWkmglKLXZKrN5pVncTOxOdYc8882BM35j
b/bK7A4tMCuyWUi5EFaZ3a5jtiUfMP+DHRLqITF4UJCbDmuTp0V4bSKRohxxLBQmbujhtZWTWRA+
T3IRqM0Ic1EwSTGKxdkoO0SsluCKSEKx7flnQZpGOBvp2cPe6gdiPhFvRGEdntSamtM02iCBISit
69m6lf1WADUmiVpw+Wtqxp1hdLVO12gfAd7foEjYJAAlBn7gcYLBJ1H25lV61GxqdlM37nSza+pw
aD3SHF08ClGIEE1zn8B38ZrkYjkUEMR9wMLtx8ej/ja8x1EE1yyI7xGsBZjA0h+fPo6ubrXBaPix
c34x7t21HFPsTh5AKKLQMjTdaamvr6//AwAA//8DACRf6+xeFgAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:57 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-cash_flow_statement-2022-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGU7fWYAA7SYbXOiSBDHvwrFq7s6zQIiilX3IubpctFoctmsew9ljTCys8GBMEMSTOW7Xw8q
jhsQFnfzJjrdM/5/PT3dA68q44i6KHLJErvTOaGIOgT5TO3986q6iKMpR57ae1WJq/ZU+Dy99j4H
F0u1oVK0wDB2ElAW+AR8satcY65cUidYYOWD8ssgYOxX8EyXUCnmJDXBSIgiTLk86AQUPsWEemBm
+DHG1IHl9YY6Rw4PIvD9DSwz5KPUoDoRdgmHoZgSsVLMXPWtoT4hPwazbXe1lpb+HWlvjQKWx+XZ
sC+x5MhXTjJhyijEEeIEgN9D7eiX8RzEvsyjYLF1CFbLUA/AyBPhBLMd5tZPZXYnI3yVbJlPcRhh
2HPBpZy9hJgynOG5khFntsPwzEI8F8+K6XRd18xSutnyEYXyjga0eQISlWP3a8z4AnQz5S5QbsWG
OcTHUspuNxVMMAdtp/CgKHu/n9+qya9pZjl/6N33DU86nV8Q9TBTCN1kL+TxMWMYwgAHXxkQNCN+
KrKhAE4WA4CNMGLYxav/hGZcDgoJR/7BgejUDIShaaVxuJ5YN8jbPdlpHpyDxJwzLaIiq8xOd1Ws
vFCUBaBbNwCG3tZLQ6BNBrduUhSCqtwVaNMUI+mR2a3d2k/lu598GloS3ziOQArDSjBXxpHQzZOG
Moaf5Mq/saYZlnL2GJNQHOiMNFxPCuahcAzX8+BoYMl3f54T+oTZnm3Wi5vY3jg0da2jdctT3Rvf
o2V+HC5TaWkJy0EmO9YDIYu71n7IjmUb5V3rdAmlVzrPfyEo3bBLH4JIGSIeR4QnRcAMfH8wbM0a
bnVaVjkrXf7Zt6QNHfEvOFqT7R7Y3ZIdCL8c6SufA4lrFuumoXWtSl3723tYbrXOC8L+ap0PlheM
0hDULNdNw2i1yzv3OAlHg8IYVAWvgFtUro2a5boi34v3MuxOtny3OESJOI7i2J7i2TaPo40lmLur
8f25u35qKdw4o279bXfM8vKLvK9+Z7nDJRXgk2CxEPdqaCY8kQmzIuykHnjjcCBq3SrctU3NKGV9
SPwHU2410g6CHBdTV+oz2SZKpgPxaj47NHWza5bfKJ6T1s29lKKXjMVi+XcZStaGH5Wg7XpYbdNq
l0K1E9ceSJ1z1U3ON5L2d5Mc5VW6SSlw3VJqGRXuCv3kKngpvPhK3SQvCPu7ST5YXjBKQ2DXTWW4
FZp2aRBult2+W/gAVJW8Am9RO2nVvvVWA7xdLvzR5BvAVIx42E1RpVs/LL5zJ3yvfANFY9/f4ZBr
zu/fdXu32+Ul1fD6s2f5gV0Iv6QcR9DHlTECx41mIZSsLeHKUCi6XSR65Zmr2OhWKCdnnjm0J+/0
pu/M7tALZnmahZULY5nsTg3Zut3ubIvCf7BCTF0kWg/yM+kwNrUurm/GoUhSjjgWDlMncPFa5XTu
B8/TzARuc8Ic5E8TjCJxOzKMbAieEUkglj3/LEiTEKdNPZ3srn4g4lPxShTGYabe1OymYYEF2qA0
bqTjZvpbPpwyydSCc9DUjDvD6GndntE5Ary/wZGwqQ9ODOLAoxhDTML01as01WxqVlM37nSzZ+o9
s32ktdOpsAshokkWE/gu3pNcLEcCgjgPWIT9+Hg82G7vcRjCgxbs7xGM+ZjA0B+fPo6vbrXhePSx
e34x6d+1bEHgkAcwil1oGZput9S3t7f/AQAA//8DAFGvr5tfFgAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:57 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-cash_flow_statement-2023-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGU7fWYAA7SYW3OiSBSA/wrF026tZrgIilX7EHPbbDSabCbj7KWsFlqmJ9gQukmCqfz3PY2K
7QTEwZm8RPsc2vOdazevKuOIeij2yAJ7kxmhiLoEBUzt/vOqeoijCUe+2n1Viad2Vfg8ufY/hxcL
taFSNMewdhJSFgYEdLGnXGOuXFI3nGPlg/JLP2TsV9DMtlAp5iQTwUqEYky5vOiGFD4lhPogZvgx
wdSF7fWGOkMuD2PQ/Q0kUxSgTKC6MfYIh6WEErFTwjz1raE+oSABsWM7jqVlf0faW6OE5XFxNuhJ
LAXmKye5YcowwjHiBIDfQ23ZL+O5iH2ZxeF8oxAut6E+gJEnwglmW8zmT2X2xkN8lW6YT3EUY4i5
4FLOXiJMGc7xPEmIc9lheK1SPA9Py+l03dKdSrrp4hFFckRD2jwBE5Vj72vC+BzsZspdqNyKgLkk
wFLKboIKIngGbR7hYVn2fj+/XY+/Y2t2JX7k3/cMXyrOL4j6mCmErpMX0viYMQxegLpX+gRNSZDZ
2FCAJncBsMYYMezh5X9CcywXRYSj4GA/tOv5oWlb7XalI67H9g3ytys7y4NzsLGgpoVbZDPz6t6X
q8gXVR7o1K0EzWqZlS7Qxv1bLy1zwb7ce9BmOUayktnu3dpP5bsffxrYEt8oicEUhpVwpoxiYTdP
G8oIfpIr/yaaZtjK2WNCIlHQOWm0eiicRUIxWj0HtYEl3d2JTugTZjvCrJcPsd2ZrmuOVd3yrv3R
PVoU++EyMy1rYQXIZEt6IGT51NoNaTiWXh3s0wW0Xqme/0LQuiFKH8JYGSCexISnZcAMdH8wbM0e
3rIsvVXJShd/9mwpoEP+Bccrsu2C3e7ZodArMH2pcyBx3W6tm2Z1txZT+9tzWGG3LnLC7m5dDFbk
jEoX1GzXwF99Khul0bBf6oF9sfeALWvWRs1mvRfdi/8y6Iw3dLc4QqkoRVGyp3i6yeF4LQln3nJ9
d96ubiylQTNq916rrWuVYMj/GrQXW2BS9z0J53NxqIZJwlMZMe/AbqaB1woHstZtwe22ZVWzPqTB
Q0ueM1IIwRwPU08aMnkUJdGBeDUvDhBKzajO0efUvLmXcvSSsURs/y5FyUrwozLUqodlGUanEspK
Pacvjc3lKDlfm7R7lBRYvs8oqQSu2UebcCjUK4l76VX4UnrqlUZJkRN2j5JisCJnVLrAqX0i7LQ6
1WG/WXR6XuntZ1/yPXjLpolZ/8i7F+DtYh4Mx98AZsaIq26GKh35YfOtA+F7y9dQNAmCLQ655/z+
HcXZtqsbquH3ps/yZV2YfUk5jmGIKyMEimuLhZlkJYmWglKTrTKTl5rFU7yjVZ/Bz/zWwBm/szd7
XXaHXjArsllIuRBWmd2uYbbesdubC9J/sENCPSQGDwpy02Ftcj996gVUpChHHAuFiRt6eGXlZBaE
z5NcBGozwlwUTFKMYnE0yibrcgmuhyQU255/FqRphJcjPYw59pY/EPOJeBsK6/Ck0dScpmGBBIag
tG6KdVPLfiuAGtsS6XpTM+4Mo6t1ukb7CPD+BkXCJgEoMfADjxMMPomyt67So62mZjd1405vdVt6
t6Ud2Wb2KEQhQjTNfQLfxSuSi8VQQBD3AQu3Hx+P+pvwHkcR3LEgvkewFmACS398+ji6utUGo+HH
zvnFuHdnOi2xO3kAoYiCaWi6Y6pvb2//AwAA//8DAK8OJlJaFgAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:57 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,84 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/filings?api_key=MOCK_API_KEY&end_date=2023-06-06&page_size=100&start_date=2023-01-01
response:
body:
string: !!binary |
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
sf+04OXH/wEAAP//AwAHdYEtlnIAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:05 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,183 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/news?api_key=MOCK_API_KEY&end_date=2024-01-03&page_size=50&specific_source=yahoo&start_date=2024-01-02
response:
body:
string: !!binary |
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
5X/7PwAAAP//AwB3UIfgooQAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:48 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,39 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/forex/pairs?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAFs7fWYAA5SUwU7CQBCG32XPPAG3KmAjsZJiE60xBmsPXEQLHAzh3f3HvTDDP9nuse33bXf+
nZ1T+N5sh32Yvp5Ct/vswzQUzey2mIVJ+Njs+/fuOAz9V/cbP+Dtz3F3UK8FPk+UXi4ydMBav1+9
jNcF1nrVZmxeYK036wxd4AsdUfDaY6Cp2kHx2h3d1I7VHP1/Tyl93tSxSqvjA9MF1jpvG0c3bSM6
jc7TdXSg7m5W43WBtc6jc/Tr6KrH5XhdYKPTpvX01ka3nmf8XWCtP9UZtQusdX5lHN1cGRwE77p4
nKmuA8W7ztFN14lOu87TddeB4m3j6KZtQPFzd3Rz7qB48o5uksdqPLq4p1R0otPoPF1HB4pH5+gm
OlC8dkc3taOH+d/jTUj9Havx6OKeUtGJTqPzdB2d6FWZoQPWernM2LzAWufROfp1dA/P1XhdYK3z
SevoZtKC4qPS0c2oBMVHpaObUQmqLerxusAXOh558nFRnvzb+Q8AAP//AwC8qfa84wkAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:47 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,46 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/securities/AAPL/prices?api_key=MOCK_API_KEY&end_date=2023-01-10&end_time=23%3A59%3A59&frequency=daily&source=realtime&start_date=2023-01-01&start_time=00%3A00%3A00&timezone=America%2FNew_York
response:
body:
string: !!binary |
H4sIAFs7fWYAA6yWXU/bMBSG/8rk69TyR2I7vQNtQpM29oGYQNMURanbGkKSOSlQEP99x03axmmH
RMTlOT5+bT9+c5xnVDdldptU1mS6RtPfz2iWNhpNESOMTwidUIICZIrGppW2ppyh6TzNax2gudV/
V7rI1lA8S02+hrqy0gWaUk4wEwFamsXSRXQT5eUDBExhygKU5WWt20rJA3Rf5qs7iAVXsaBRhEmA
0tlN0umxGLM2sZUkmMZtppOVmMg2sZWGSUK0qWPy8zRrSgt1Lqir3DSJTRtTdpmZuTczXcBxiQuz
ZVostAsiFSAgkemiSfZZQsIINM28WSfNQ5k8aH273ayUmIcHg92+OabiJTigTuJR1EO5p85xSHfU
Y6xijzqN9tQlkTFRlB9SD33qDHPmUVdY8QPqJPap9+VHU+f/oU7flbp4O3UmMKF76uD8eEc99Kg7
Q7I9dSVlFEp64PUQx8rD7tzPPewcq6HZFY4GZu/rj8MebjSPYOdCvSv2aAR2iSnfYYdIyh52KXrY
gUAfO4kFk0QNsYudb7eaYtOaPOwyHGAPtzLH5MdRn1DMj7h9AkWUiHflHo6yu/P0lpHa9NhuGQCt
etwF5qLHPaaUC37QZCKsIp+7xMLDDozFAHu0QeRx78mP4w6v1PHWTgl/hbqQb6XOxz2oqt9k+j2G
St/scg+dUkaphC5w5EFlwyajhm6nQ+xwE5GP3VtgpN+hS7Ljfufy0NLdfhXBr9v9D2xBZytrGuD5
jAws6xJJurixixtAm5V3VVqsk80IBMn5lTh7+gYj7S+Rfmy30hbUj4ukfPpqY3crRerOjk6qKtcf
PhfZRm3mUp9+XLhgZW13kZcXHyHRmOxWWzfl5PuXbu2yNo1OvJHppZs9NwsDidPTM0LIaXwdXTFv
ymD86ue1+47rZWo1XFVa114FvYjO1S8FFfCPd5fadZKbujHFAk0bu9IvcBr92CRV6qAXqzx/+QcA
AP//AwBIRwI2FAoAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:47 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,57 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGs7fWYAA8RW224bNxD9FUJPLSIZK9mxI+tJUZTESGwJrpykQIEFTVJawhS55sWyUvTfe2ZX
q0uiokHRooZtLDnk8MyZmUP+3tKyddkSbpnffDl/93XSareiFg/KY3Y4nH7E2PKlolFZGsWurDjB
nFEaU+8/300/3GbX08ndq7fvvryenfbPKuOCm/zYthCdeMjVsyi4XZD1hgfJH8miRevy9OVFF5+F
8zGXKgivy6idPfDCYNALG9psyW2acxGTVxhxKzHjH1QMLOAjloWzZCiVD85ywxBkmSJGbRb5vcHC
Nlsp7ul744ALoUJwXqtwwq4i4yY4FpQxgT1xr10KzCvDo5KY9U9a0MaQRMF4YDXGoRdcKrhjCxAA
4/02jmbPYLP0OiHq9mYw4l4231O+rvHsTCdsVqgqBG7XlSMVMLQhLauIELIxNQladoL+Coj38A8K
ggqDyhLhQckkOIFpM2VBRul1UPVhC/ekvF1iuiGyyrSzi/89GWzlvJErLdWPpgXrLONS6jrWuEee
m89xLtNTwkSJMmAJs/tIB+yai33b98AH8MDl/pplMlF3yuRLF1QTFpKt/dTJAI/PFBgjmjsIla00
UCNEViguq3PrPO3xULil+p4NwoC8abtonDeVM/vUfH3mURRt9lpx5KD0Dnknjt/DITbUPjW+WHSo
3xP2NnmQ5NtMR1r+BK43JY3yozouS7Tllt8BE8alHd8MrU3Ltmby78AasrLLUokkzZ1fAoi2wiRJ
IVBucBD7pfIQC04JNm7FRIJTKm9gZFIHQcxVjqVbWeM4WAFAXRd0qC16oWOVJlS3jbvuvHfugeq0
7jkKz7WrFt1UW+mk4AE1z4abqgGI9dHKaaL59yRgVWg42LhPgf5zhO+rkjY6IBRiSj2DUK2sUKid
iA22I9WS0HsuNVoi1kw03m/UKrwgHAcQLGY3HbrgX6l2vwE1+/TiG0hQbAOkTyhzD4LtjuDBgXwB
tOvcezgHbuEViGQClsGemtXihulQVMVf8nWlORsQbeJxpUjMAkIXykK/UJT4w4HGKGgMjkeJgou4
/jtdpHP/G20kIUJRRq/vE9V4LLSXnRISsj4sSxR8hb9pQqz0Li2Kw8I/DGRP4Y5upUmvItd1XM5W
GlT14CZoCXERYJWDZIIgVBPoDqbAAclAiayKUNgHyhXqi3hbFQ4bsZkG9UlbPnEGJcJTr+yughWn
FAkH9avrVlvW7V9c1EpTi9xjwrnK18ZRogxqiz4ccaOB0WpOV45QDrfMTC9dLNbszQkboXdpviYn
T97AThyrE8zB0mQzh+IDXYB5cjNmw+n045hNh7cf2Ofhrzjmbjq+nV3dTPA5bLP+y6xL75UlgkN7
/bPN26MrAc8tQf/pLHv1M+v3zzvdrJthUfHYOO/C3AVhc211VOyjc+WBvde6tMmY/alc6LjGti1f
BxtyXDYQvFw4SQ+qBhYqFbvy+ilGkgvb1c1ocjud3A5n4zdEp37AZIaf017W7Z/SZU9qHfN5zYfE
CCt6We+sk73sZL36YFIZmt8lrZ4XLtnoCekdxSZR15X442YcohnRD1iHCjnugAw/5EEtS+PWSiFP
3fMzoN8GS34TpW84ml19GtOrEi3g6Cl7vX2eILDqNInLxa9zNKlauOrM0eZmZ++hWCtcevvrFui7
cn/RbynLeudsMp9Do9j4MemS5IHez4SwjpC2V89e9ACckvLkQAEhbV1Gn1S7NdeeCE+w03Yka8t6
dtHJ+p1ev8rLXy2i1Jx2TqnIalf1ExvSJVSzqtt/lXW6Pfw2ro4sql2dd3rnFAKaNVeWHiGyQUql
JEByQ+lMicI64xbr1tZ4jNYxSbZ3VotwZGHD6xtw4oOea2R9f8cffwIAAP//AwDKz3HRogwAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:03 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,40 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/securities/AAPL/prices/realtime?api_key=MOCK_API_KEY&source=iex
response:
body:
string: !!binary |
H4sIAF07fWYAA1xRTU/CQBD9K5s512YpBaQ3uRgTD8ZoRI1p1u5QRra7tbtFkPDfnQaQj81e5r15
8+ZjAxV6r0r0kL1DpZoFhrxAG7CJhCEfyJb5Em2LkfDKoM8LZzUFctZHQlktvlsX8AQVqkHhrFkL
tVRk1KdB8UNhLlzbCI1GrVELT7WYIeoYPiIwyoe8bqhAyJJeP+4N9ligiiFIZJJeyeFVMnzqjbMB
/+t4NJRvsE/z9MtpI1Z9kj4UkrHcxTuWA+UXZ2QX/5OuRnvsQcajfgSFcR4vG5tTOT9iaXzdNet+
TrX9NAJcFXNlS8yXzrTVzmO/3QNiW2MiaGutAurc2fNJE5nJNEvGcZL2u0k9r68zAMJVN/jpaQ61
Lg/E2YLfkzg+ll4e7KA+Oz7zunO7YwH5XDNXO2cgmynjka2waBsKa8g2QJoTGchV+dWUX6wIVCyw
YfTm5uEeTrZxRmTPL8zNqCQGJpNbKeVk/DqYJowWrqqdJ270gp8+vqaw3f4BAAD//wMACXw+obgC
AAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:49 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,53 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/search?active=True&api_key=MOCK_API_KEY&page_size=100&query=gold
response:
body:
string: !!binary |
H4sIAHA7fWYAA4xWa3OiSBT9KxafZ7NNd9M0842XhIig4AOztTWFSjlsFAyah5ma/77tmBnoNh3N
NyCevn3uueeeH8qi2myzssh3ytd/fijFUvl6fPVt/vbYm6+UL8q+WDzkNXvrRYHDnstsk7Mny4xj
3+51jm87dhQP2Kd1XrAvIMI9a2jf3acUjnuebU10xD4uiofjR/ana4QaWPn5pXXcmztxt4f2cb45
Tpvjir8o6HjVetmxq3p78/uw8mm9bkGrVEMGgQL0o6XNOehw4gXdBjucNMgyYAJ0CnQeeJXTaMoB
jxNz3OCOb5Kbhh9ZzQBAHRhIgJ79R8K0BX360TtwD14uWKMfMNHPH+kbx4TXammYv5xw/XJx0/m7
6/9pqYYNBIDmAS+0bwfglgQG4VpKjxQR/rR0+rqevcnuMArjc+2Il8BIUw1DoMbMektOmKO4JRT2
8I77CTmqjggWKD+o5F5fycodhN4VnENdVwXOD2un4tTHwSZZ+Q77GQsAU1U9g72Xwwbj0DmxEIwc
GSybQzaJArkOyZ+lPUuqTXbFEOqsbQAI9c6d2mwLWpmYY7s1hJPi+SpsiAAW5vCAnrMhJ+sk9u4b
6GSf1VdAY2YfSBO9o3YeuRGPZ27SQMfFLr8GGmJKRMfb1GUp7WBqBv5l71CxbmAKxJqdTJN6R5zt
8/Wp5GC/lOIahgaEAUn1u2kuHZDkNordU8V+aMtwIUWqLmruBRMkrdfK6qfLk4cw1pAwefUK9GNO
crHX3mBxNDODSxUza9M0URWpF9ApJ7g7htwS8122/TPYn+mCUALESVm99mcPUjr6rNTosnECCCgU
tVzVOsez4sVmvyn6V7nddVVnF3asTgwsMpJt1oDD7o7jWYN9fDpVzS7gJp/ZkqZizRA37WC4dnn3
aA/4xE9G5gdJ5LS24NTujoLexPKpgymfRChCUJjLNCKxfA/0zdTsX8E/Zo2lwiVw4BBucVkjrxWo
4OV1CA0DCdSkZICIfL8UqzJbN1tdbqsQqli01WDoyInIXnZVedFICIQEGmfBoCbc+ARR2N4FQVUu
qvpy1ViHRDXEjDPtu9Kq7WxeX8MHAQbVkYhczh/4HNn1bD4+dauncnlNTsWAqKIPTuYlrw/T8xt4
MzD7UXLmV+8iHzlRqqOZN0tdQzMUPuxQKrK0AsFA3luvesl3+z+9ld5CgxQiIm6feDDkWHLilumy
BzGXKBqTNQD3YIC8OA4h6nsIK7ybsRx4lmWnS4Nja+w5fktE47JYvbdZ5u0GZilQ3J40tCq+C2Y7
1B9J2TBzT7LF911n8P2wKxa/FeWOutIBAywACFQdtvEc84bcbTX8F09d3w2c5AO6UC/1rbvhzLYs
R4dCw6EuutpbBaelPBSYjj9utCVtuKoiSETC7gbEkkrJ3GXl/pqIpLFgJ0KvhtvHntTbzNDrRfEV
IUmHAGARGs5yV56fnzZFeU0cJQaCYu5Y5cu1wU2AeRvGrUEe3brhB+vqLNMAjAGb23/ZL/PX/bdt
tspP//XzfwAAAP//AwDM4r++tg8AAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:08 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,67 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/etfs/DJIA:US/holdings?api_key=MOCK_API_KEY&page_size=10000
response:
body:
string: !!binary |
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
IeD3uWc4AAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:13 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,184 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/etfs/GOVT:US?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
AP//AwC4brl6ixIAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:12 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/etfs/DJIA:US?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:12 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/etfs/SPY:US?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:12 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,82 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/etfs/SPY:US/stats?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHY7fWYAA5RV227aQBD9FeRngmZnd/bCW9U2z2lIpFRtZbmwIas6JrUNKon67z0mDSE3HAQy
7HrPmTlz27vsOjZNMY9NNv72Y5jNijZm44yJzRHZI5ZsmFWxzYumwXNVlEu8FmNGzmkvfpj9jG2R
r5q8uVlnYzWiYdbWRSpTNc8XVcyvF1V7ldexXdYVzpQJVNUsn6VVmsVqlo1pRDqwCgp0QVlnWfop
FlW5voeKd45FE2syWuxz7DoW9X7r7IRN8MEY8cFpq3sZHoyzOCsuGO+JvGL7GnC1KIsWe+0ahqtl
UabbuDGrFHvlReM3aGNt2EG3V3X8j38E7VehyJCHfKXIgjC4w+i28fQO3oBClEVWjH2d5m1VTqNy
2GgSi+oQ3sFfptWhokxgZ1QXY4f8Bn8Q24MmpfFhH/DtvDLuVZY3JTEFIW08MZ6MmOyGJFYHKmLn
AgUrxlun9BNFvWRbQeR013yIMFntkaNUTeNNmxbVAfWiJaDiRdA7cMa/h+SxSrQo8aSMqICAAjwt
SjDD+Y0C2W8c6eDOfPCOBPUvPfhtw3mHkkLHYErQptefwkyPZq+1EmFG5LTj0APfhtsqi+qzEpB9
FPULtbpnwHjH3qtgkXUyjnQPfqsWR8UoNJNywb5A8T6rR51ahcnGBoVPaGblegjuzXZATDRlDQkE
E3LEz4GqR69VSA8kS5ctRy8Mqzf0GkZTBCdee4c82ee4dpF3t1NPkkWL1mygwsL7d7Jsc20sW0Q8
sBBmWdcWsb3MxndZAnv3P7/9TfrLRXcrFtfdTTk5+XQ6mHxfErE9GQjR4PPZ8eCsXjYtDrVp+ivW
m2NfsbxM85Tv7o3PJ9iu0/R+OTrBKjWpwvJ84jzcOUarEnabOFuU2bhaliWc+jO9Kqo57sYN8sPp
x4vs799/AAAA//8DAKcBTmvMBwAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:14 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/etfs/SPY:US/analytics?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHY7fWYAA3RQyW7DIBT8leidHeuBMcbcqrY5p1mkVG2FUExiFC+twVka5d9L3UWVqogLM29m
4M0ZauOc3hoH8uklgkJ7AxIoUjZGPqYpRLCxG39S/tCqgzE7VdptCTJNMSb037BqDyAZijgnEezb
qq+N8p0uTAEyETRLEsZjjEDvTRdeVYW21Ul9C9vGqLptfIhnAolISMhJ2XCuWHzZmV9TmiNDTpM4
5yK75nD2+KPnGUkpCXrGMGdMiAhq3e2MV2v9GuISJlgueEY5xjQMXak741Tbe+d1U9hmCzIXhAtK
yLCV8RuQZ7Bh2c+7en/D5GEVKmx0/VnrfHo3G82fe0TKp6MUcXS/mIwWXe98EHm73plukD0OtW+t
+svJ5TzQnV1/wXgakHW2CXA5zwTjdEIwwcA6U7QVyKavqvCp47rUTaihHpw3s9sVXC4fAAAA//8D
AFM/0IH5AQAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:14 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,603 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/etfs?api_key=MOCK_API_KEY&exchange=BATS&page_size=10000
response:
body:
string: !!binary |
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
GJ0CAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:12 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,241 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/fundamentals?api_key=MOCK_API_KEY&statement_code=calculations&type=FY
response:
body:
string: !!binary |
H4sIAHE7fWYAA6zXXW+iQBQG4L+ymWudzJmBYeCuTa370arbtNF2szGI1NAioOL60fS/72CJaQEv
PBnvmIGBJ8d5ObyR53Uy9edhkvvxinh/3kg0JV4xOr50OpP+FWmRVe7nYXHKOEinoZ4N/DhYx34e
pclKzz9HKz0y3oX+kniccXEcysJllBbrXT/q8/Jdpq9O1nF8WHOZj6d6YT2rr+Ft5ra5rc8Kk+mn
cVGMC3a4Sxwls3LqY5FoNdZPEa5y4uXLddgi66yY/ny91WayDfweLM8CDxgVUj2R99YnZxr3l5sY
4eQIJxycsub88FuGnNymjm1XnIu7rDe5RDgB4WQHj1NzwrHORpyKOkJUnD8n/GYiEU52vhPcg8et
OdmxzobqqSSrOHcT58J5Ot8JLsKpjvvwi7P0K1NOSYVVdc629pb1EE6FcDpt0KWDmlMd62zEKSgD
WXHuFzfZELE/wUE4ZXPear/JvNX1lLyaQ7Pewh9i6ikRTrs5h0q/sbx1qSusinMkX+Rig3DaCKd1
3IdfnbbRHAJBbe5W/7f/hHuLyFuwEE7RnLel3zHl5NSu1XMWdjuHnXGuE9EPAT+Rt8J03tadI78/
3N4gnIh+COBEDnGjeQuuziGo1vNF9B5vEU5EPwSsue8r/cZySFJLVJ37znbTAYQT0Q8x90TeMqN9
HwBlvPr+nP1O4S4938kQ/RBTzXlb+o3lraLcrfa3s6tsM5ginIh+iDnNOVT6jeWtopZT6xN4dzlH
vFcYoh8qHqap7/vwm8shRYUqvj//tkiQzjM/2RGvJOvjcW8ku/t+8ahR8BpqDbm4GBRRnOhP9OIo
y+Lw248koHosDiM99H34MPh1x24H/Qd13R1d3gu3SJMgetWTTP9E0aUL8v7+HwAA//8DAKrctbLs
DwAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:09 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/fun_olOrwl/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
AAD//wMAU737rnReAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:09 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/fun_B7EbOD/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:10 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,109 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/zacks/ebitda_consensus?api_key=MOCK_API_KEY&identifier=MSFT&page_size=10000
response:
body:
string: !!binary |
H4sIAHw7fWYAA+RbTU8bSRD9K6s5G6mruqo/uEaKtIcVUZLbamXNwgSs4LFjm2xQlP++Ndhjuts2
HsbjDBgSRU4DNu/Vq6pX1eZnVvw7Wlzlw8tJOS/K+d08O//7Z7YYXX4tZtl59ten95+zQXY5GU/z
8n5Y5uOiOv3z3ceLTxfvP//x7uLjB/l8MV+MxvmiGN4XuXwbKtTB4XhSLm6yc8BBNi1mo8mVPMWX
bw9Pu3rR4eJ+Wj1xUS6K2XQ2mhfD7/ntXRE+9eXkrlxk52qQ3U2v5OBqWP2bnZd3t7eD7GZ0fVM/
vp38Vz8cF3lZP54v5FuK78v//hr0h/Iyn98Mv8hPOZQvHM5v8tlrBGpCnPfbcE5nxSL/MRyV8nov
HiFvItQnp1d6E1m5BaV/CyDNWwB5eknZqra+DZDiTU4WmJiucT67HpUnjPClQ2vV9F+hfWvX908D
6P7Wfxo493f/08B5kgnaqsa+QpytdLtvjgSdQsyqlzpTRv5mNVQ0Flg9fKwQI3tNvDpZAkej2erV
0Ro/KkOMcna0rnP4MN2MBEAi9hELAEaRURENAN5b3uSB0YOCzojYp4ZjEqEsPoQ0IEKiXEtkTYQy
ztNWQRD9Nh62jznbzXHDZLBsYhlIejhiiJLBorKON7Gj7zkZdmGnpjmgmeIc8EjexKFHYHaYhh7Y
GNK+3xw4DL/yytpU+h68S6Tv2FmT4mfwGl+A9J8an7gJDWxsSAF5jOAzOI2J8h3b/nX/FHDTCLhT
MfC45EmNF4nbGPhDbvQs+K6Bi5Jj4NrptNZBhxE/QOpbENsmiLV12mIIWoPBddtb4tZSzXDJTQhd
Ay0zpHe9b0HvGhU6q6RWQVTotCXmGD8wCAW1Fh4LPVhLBN11ugOE35qBKoQQCQDE9YKLa53gFxJs
yoAFJ8XAHVMC+4e5vXYPdhDBZxAkAlhQzKHf8ZXxjc2/l4+l5gMWnNIE3eVBu1VMVyygc8qHLLgV
uJAFK1FPK6Ew40x3Umi1p+mIBAXCA4QkWGO0NhEJ4n1IpVKwIOWk53zYZf2apgHbqCBKtL2PBaAV
IdkUu9GrWaDXm8jDwJNMbRip36Tq1wqFkrQZivS1PSr4BheUB2FX8sdF9c9pT8rFmQ+k0KeGn7D6
yt5F/5T92zXzRhzw2uSsfG8ceVbOpBbAdgi8veI7QB5NuxvIZfxLHD84eAFy7wC4D4GzikdcRrAp
cHhofb1r/RlTbYSYtHbr+rV0/JLTlBQ566UFpmrXVqN2R+3xjQXfGj4S6yjmmtClNV6CbjhtcMKI
99xd8A9QfWv0iqSEU4he3E4afK4EkgYfPUlZ6G6t1Wrca3ahgTuooDP0wezn2XiznnqMNWSDiceK
35NxP+zxdNTY/170VUknt0YvxqeyL2v05KwR2xeqH7ur9+1G/f1vaNnldAR6sNn2KG5+rfmVyY3O
arcTHfZw2XVkHsTsgk54iM5qHqLDl3KJu2/Y27XxExLokQRDBnQ08Ep7SAdeNo7rm4/HhPDIx13+
tZ71dq3+Eujo0utOa3V63alIbYx6IO2hw81fa+ht7F/EAcfLP1bJil+5dNMNSzZ6B/4MBxAh1qaK
aCh4GWi1iqOuEcibVPDIXqHprgu0e2/8vrTftfaEM3SB9sF55yLtazQQa5+ZvdlYe1unsbudb8tf
g9ie902xU3zPUdU3X8/+NXavidIdn6jCdij/9tifpX8Iu57UN6vIRj3PyQnE+kdvNrbdCFVWdOcB
D4H//LoHUd0jFwpAjH203GSst2CB/V+Ovf8MsrL4sRhO8+vVO4V+/Q8AAP//AwDBQQXuIzQAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:20 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/zacks/ebitda_consensus?api_key=MOCK_API_KEY&identifier=AAPL&page_size=10000
response:
body:
string: !!binary |
H4sIAHw7fWYAA9ybXW/iRhSG/0rlayLN+Ziv3K2qvVhpVeW+qpCbeBPUYCiQ7Uar/PceB9t4BijU
2MGQi4iZAMkz58x73jlDfibZn5PVQzq+n+XLLF++LJPb338mq8n9X9kiuU0+fbr7moyS+9l0nuav
4zydZsXs3d3Xz798+e1X+VG2XE2m6Sobv2apvAIVUmNyOstXT8kt4CiZZ4vJ7EFe/e3v93csf994
9Tov3jPLV9livpgss/H39Pkla771/ewlXyW3apS8zB9k4mFcfE9u85fn51HyNHl8qh4/z/6pHk6z
NK8eL1fykuz7evg2Og/geqGn6eJxkl8d3X26fBp/kz9wLE8cL5/SxYVF0DcRX3chzhfZKv0xnuTy
q4YMp7fh6Jq2H1+7vuwA9FfOZ66c76o2YCv1vHo+Ke/XyHShluVYuAFTtarjl+XD2pXyi2c8XM0v
HvFwQb94xGvbjK1U9LIQd0jq6ec+G8MlRb7cKHMDLqkggdGiQ1V8lbCASB6onFpDA3rPXpdzNbwx
GsgW073LUY9LgOCN0sESgCyA99ESKC6f1VwC7zy9z57pfLzb3h0FTkgS/CY3OkukAmwSamYTUQMD
aw89Bf7IrlVbbnZKe+sa3GTIoscmNyNoJoy4iYmMoY9I+M6x0YNhZ5vhtmj0Os0rbLSOvI2xDaOC
TpK83Rn7FGr2TqkgyYnBoAmoGQi9i6i1liTgnrZ265PbsbKut2Ud0NhQ00ih5WpuE24tJUB9SJZ3
T45gNUZq7rzWGJIXL9Vb5KBkkei8cr7z8EdHCbqWbCXTFDYodI0CQSfnGH0M7sGCcecV9PbkkrDo
g6CTdxyZGKliDDYuZQY8g/JnlfQTQi6uBAia8uYdGQ7kjZQjQBuHXPaFepf686n6TnA+StetVZGu
a6/IQ6DrxonUx7ouHoe5E+7Wut6eG7R2ELo2EE/C5EJ9Y/JszJZb1dbQu+CfT9lPYCepaTrUdvTG
W46qGhhttw4r4li1pk42eittP3RYMXuWQN8gbfY7WE9h2jsXe3Y5rDlSWxKPEnvVV+yPkPhOFoDR
6dq9leadxesE+14E3VjiaAGwsPnvyngepe+EX9QMfJgARYlfF7+NixfVc7GLF4HUcD697wafq/Rv
2Hk5xLjYzmsfF3pt5bzbSfRPsHb7Ly3gqO3Pob2rh2Whr8dD6Id3Qyz7vUlcD0viejyA7ng3wBLE
JnA9rOx7NR5Ar7wbYLDNpsRmWALX4wH0XDuKcNCF2QzrA1ovwCcYtpNVSwUpXQ8r1VK9pHS7CB/+
PMB+ZmU2hUrMN6MLS1U4V51RgskhxLyrJbDGl/LcMCvBXG1XmpMDyILjro/+YxU2ye8Qi7ZMyV+P
1uT1cABh75DZKl+4z5K5Hq2Z6+EAbkIPedJ9x1KhxUaee1TsgywnB9pGOW7sVg9GnKqyfXXdWt8e
6eOopUwxB9RMCBBRs1jxmBoATV+3hv05cb4h1SjiJnDi9bAq4uajnHgPXeWQVHmPttliJAWIHJoW
qWFAcaC5uDTu5MjV7tPfh7b3vkjDDfKG37MBaG7vYKbkb04N4YPve7Y2HkfsRJgwIJZ0dqFr85aR
494qgF63Hc/63wz/I9UDcC6saHAzzIpV3W+ob4blGVs34tradRfq7Y9Rkmc/VuN5+lh+pOTtXwAA
AP//AwBueTOU0DIAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:20 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,48 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/zacks/eps_estimates?api_key=MOCK_API_KEY&identifier=AAPL&page_size=10000
response:
body:
string: !!binary |
H4sIAHk7fWYAA+yYW0/bQBCF/0rl52S197XzRh+gVS9AVVSqqrIsxwWLxImIaUtR/juzcWyv8Wwd
nkoDPHnGy06SL+fsce6CbFXm86TMVsHk212QLubLpLgNJndBPg0mto4/nuujP8fBKCjz9Cq7hu7B
wcl7qItkntlquZxlr94WKYHeLMuh9ebL2cm7T/TDyfFZeHh0/vqziCTcTPMruEnhT3DKIhGsR8EU
ZkOTU27GNBoLCut+5Ks0mcW3WQLT7J2mtcyu84V9YYdf7X7JLCumyXVnZdNs1p4Ku3ZxU5TBhI2C
eZYUwcSQKLTX07ytLvOLy/p6tvhVX67KxG44jafZzzwp8wX8Q3Ezm40CGJFmRRmnl0lxAW9jTAmL
qgmxiafJ7SpOLhb16k1bULyvPf3oYX89+reYtBeT7mM6lSgmPYSJ15g4YVK1nLZlBYoTybagGAk9
oCgRRoZ9VM5H/ELKL6hBUqImFRJptGlRhYTXoCKio0ZRSuKgGGGUyT4opki4/6D07pISjwDFEUmB
VpQjqW1ZkWKt9zFihE9SzOhnKykxFmxHUvwRpBhqfpR1zG9T1ubHRWt+Xu+j1iKfISg1Znx3UAwF
pVBQEgWlaQfUpqxACUJrScHp5ZWUNux5Skp5Tym1c57ASTmnlG7Nz0hmXPcz2jG/Nk9YT/SYH7yJ
F1JDpDx5YpAUa0RliOBuQudRo6mQ1KD0X7xPywiJE5AzsDwB0xQGCuZyDJQhDOMEbfYEOHniBKYo
PE7gnDiqKMVdPTlZwsbBrZyk9mGim9TYwySJlPuvJ0+YwDjhYQLnxHDno13n08ZhFbZpQjMvq8ge
YIikGo3sKyvpzRMYKzxPyKE8Ydo8ITpxQsg29jWPUjYO+kDBNN4HZfb+SUp6jyi5c5jAMQkEE5id
kKJjfsJxP966X+RVlORI7FOgNIRUtX+fVG3BD0lBHz2k7Pr/ipQnTAySasOEJiqUzjkFdVSj0q2m
NJHGi0orjWlKMgRVtX8fFfQNhkpvfhfpo4K+egKoPHkCExWeJ3BUTp5grFWV4GEnUghHVUI3quLe
6Ed5iKBSOKpqf0xVwqMq4VGVeAqq8kQKDBUeKXBUeKSo/KVxP+oECvt9HrY/vvujlONmD93vkeYn
19/hk89+l/EyqQeu7wEAAP//AwBFKFSBCxkAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:17 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,70 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/zacks/forward_pe/AAPL?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHs7fWYAA2TOvQqDMBSG4VspZ9agJybUbFI6FKTkDg5B0yL1J8RIkdJ7bxw6ZfmG91m+D4Sh
e1kPCppGt5BBt0zOzDvNZrJH1bq9nm73S6TN9SbYno6NhAVWeSFzlNEei38b35OztFvjS1AcGT8n
gKCwZgVPgEcQrJQJVKDmbRyTLtL+JG/CsPwfIBN1BmN8uwYKYSLrVlCSVfz7AwAA//8DAJhm1Wb4
AAAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:19 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/zacks/forward_pe/MSFT?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHs7fWYAA2TOsQqDMBgE4Fcp/6xB/yS2ZhWEDsWi7iFoKtKqIaYUKX33xqFDyXLDfXDcG9zY
3bUFAZembCGCbpmMmjc5q0nv7bmoq6Yq20NR1VfvT9Mrp3u5p3dMkMVJFmPm7bbYl7K9NFpuWtkU
BD0RhgGgB0Zo0FMQmBN6DIB5YASzALiHhPC/qUFa5cbldwEJzSN4+Lurk85NUpsVRJoSzj9fAAAA
//8DANw+WDX/AAAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:19 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,54 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/zacks/sales_estimates?api_key=MOCK_API_KEY&identifier=AAPL&page_size=10000
response:
body:
string: !!binary |
H4sIAHo7fWYAA9yaXW/iRhSG/0rl62DNmXPmi7vtxW6rfmy26qpbVRWywE2sBYMCaZpG+e89Jhsn
DDMDXpkEyp3PTHgt8vCe8465y8rlqpoVq3KZDf+4y8bz2aKob7PhXVZNsmFzPfr5k3737/vsLFtV
48/lFVffvDn/ka/rYlY2V4vFtPzm+3qcc21aVlz67reP5z/8In46f//Rvn336dtf0REvjqvPvCj4
hVKAw+z+LJuwNhelkGYg3AAF7/urWo6L6ei2LFitWWlLi/Kqmjc39vb35v2KaVlPiquNnW2x3fsB
m73z63qVDeEsm5VFnQ1JGL4FsX7loqlOqlD9srq43K5O5zfbxeWqaIQno0n5d1Wsqjm/3XqhqIvp
7XI1uuL6ksvL5t7GZb0ajS+L+qIcwU105/XiYTW0Npnf1PFVX2OW1JglNWKrngYmNTCpsV69P3td
BnWUQb3N4AcKMqh3MYiPDAKA1GQQPQZBWOek9hgEiYjKbTIIAkgrk2SQZUAYhC9b9qKRcjw4jQmN
2fqb2gONALlxKgFkXGa9elJARkxxJ5DUmiJJIr4tH0hCq4nvTW+aokOrfCDRWY06bYoktUKpqAuQ
MgehD45kUqU3KClX2nw1k/IImNT7myR2YFIGTNI5rSS06D0i6RqHXCP03CIFswewSSTv09aYFJDa
KiGt7cajki+AY1ykNxpdDoZO2iFxgLAnjbIDjRBq2dxIEWRL01PLZk63xkYAkkjS49EYJzSkeLQK
UX5BvnkF/wXBGdKaw/ftpEp/nVvk/LU/XS7VAOT+XEKQSxXkkkJcojXOkvZtEkjwdKh8Londk8wm
lyCbXv4Ea3CUlAy6tZ1GScz5rw4OZVKlTyjFKZulio6Tau98E4by2Thp2tZtnSZu337r5mFy2yoF
e572rRKdUTtmSY5Fpp0O9nRJEx2/+nTJhEpvQIpcqdjAuptHdVI8RuLNTh5tG29AcJKx1geShDFa
gfLOfEg6rT2TRCecgTSSoNE5JVTbvoMzXABMyIEO75RJlf6cMkeV6t7Bz+SowIxknJBRhjNOGEwZ
MErrLI+UAB6X1joFvlE6Nkkg2qDSajBS2hSUKLV0qLr4JORaxI5O+sQxodKjT2r39cPkMeAYCTkh
HMMhJ4wjhPq2UWBJWg9Hp9EqH0cQkh7LzyI3kraY5FGhUga78Qh4+MydVOnRHpNtO+2O9No4UjTb
hHAMZxvalW3atg1S82zPAcfPNlIFHtXwRsf52s82XDHptq20VVqabkSSPPyhZFKlz4YNsbGgWQ+6
Z4skvj6SsUmS9k42YSRDk6STQmlwW4eSwINfM/ttNGzFgfmpOT80bI7fIo0jK0iATmeSHAboJY5/
Eiq94ThgmSj1u3k8AovswGMk2ezPI3dgsBKEP0Fy3T4H7YHIxiEf7fAp2RgeNjHNJBLwqNqRSZDu
BZhMqPTJpLCpBzfBk6Gj8shIqAl5ZDjUhJmUASZ5/tMGnfRDDSKSwk0iLY+LVmwCaYV0O1o2sEVI
6nj4EzlO7/uHFnGVPnnEVMs+fhwjoSaEYzjUhHGEEI7NE0PcOozk8vb5uAOlhfNatlW7cHRstdjR
Hf8fP/phEilqwLvzNd3/yXSV/6xGi+KC6aivp9P7/wAAAP//AwBj51stnCYAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:18 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,39 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/indices/economic/$GDP/historical_data/level?api_key=MOCK_API_KEY&end_date=2023-09-20&page_size=100000&start_date=2022-09-20
response:
body:
string: !!binary |
H4sIAGc7fWYAA2SRy27CMBREfyWyuiSR7TxIsqNCYodQ201bVZFJDHXl2OAHIkL5995AQZDufMfH
o7njE/oW1mkjaiarhjmGys8TggNHJaKYxiGehpigCTow6UGk04zgiNC8n4y4ZMThLI4wof848shl
OYmjDJNHjoYEj7gE51GC0zE3zpcWRRJlcdF/TZBQDT+i8oREAzhM1XL7TpZbwG3XrrUE9WkxX8Gs
WDtYLoy2Npjrllsn6mBldONrB/e1Vk4orhwqlZdyELxypruOfjeEqjaG7z1XNeho75lx3MgOnktm
XXVhmnNykoaEhpS+kbhMSUnyCGP8AaReW24OzAmtKuvAAXBSJNNbcfcAVze3aw+WM6sV/CZrfrx1
7Tkyev1TZRfMzjpvgplSnsngZSgTFlDCWSCfhZRgbQO9gR6kZMaiHvrhR1ft2JZfFu5/AQAA//8D
AF1gUZ85AgAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:59 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,138 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/historical_data/AAPL/ebit?api_key=MOCK_API_KEY&end_date=2023-01-01&frequency=yearly&page_size=1000&provider=intrinio&sort_order=desc&start_date=2013-01-01
response:
body:
string: !!binary |
H4sIAGk7fWYAA3TQ2wrCMAwG4Hfp9ZQkPaTdq4iMokMHZYpuIoy9u7U3LaPrVWg+/qZZxH14T4/X
cPGhu/rJi/a0iFj0ohUERAdwB1KiER8f5niJ6BAkpHOEtSkxJqwLDI6A6xgSNhkbhhhds+iStYXV
LOu5aJN12TK5nYGR/1ZCkavAuro1200YlEx1q7d/Y9Ko61Yly9lqqezOvHK7Bx3fyrnnRoz9d+qe
/hZ74xzC+gMAAP//AwAceBCU4AEAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:01 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/historical_data/MSFT/ebit?api_key=MOCK_API_KEY&end_date=2023-01-01&frequency=yearly&page_size=1000&provider=intrinio&sort_order=desc&start_date=2013-01-01
response:
body:
string: !!binary |
H4sIAGk7fWYAA2zQ3QrCMAwF4HfJ9SZJ09+9isgoOnRQpmgnwti7O0RQ2uQqJB/n4ixwGR/5eh+P
MfWnmCN0+wW2ZYAOFCrVom0ZoYFnTPN29OzI4md2uDb/lkrriFDJFktrGFnOpVBazdZ72frSstVO
y9aVVoWAJFtbWWM5yNaUlrxBJ1td5Tr/rayyXFs0v34PDUzDK/e3eN5+05zS+gYAAP//AwAidEj3
3gEAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:01 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/historical_data/MSFT/marketcap?api_key=MOCK_API_KEY&end_date=2023-01-01&frequency=yearly&page_size=1000&provider=intrinio&sort_order=desc&start_date=2013-01-01
response:
body:
string: !!binary |
H4sIAGk7fWYAA2TQ22oCQQwG4HeZ61Um54mvIkWGVlRYbGl3pSC+u8EryeQqJB8/Ifdyvvwt37+X
zz4fvvrSy25/L9Ecy65gRdwAbgjKVG59XmMIpu6ClZFct/UxvWvIGrlpdYlChqzrkK1MSg1ixzkb
fNDBBaqQVLSsW9bGyt6sERhlbBkrEBmSOdmQrBkzoxLiKz5jyZhc2Kk5Cw+YB0wIrnE4s2RMw6uV
4gJgl9YCf0zlevxfDj/9FMvrOs+PJwAAAP//AwCqcps57AEAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:01 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/historical_data/AAPL/marketcap?api_key=MOCK_API_KEY&end_date=2023-01-01&frequency=yearly&page_size=1000&provider=intrinio&sort_order=desc&start_date=2013-01-01
response:
body:
string: !!binary |
H4sIAGk7fWYAA2TQW0pDQQwG4L3M82lJ/kwu062IlEGLFg5V9FSE0r13fJPMSwjJR0hyK+/n7+3j
6/zS1+Nr33o5PN3KSE7lUEDAjrETLkv56et1FEFqHBYGIPZ0X/5rnnQ0qFcRVZKsadKAaq3s7FaT
5pY1w5mkqSi3lnVk7SD3WhFBnLFnHBCwkMFkwpaxOjxEndmmNXTCUs20Sh2XZlznyc0Q3iQ0P48l
43EbyEZs9Df5eSmX0+92/Oxvo3m5ruv9AQAA//8DAPeSJDvsAQAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:01 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,38 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/securities/AAPL/prices/adjustments?api_key=MOCK_API_KEY&end_date=2023-06-06&page_size=100&start_date=2023-01-01
response:
body:
string: !!binary |
H4sIAG07fWYAA5RRW2vCMBT+KyPPKklr7OVN2ZDB5i7icIwRQhpjtE1Lkg6r+N934gbDvu3xfNdz
khNyvhZ71lgtJOPFrnW+ksY7lH+cUMG9RDmKcBQPMR2SCA3QhgtfW5TjUZalE5ImmOKYZgkZoEJ/
6UKaIpDR+G9morVWGtFB1mp5CyGuKbVnlntdo5yM8HnQK4uGBPfLxgmlOE3IhJC4Vxb/q+wTMAky
7UF0QhoyAsC42lm1A4eoq4abjl0YGNhiPZkfn0LW5bXkQWy5UfJH4A6K1cdHm3UgMLwKV0ybppQ3
90Zc0ooA3b0sw9DfzmuxlzZYps8Pv921016yKyZfBfdGKw3AbDbHGM+yd7qOriw9fv36Pg5Lb7mV
TJTcuSsFWdJF+paCAr6/4rZjpXZeG4Vyb1t5hmvkwbOGK9jftGV5/gYAAP//AwCKhFgOLwIAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:05 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,86 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/historical_data/AAPL/marketcap?api_key=MOCK_API_KEY&end_date=2020-12-31&frequency=weekly&page_size=10000&start_date=2020-01-01
response:
body:
string: !!binary |
H4sIANRaKmcAA3SW22pUURBE/2Wec6TvF39FJAwaNBCiaCJCyL9bx6e9SQfyEDIrTe3q6u55uXy/
//3049f9l+vD7dfr0/Xy8dPLBb/cXT5ehIQOlkP8cnP5c314xh9FwsySs7vkA73evKG5FppTxbJK
3GimeaWJjFqrJXSkyRaaOgNiktqn2nxIrjSRm1d7GM80rTSrsTOTeo8060pbgNMqz8kTPihWWsOz
wpxj0k2HLkoYYFR3pPakmw5ZlHAnXtkVSjIpwc+upFLgeLnbSFNvDmqAlTSrmZZVCRyx5iiveEtT
b6niZlYKEWYfaoNeU8XFlSTOFlNOTprX2hRInxrqz/SeKgcv5kqWA12HbPkG6WUpVO/QW745+cw4
l84026rbg1S1pGrSXQfl6kmzqSTVmFjKQ1dPitxTA93sqXYesioBionPppoyCJpXJaFRxOLJNGTw
pNd8h3RlQruODuZBa77dIk2smmii45BYaW5DWTxz7GUc3CtNWDvpjGGYPAG95ht9T8TQTKdpAE1r
vqFZHdlK4qk7fsiqRCMIywRTPG3Nk16VKIqefX+nO37wqkQxZIqndrePNK2Tpiqu2EHnf830mirR
iqbEEsrJE9tTheFxuN3niRjpLVUYnhJtE9XJE9tTxVYaWCYQM/lte6qwHCzkvFI1vVK3S8KEweEy
OfMy04uSbtQ280yd7NbtkPB5SXAvE4+c6fWQwD4YiE0lMhoo26qCfYZr2YXuT/GWbVUBwm1N2G09
PVL2VWVUgp1C1jkNmuyrCimpDqvkMYK8ryosBlYmzI9NreQ9VJrBGHhJlymCvIdKsdTwZUNMZAoV
76HCV4JAbSpYPtJbqKRwSRwrRf+f4s83l8e7v0+3P6/f8Onj88PD6z8AAAD//wMAyLTn230JAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Tue, 05 Nov 2024 17:50:12 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/historical_data/MSFT/marketcap?api_key=MOCK_API_KEY&end_date=2020-12-31&frequency=weekly&page_size=10000&start_date=2020-01-01
response:
body:
string: !!binary |
H4sIANlaKmcAA3SW3YpTQRCE3yXXe6T/f3wVEQm6qBBUdFeExXe3zt1M7L0JIakMdWq+rs7L5cvX
X0/ff379eL19+HR9ul7evnu54M3j5e1FSOhgOcQvD5ff19szPuRQZiNzE8o39PfhPzXXqiaKzHL1
olnNi9qDwzIsXGpUk23qTpIIZp6c8CG5qjMo1cy1ZFbTqjbCg2ox96xmXdXFSjDSmjqqKbYEtcOT
LWpS06GrE8vK0CKjtlEtuxNKx+FRr5zNmxPyUk5y6+l26KDeEsSxwS6dUyZQy6pG2l4lpjaoqXeq
HDmndasqj+qNKgtruFERHW7+VK9UWQMV5CJFw1NCfUdVSHEKbnRIkOqQjW8g5caKYHxWb3w7THSG
e8xn8+ZE1HD3CNGGm4eaNr4RSYe4a08J5qF7Js5cEkJjgnmIbQwyi3FbTdMANa9ODOcmkzCsz2ra
Z94FL+cvRjXpHVUphpmfpoHikJVvsFckZWk0OYmDV75N4KLhvWU+m1e+YQPlg1xoah+oaeVbTwAx
N8UVg9oPWZ2gIITPZpNp0k715sTQgJLwQxODfvDmBJmgphShTww6wNrO9j4vVJ1fUa9UwS6YbUdV
TU5sp0oSaKNjqXnKxHaqFC1VjsUD0mf1ShWWE3W5heg087ZTBbgNblIyJie6bxI8nWDIzHJqzVO9
OiFC24fgfJ3uUvdNgkrudCwT7Slv3TcJ13k82tBkmnnZu4oLMnixnnbxqea7vM8p66iJb9m7CnyA
FXL0yTRpsncVlChlLlWZOOG9qwSrDxV01uyUIN9RhUUMqpLwt2NUb1SJcJo0/p9Ez+r1LlEPIU2Y
ofEp+Y4q7zSuRGueVL1/uHx7/PP04cf1M7799ny7/f0HAAD//wMAPTPfo34JAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Tue, 05 Nov 2024 17:50:17 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,798 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/fundamentals?api_key=MOCK_API_KEY&statement_code=income_statement&type=FY
response:
body:
string: !!binary |
H4sIAGU7fWYAA7SWW0/iUBSF/8qkz9Dsc+3pedOozKiAGLwxmRCEOqlAYQoyXuJ/n31qZbS0MW7i
Y/e5wP6yz1rrybu5S0aDaZQsB5OFZ38+efHIs67a378+bJ7fejVvsRwsI7elP5yNIlyNk+FsGvXX
ddxzEy+Gg0n/IRqknuXAxbo0j9J45u48uMJ9y4e5uyGN5rN0GY1ebk+X/RFehXU8yesQ1rnClSgZ
vakLVxeQ/dYkTn6/W2KsDrzLuQVjeeADQA83xov+BDctlp5dpndRzbubu0Nvb5V10HXGu0xayawE
XwPrec+1NxzaaSs6PCdy4B9xyA6XcWAZB73B4YWP/FIOgvma6wKH2WQ1jRSRAyNzgKzfYIMDW8/J
13Fggc9NUODQMbf3exMiB6ByYGHWb7jBAdZzssGB1xkguowDNiO3eRdKqwIH3Rib6waNAwvJHMxa
B95xyPmYMg4s42AyDtJy82kOoovnILCM+yEv6kPvqrk37RA5GDKHwDUFbIODWc/JBgfIOIQZB225
onMQPigocHhMVXSqiRwCMgdd7hfIp8ovcFSQgwDHgXErNF0ntS9N8V1cJS29or4LTeagynUy51Pm
FzgqTidVlwmnD/jIyTqp/EDyAofVvdyftogcFJmDXOvAew6qUifdU0IOossynRRb+AWOUlDk0DFt
fkLMD0ySOYhyv8j5BGUcdKYPusvBSp41s4VfiGJ++HPKVpyYH9iHebKSA6/wC1HpFzgquV8AJiEL
4VbzALLAYTeQqrND5EDOk4xV6CSv9AsclTw/YCfMqs/7xZs8qYwpcLhoi94pEDmQ8ySD8lyd8ynV
SZH7BeA8GEp+WM+D8bko5kmRHu81JZEDOU9CWOEXUJmrWZYnBXPz4EIA/V0431RF3zSm3R5d0zgA
OU+CKfeLnE+pX7D/OikUJUe9csCjXIsCh6PxSkxnRA7kPAlBuU7mfEr9Al71ATlgnmRbzQMvzsP9
lfz754jIgZwnQZfn6hc+5Trp9uOTce+CK6vo+sBDX2Q56lfNwxbng+TBszkS/O63LnXjse3aiIfj
CDv1dnZOjvE7GUzdhTvz+ST69iMZ+libRDGWvl+cnRydQvOkfWYOGpe7XRE6rRnGY1zE/wnCBWLh
PT//AwAA//8DAGe6v00MEgAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:57 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-income_statement-2021-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGY7fWYAA7SYXXPaRhSG/4pGV80UiCSEPpjpBa4dt7YD2HFqJW2HWaRFqBG7sj6IwcN/z1kJ
oRVIQJXEFx6z52h5n33Pnl35VYxiRBwUOt4aO5OZRxCxPeRHYv/vV9FBMZrEyBX7r6LniH0R/p4M
Le16PRJbIkELDGOjAIco9ogrPOAlJgmGUPqMSPNIuAsEKMQkZjPRGPnFeISfE0xsmE9uiTNkxzSE
pF8hMkU+SgOiHWLHi2EoIR6bIokccdMSl8iHKfpdrWfIupT+dKRNq0a9ZN1dWi+F+kem40D5nrqy
ajekURSEdJaKKZR3f67yv6ynG3dZte6/0ygW6Kx+/W1IoLM6nv1oQaTWEjl4Wg+kyIppyCeBhu54
uXb2raiDqZR6njEah9H+4RjP66uL1c0+xjXTIoxzMRxDWWWZYOeYR2y6KJuhNywvuacYXe0khmON
bi1aYHzAvg9CWsI1JiDKF/5JJEnRhIGz8Ihw9RJgEhXuRC7Cu6Eapm1CVKIympaYqXdPMpH1zXB9
UTA94Aij0J7nLJdQSKBvAWoPiEKnGZAsNSaS1ZNE/60efOv9frEVreCqkMSVXJXi8wtPNpvtH7Vr
GGc0ZHf4fLh9CqI/c0FVPDu1ZZogxDF6qUBRmp4usmSYqnkSZuF+/bS+53p0PMfhFkF4K/yytedN
SyC4aAuUZdWglGMcSX1vPk6i9IyTGPdrY+pODzw5C6ZC9bnm9H4i0tT6PF4dbJxxiNuP6CWHKkPs
Cd1RAG02aFMCfyVQh2UOrXGRmYp0eseYFtL4rrYVzzj2m1imEygqetlJDL3ZtpfVnnIaQnEvpDVX
YkMcc6V1B0fkG7gK5MLyfkBJ0dmq9R/ilaHMht6YqrYtsmNUl66CV1pBBQQR9T3IxY5QgXgIU4kQ
U/i9oKR83Wx63zwPpWfpQ1c6btAgjkNvmsRo6mMhpmAYUyl8mAPBnPoODivs4mByUpL4fgmNL73f
fjjas4uH/FXnCXvunDk0WEKVuVi4QJFnZxiRMEri9B0pq68M5uv2CbTEU5Ybpam0dK6mARyUbwdd
/r7zlifL1mBLlc3HbypNl2RFV46Dqeuw1BkyjisUEhAfCbCHMqgdB6ex1guzzouSYvABpk91c7J7
HU2vP/lXU919OGLDpecn7PN5RjhZdpUV29C+GarU1AxDU03ZPG7G00oe82bkNEfsKOmsM0SVv88Q
uVbxi3tv8sd+zb7IL8//y5200o5YxMcPfFKa+qRKWtfUj/t0u+4NVyHXs1E0B7il52DiRFxbO/TL
hlQnz9yt9hHr1O+wTuoYvc2/MEFCHMReWZC/44CxCfWXC9xjCxfDccMSJjZ18O4WMNmNQ87Mi2zk
T1bwOgSHopTei7Mh+GaPsjnffWKcq4DNAOvKHnay2cN4wk40GIcnpbZkthUdIrAI3LicjvfS72Iv
klyo25YhqjwqSl8y4J7RAYM+Q6IXTXxIimAN4jDBsB5BenJyj6ptSWvLyqOswj7oy3pHMXT2KAAG
iKx2CwKfi39UxZ79BbMlHwzGd4XRgyCAYwvOtA6M+diDoT+ePo5vH6T349FH4921dfHYNVU2u/cF
guxU6SqSbHbFzWbzDQAA//8DADYUKoI6EwAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-income_statement-2020-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGY7fWYAA7SYa3PaRhSG/4pGn5opkJXQlZl+wLXj1nYwdpyapO0wi7QIJWKFdSGAh//esxKS
ViABVRJ/8Jhzjpb32ffsRX4VwwhTGwe2uyH2eOpSTC0Xe6HY+/tVtHGExxF2xN6r6NpiT4S/x4OR
dr25F1sixXMCsfsFCXDkUkd4JEtCYwKp5BnRzzJBnljggNCIjeRH2CviIXmJCbVgPKklTrEV+QEU
/QqZCfZwkhCtgNhuBKGYumyIOLTFbUtcYg+G6Mm6okoqSn46aNuqUY9Gd5ejVaH+iek4UL6nrqza
CfwwXAT+NBFTKO/+XOV/jZ5vnGXVvP/uh5HgT+vn34ICf1rHs58tiJRaIptM6oEkzVRV8yTQwBku
N/a+FXUwlVLPM0bjMNo/HONlc3WxvtnHuGZahGEmhmMoqywT5I651PLnZTP0hu0lIcVUtZMY9uj+
duQXGB+I54GQlnBNKIjyhH9ihGRN6NtzlwpXqwWhYeFO6GCSh2qYdgVhicpo2GKmKZ1mopubweai
YHokIcGBNctYLqGRQN8c1B4QBXYzIAk1JDJ0VT5J9GX96I3e7zdbsRVcFZK4lqtSfH7jSWaz9dM1
NM04vSE7g5fD5VMQ/ZkJquLJ1ZZpFgGJ8KoCRW56umiabJxmmTvfPm0euC06mpFgRyC8FX7ZufOm
JVBS7Ao+q6ohKec4kPqt+TiIgbonMR42xsSZHFhyFkyF6nO9UX8i0mT0ebg+WDfDgLSf8CqDKkPs
Cc0pgDYNWj6Fv2JowzKH1rTHdGRKJ0nMEdb4PW2nnWHsb2GpTICo2MlOUujNFr2ZLfljDLJzgTZc
gw1IxDXWHZyPb+AekOnKNgOfFttatfxDujKT2dAZVVek085cOjJZawUVEIS+50ItsYUKxEOYSoTI
h99zn5bvmk0vm+ehqCN94KDjBvWjKHAncYQnHhEiHwxjKoUPMyCY+Z5Nggq7OJiMlMaeV0LjO++3
H4724pABf895Jq4zYw71l9BlDhEucOhaKUYo3MdR8oKU9lcK8233BF6SCasNk1K/dKgmCbIoXw26
/GXnLU+WzsGOKh2PvxroXVWWJPM4mLIJShtDynGFAwriQwHWUAqVc3Aaa70w67woKQYfYPhEN3/+
d7pS/bG/nujO4xEbLl0vZp/PM8JOq6us2KX2zVBQUzNU2ZAl5bgZz2tpyJuR0Ryxo6SzzhBF+i5D
ZKNW8cp5MPlDv2ZdZDfn/+VO0mlHLOLzBz7JTX1CSDKQfNyn2406WAfcno3DGcAtXZtQO+S2tUO/
LCi1s8p8to9Yp3yHdaijm+r2XxghpjZmLyzYy0EgNn4wvqwuPTZzEZw3rGBs+TbJbwHjPA41Uze0
sDdew8sQnIowR3kIvtr12ZjvPjHQ9YKNABPLHrbT0YNozI40iMtIMtvIbMsmZGAWiriMkriWfBd7
jeRScltCbVl/kuUeknqS0gGHPkOhG449KAphEqIgJjAhi+To5B5V2khrS/KTpMBCgBXcUTWVPQqA
C0zX+YTA5+LfVJFrfSVszvv94V3hdH+xgHMLDrUOxDziQuiP54/D20f0fnj/0Xh3Pbp46poKG939
Ckl2rHQZcVfcbrf/AQAA//8DAMWee3U4EwAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-income_statement-2022-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGY7fWYAA7SYXXPaOBSG/4rHV9tZoJa/wMzsBdmk2U1SIGnauN3dYYQtjLdGJv6ggQz/fY9s
bMtgA+u2XDAgHYn30Xt0JPMqhhGmNg5sd0PsycylmFou9kKx/9eraOMITyLsiP1X0bXFvgifJ0NT
v96MxJZI8YJA22hJAhy51BEeyIrQmEBXMkb0s54g71jigNCIzeRH2CvaQ/IcE2rBfKglzrAV+QEE
/Qo9U+zhpEO0AmK7ETTF1GVTxKEtblviCnswRV8xVEXuScmrI21bNeol8+7SfCnUPzIdB8r31JVV
O4EfhsvAnyViCuXKz1X+yXy6cVZV6/67H0aCP6tffwsC/Fkdz35vQaTWEtlkWg8ky4qm6ieBhs54
tbH3raiDqZR6njE6h9H+4RjPm6uL9c0+xjXTIowzMRxDWWWZIHfMpZa/KJvRbZheqCt1e/JJDNsc
3Zp+gfGBeB4IaQnXhIIoT/g7liRZFwb2wqXC1cuS0LBwJ3QwyZtqmHYBYYmq1zDFNMlQTzLRzc1w
c1EwPZCQ4MCaZyyXkEigbwFqD4gCuxkQkhoS6bKGThL9u37wzPf7yVaUgqtCEpdyVYrPTzxkNNs/
GlJU7XRBdobPh9unIPozE1TFk6st0ywDEuGXChS56emCEBTp7kmYhfPt8+aeq9HRnAQ7BOGt8MvO
njctgZKiLPgsqgal3MeR1Nfm4yRtRTm9ce43vakzPTDlLJoK2ee6o/1Mpqn5Zbw+2DrjgLQf8UtG
VabYU5pjAG7aaPkUPsWQiWUQvXmaIUk5iWKYWOfr2k4849gvY6lOoKioZicxus02PjJ2CEchZOdC
2nA5NiQRl1t3cEi+gctAJiyrCD4talu1/kO8MpTR0BvD6J1hzaUjk7VeUAFB6HsuxBJbqEA8hKlE
iHx4X/i0fOFseuM8D0Uzu0NHOm7QIIoCdxpHeOoRIfLBMKZS+DAHgrnv2SSosIuDyUhp7HklND71
fvvhaM8OGfKXnSfiOnPm0GAFWeYQ4QKHrpVihMIojpKnpDS/UphvuxF4RaYsNkxC/dLJmnSQZfl+
oPA3nrc8WboGO6p0Pn5T6TLSDF05DqZuglJlSDmucEBBfCjAHkqhcg5OY60XRp0XJcXgA0yf6OZk
6x2k1Z/962nXeThiw6Xrxez7eUbYaXSVFbuufTNUqakZiqz1kHHcjKc1GvNmZDRH7CjprDNERd9n
CKpV/OLcG/y5X7Mvsuvz/3InybQjFvH9Bz7JDX3SDKmHUO+4T7cbbbgOuJqNwznArVybUDvkytqh
XxaE2llkvtpHrFO/wzqpY2z/gfExtTF7ZsFejgFtk1EwJDef2LpFcNqwgInl2yS/BEzydoiZuaGF
vckanofgTJRkOW+CH3Z9Nue7zwxzvWQzwLKywXY6exBN2IEG7TAStSWjLbMjD9aAa5eTdjX5LfYk
yXUpbQSj5EdZ7ks9uGZ0wJ8vEOiGEw+CQliCKIgJLMcyOTi5oWpb0ttIfkQqbIO+gjq6rLOhALjE
dJ0vCHwv/qmKXOsrYSs+GIzvCp8HyyWcWnCkdaDNIy40/fH0cXz7IL0fjz723l2bF4+KwQgs9yt0
skNFkSW43ojb7fY/AAAA//8DANuT9sg7EwAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-income_statement-2019-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGY7fWYAA7SYa3ObRhSG/wrDp2YqOdwvmukHuXbUxo4sO05N0nY0K1gharRgLoqFx/89Z0Hc
JBAqSfzBY51zdvU++x52F7+wYYSIhQLLSbA1XzoEEdNBbsiO/n5hLRSheYRsdvTCOhY7YuHv+dRQ
JskNO2AJWmOI3fg4QJFDbOYObzCJMaTSMayXZ4Ii4aMAk4jO5EXILeMhfooxMWE+fsAukRl5ART9
CpkFclGaYM0AW04EoZg4dIo4tNjXAbtBLkwxEhSOVyUu/TnjXgct6jnj+sJ4LtXfUx0HyvfU1VXb
gReGfuAtUzGlcvHnKv/LeHhvb5rW/XcvjBhv2b7+JhR4yzae/WxJJLUSWXjRDsQrvKoJnUBTe7ZJ
rH0r2mAapZ5mjFLBGP5wjKfk8nz7fh9jQrUws1xMhaGusk5QOOYQ01vXzVB7tpeuiXo3hWXcXBle
SfERuy7oGDATTECTy/wTc5ygMGNr7RDm8tnHJCzNCW2Ei1AL0q4grEFpPTtMEyS5k4kk76fJecl0
h0OMAnOVs1xAH4G+Nag9IAqsfkA81/eZEXi1k+i/7Z1rfNjvtXInuCwlVTquSfHpfcfr/R4fUZKU
7r7j7OnT4dNTEv2ZC2riKdTWafwAR+i5AUXoe7gooi5ynSxr++vn5LayQ0crHOwImLfMLzt33gwY
gstNwaNVLST1XAWkfWc+DsJrXHeX3Sbawl4ceHISTYPsU82RfybTwvgy2x48ObMAD+/Rc05Vp9hT
WmAAbhY0PQJ/xdCIdRClb5fJqthNohtIqe5qO+0UY38Ty2QCRMNe1kmh9jw1OUnjOyEE+5xLKi02
xVGlta7hhHwDN4FcWL4feKTc2Zr1H+LVofSe1siyICudVBe2gLdKSQUEoec6UIstpgHxEKYRIfLg
99oj9dtm3+vmaSiyoU5t7rhB4ygKnEUcoYWLmcgDw6hK5uMKCFaea+Ggwa4KTE5KYtetoVVb77cf
jvZk42n1qvOAHXtFHRpvoMtszJyj0DEzjJC5iaP0FSnrrwzm624E2uAFrQ3TUq92rqYJ7NdvB2L1
vvO2SpatwY4qm6+2xUkqL4rKcTApCWo7Q8ZxiQIC4kMGnqEMquCoaGz1Qm/zoqYYfIDpU93VN5sz
XW8/+bcL1b47YsOF48b082lGWFl1kxW71L4ZEtfXDFmXFZk/bsbDlp9VzchpjthR09lmiMR/nyFq
q+Jn+1avHvstz0V+ef5f7qSddsSiav7AJ6GfT5IkiYIiH7fpKpGn26CyZaNwBWwbx8LECiu72qFd
JpRaeWWx2Eeck77DOREY/oXxMbEQfWFBboEBsbkyedQWE7psERw2tGBuehYu7gDzIg41Syc0kTvf
wssQtASXXvCzEHyx49E5332mmFufzgCrSgdb2exBNKfnGcRhpDbk9KFIjwlYg0pcp3FBS7+LvkaW
KYEf8hyk7gVhxEkjQTsDf75AoRPOXSgKYQmiIMawHH56blaGSkNOGfLiPYzj1BEPzSzwdCgA+ohs
iwWBz+V/qSLHfMR0xcfj2XXp89j34dCCE+0MYi52IPTHw6fZ1R33YXbzSXs3Mc7vRV2iszuPkKRn
ikjJRPb19fUbAAAA//8DAIUwYXE3EwAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-income_statement-2023-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGY7fWYAA7SYa3PaOBSG/4rHn7azQC3fwJnZD2STZjcXIGna0O7uMMIWxq2RHV9ocIb/3iMD
tgw2Zt02HzJB51i8j96jIzmvYhhhauHAchJiTWYOxdR0sBuKZ/+8ihaO8CTCtnj2KjqWeCbC35PB
WL9KhmJLpHhBYGzokwBHDrWFB7IkNCYQSp8RvV0kyAI+DgiN2ExehN18PCTPMaEmzIda4gybkRdA
0u8QmWIXpwHRDIjlRDAUU4dNEYeWuG6JS+zCFGdKT5F7mpT+dKR1q0K9NL69GL/k6h+ZjgPle+qK
qu3AC0M/8GapmFy58muVfxw/XdvLsnX/0wsjwZtVr78JCd6simc/mhOplUQWmVYDyUhFSrcWaGCP
lom1b0UVTKnU04zROYz2T8d4Ti7PV9f7GFdMizDaieEYiiqLBJljDjW9RdGMbsPyQrqB1F4thjUe
3oy9HOM9cV0Q0hKuCAVRrvBvLEmyLvSthUOFyxef0DB3J7QxyYYqmLYJYYGq17DEVEORa5locj1I
znOmBxISHJjzHcsFFBLoW4DaA6LAagaEpIZEhoHqm8CX1YM7vtsvtrwVXOaSuJIrU3x64SGj2f7R
1J5av30ke/B8uH1yor93gsp4MrVFGj8gEX4pQZGbni4IqYqEamEW9rdPyT3Xo6M5CbYIwlvht609
b1oCJXlb8FhWBUoxxpFU9+bjJG1Nry+z+6Q3tacHppxEUyL7VHe0X8k0HX8erQ62zigg7Uf8sqMq
UuwpzTAAdzNoehT+iqESiyB64zJTuopei2KMsc73ta14xrHfxjY6gaKkm9VidJttfKR31fq9Itvn
UsLV2IBEXG3dwiH5Bi4DO2G7juDRvLeV6z/EK0IZDb0xdMOor7ILWyYrPacCgtBzHcglllCCeAhT
ihB58Hvh0eKFs+mN8zQUbdwd2NJxg/pRFDjTOMJTlwiRB4YxlcL7ORDMPdciQYldHMyOlMauW0Dj
S++Pn472bJMBf9l5Io49Zw71l1BlNhHOceiYG4xQGMZR+pa0qa8NzLftE3hJpiw3TFO9wsmaBohf
vB8o/I3nLU+2WYMt1WY+flNpXVWVFXQcTE2CQmfYcFzigIL4UIA9tIHKODiNlV4YVV4UFIMPMH2q
m5Otd5Beffavpl374YgNF44bs8+nGWFtssus2Ib2zVClpmb0kKylt5sjZjyt0Ig3Y0dzxI6CzipD
VPRjhiiVil/se4M/9yv2xe76/L/cSSvtiEV8/MAnualPmiZ3Nfm4TzeJNlgFXM/G4Rzglo5FqBVy
be3QLxNSrV1mttpHrFN/wDqpY6jr/2CCmFqYvbRgN+OAscnl9Pru4xe2cBEcNyxhYnoWyW4Bk2wc
cmZOaGJ3soIXIjgUJVnJhuCbHY/N+e4T41z5bIaA+F4AzmxmD6IJO9FgHJ6U25LRljWIwCJw4wob
V6T0u9irZCGEUFuSH2X5TOrBPaMDBn2GRCecuJAUwhpEQUxgPfz05OQeVduS3kbyI1JhH8AG7ugS
Yo8CoI/pKlsQ+Jz/qypyzK+ELXm/P7rNje77PhxbcKZ1YMwlDgz99fRhdPMg3Y2GH3rvrsbnj4qh
stmdrxBkpwq8diJDEdfr9XcAAAD//wMAbNgp7jwTAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-calculations-2021-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
9ScAAAD//wMABgIfnmxeAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-calculations-2022-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
AAD//wMAU737rnReAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-calculations-2019-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
AAD//wMA4TwnAndeAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-calculations-2023-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/AAPL-calculations-2020-FY/standardized_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
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
AAD//wMAj6c9f2heAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:58 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,41 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/indices/stock_market/$DJI/historical_data/level?api_key=MOCK_API_KEY&end_date=2024-02-05&page_size=10000&start_date=2024-01-01
response:
body:
string: !!binary |
H4sIAFmCoWYAA3TUPW/bMBAG4L8iEB1t4vgteTOQJRmytF1aFAJjMY0AmUolyo1j5L/3lBQFmVw3
S3xA8l7d+cIe+jmNU3/wQ9v55Nnu+4Xhj8B2TILUW5BbMGzDTn5Y8KWqVQ1cyJfNRyZzZo3mmmQi
Z0Y0vNYfmNiqggkDXFEKcqWt40oQTDZFBUpxbShmizOh4Zo6VBZ5gG64IJnOmKvBctVQTOWsAfOf
uxXpAgheU5WKpjjUKl5Tqs6VtjW35GYuZ9Jabh3F8ticsoLqD2RZbHEZBorkRTrTSN6Q1897wzkh
OJAH5s3hbGO4o74TFJEZabiwFCsys7XiQGVWDAtGa7kgWdEcWmN7U1MARXNohaNH9VAxehiI4UDu
Jt59gR8b1scuPLHdhfUdSnxq5fPp9nmPcj4f78YB3366urnG5+iP625X4+/qZoxhrq5jt8xp6v1Q
7U9h8j8DqsMYUx9DTEhvxyk9VPtjWP9gXteWmKYzrnyNfQpd9TnhDedqvM/Q8rheu72fwq8lxMOq
O98PZ1wa/Jzat/XuX10OJ+0LwE4IHAwOAN9QjndzmE4+9WNs5+Sn9MrFX/4OhFjsptgLFhueUvu4
lvQW1R8AAAD//wMAP3H/JioFAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 24 Jul 2024 22:38:17 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,85 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/insider_transaction_filings?api_key=MOCK_API_KEY&end_date=2023-06-06&page_size=500&sort_by=updated_on&start_date=2023-01-01
response:
body:
string: !!binary |
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
WVIGYwLVAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:06 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,126 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/MSFT/data_point/ceo?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGo7fWYAA1IKTiypTFTwS0xJzclJVAIAAAD//wMAZxmyKw8AAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:02 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/data_point/marketcap?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGo7fWYAAzI2sjS3MLE0tDQxMjXQMwAAAAD//wMANEcZLw8AAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:02 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/data_point/ceo?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGo7fWYAA1IKyczNL8moVHDRU3DOz89WAgAAAP//AwBIpQsVEQAAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:02 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/MSFT/data_point/marketcap?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAGo7fWYAAzI2NrcwNbY0NTIAAj0DAAAAAP//AwC52O5DDwAAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:02 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,39 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/options/unusual_activity/intraday?activity_type=block&api_key=MOCK_API_KEY&end_date=2023-11-21&minimum_total_value=10000000&page_size=1000&sentiment=neutral&source=delayed&start_date=2023-11-20
response:
body:
string: !!binary |
H4sIAGI7fWYAA8zU3U7CMBQA4Hfp9Wj6s7PT7tYXMNFEozFLGQ1ZKN2yHwIS3t0OMVHYAI0X7K5n
p6dnX9ttSVubmW1I+rolzWY5LR1JycP98xOJSFssbdOaZRVCggk54Xwi2COHNIaUAVUSX/q0TWVD
xtSV+aIflq1x2cq4LkR5whBRq69wU7z3UcYiYla2NnObVXWRHzIphsS89KGnvD30kWUiZoInd0xo
YOEJS5hmkZk2s2ubd21R+v1sTTEi02J2+gZoEpHG+v57fF/X2y4s4UKlzs9s7TaFn3/2cTSZUbaL
fgPDdSqBcuCXYETCpMbe4QcMDMBgqKhHYCSHAKMEjMKgVFQNwqCUVN8ejFQxS05OzBAMKE3lWRiN
4zCg+QgMKKTs/2DOu2DKJA1bcdEFJFcA4gqXJPSvj1my7+flDEuiEyqGLxJqCjfHgsA1u4pFybj/
EYyz4JlrpGLRmw6wKLEH+zPLWxTy121WhV5J6jvndh8AAAD//wMAhrSB85YFAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:54 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,38 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/zacks/target_price_consensuses?api_key=MOCK_API_KEY&identifier=AAPL&page_size=10000
response:
body:
string: !!binary |
H4sIAHo7fWYAA1yQX0vDMBTFv8q4z11J/1ht3qboHM6tiMOBSIjppQtrk5Kk6hz77ks2RTBPueeX
nHvu3YPjpkHHeiMFMqGVRWUHixbo6x6cFFs0QGEyqeYQgdBdz9WOKd5hUKtqfjuaLW48kqoerDM7
1hg99EwN3fvpZ1KWnm5kswGaXl7EJIJWfwJNijzcO+TKgySJ8zyJwDquam5qVuOH5E7qAIs4J0UE
TjveAs38s05bxwwKVI7V3IUsKUnzMSnGaQ7BtZZnXxKaGC4t1kDV0Lan9mj+yp+ZgO5BejHUbLEu
pt9Lb/R/Ab+D932Lo5kSsddalF66f1lVD0/ksVquru6m6+vnrAxJhNx6SPzJUpKUGRwOb94Gv/zK
eYPnEIcjAAAA//8DANXI/92HAQAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:18 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,129 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/fundamentals?api_key=MOCK_API_KEY&page_size=10000&reported_only=true&statement_code=cash_flow_statement
response:
body:
string: !!binary |
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
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:10 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/fundamentals/fun_PQ0RrV/reported_financials?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHM7fWYAA7SYW3PaOBSA/4rHz5DxldsbaZJuZtNACWm7u7PDCPs4aGJkV5JpaCb/vUcCG5MY
to7ZzqSAdCSfT+dqPZsc0oRLCGcRZYQFlMTCHPzzbD7NeTyT5MEcPJv6w7wFec2CZAk3iRBmy2Rk
CZthg+pxHJuTGDdRwwGHkEocyhh+DMxMhPiDzIXkJMCBCB8ELVPA9wz0CrtlhpDKhTlwXlrmisQZ
Dvpd33cs/e/MQgG6BCZowlBHlsXxS6tK0QtIOSCJREH8HoP6MmThcImk9Kce3+lfljYICw2yL7ZD
CmFei8gpiNwSUafn1QW6WxAO50RA+CFZprjgFYKeb8+VgBGUJAx4Ut+hEYVbSdHv2HUpRnIB/DZh
ARGLjSNdFuptQbRIMzfyqtS1+93a6qKKHPBIL2Dzec2GQZBkTIoJBEBXZB6XNM/nDF5MtgwGshmM
X8B4O5h2t+t0m9Pos96hlCL6C7Aw4QZLWBsVC6HEJJrxdCp5bMfu1I6Jt0DXbAVMJpyWWfYHG6je
rVTdd09kiFEKHGOWPQyFAClehYQRZJwjh85Pyi7F71y6AVmviszz3N7pImZM1gfCJS1m3p+h+tVe
1clj/oTWuaFkTmMq93zsuInivSXvp7StSkzXc2snAyzZHzAJj3myoiGE5+t7rByIWvhgIOnqFaRa
YDwAUyJYZuZrI8nFDVKWLwjV82vgVdb/juP3/Lp46G0oJsU0GQbfM8phuCI0Vm52lfA7EsMdoHG0
vhcwlzvGccaDBVpdGElkLAl/BKlWGaKQb9jiOFWMjm95tXsctF0AEIorniw/EblVb4zd3BYe+50P
JI7FKDpMXyLfbmdEuB+i5xv+3kHUdmW38hy6XqfROSi4Y7ivjL2HLFDy/6L1qmg9165d8944NjJg
EMr1GHWTaPFLHE2VSAlzu8aIsKQTtUxQ3Rsia7pd3jJStYFOXVDaoomr+9XQvdpVJQdAc5aNrZOu
qu7iUMY6QTNpd6oouk7/RBn3qP5vMy7NxQ9k3Pqu2a3iszt27ZKSW2kCsdJ2mkzJ01cqF4skDlFh
FYv/8RKz56iSPIHqpfVmhkxUK20ItQNGpZQxKFHlwspd5dogPwgPm2bnXmVW6nXfXYBG0QVV9mah
OMAZ5vM69vJfmgqfr8QaMvUrHdh3382ElpxAui2UowhtuUzYnUyCxx3iTkCn1EDLGGIr1ADHsaqz
iuvVz6WlXHItRKZUGkU3CXuYAl8eKxV0K63QJMoaGHXyzcteufvZfD/GVdn81KCZFHX/EMNOYk/v
hvaobGhc26/deJfNUYZR/gVcXUuNSarTeSVPUIjhGwXKvX33rn15U9mjtN1+r1GPUgojXZ+uNrdu
v1vBalNU9h5t260NcaCCHdVfV7BM3UpRZkS55KmKl1PZYrQ7tmXXbjKUpurvcpd4J1hqOQ2w/qgJ
bK72B0qSY+A0Cd++OgZxpmrf5ROmQvYAE6xll1EEQSkq80XqgNS9WEv/X87/ujDw4tF6vtmx7Xoa
uxyz9a8lN5d4U1Wqx4SGtyBfmT7FUV3mNvfDm6p+gmsxp7pt8Xz32C3fvy0zylhIVPyRWGHQEJ+G
Y7PxZ2vCv+BDhUQjKYFZkIRaN+SYRXHyY1ZMoVhERUDi2RoIV0VJRdl2KNW+gAs/O39NL1BUrlO1
T37NvnkGl7MQd8NxXOy2batt2TiDpb807rUtt+1a+nEx+tH+lN+2nKnjDCwPA+EMmf9GQSpmqmMS
eGiSZ3hmWaoWvdq107adqe0NPHvgWWfdnq+WqntjwtbFseDv2e23zsefIwVBg0fMRANzOBzflG5x
0hRfk9ANznAsBopDf3y9H/85sT6NR/e9q4/fzqdu31O700ecVKbBzGP3XfPl5eUXAAAA//8DAJ7W
nNh8GAAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:11 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,48 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/data_tags/search?api_key=MOCK_API_KEY&page_size=1000&query=ebit
response:
body:
string: !!binary |
H4sIAGg7fWYAA9SYa0/bMBSG/0qUT6AxAVVB0G9liSagKxcxSDtNlZOcGrPETm2nlyD++5xek7Qd
mdQm7Uf7xI4f+/Vr+7zrEmGh136968TVa3Gp08Qt3rT0I50iH1SdiTglFAvNhi7joF1TCRyE1BB1
tSc0BKEdmFfXT4eqiWqvWoBNpCoIiST4QGXHYW7ck4M8J/SQJIyKVFyOgjjeJRRRhyBPBQPEVUSv
0dDz1KfQC4E6MCt3kSMZn5Vs5KFEcNqbD5ITR3UVUjWcmh4KV/84SoBWoj59jMoAJdQNhRpdUaQv
o1NjkCRVFNrD8YP2nbOBfE3x9FgPz2rLBpsPZAoWAHdUlwhDmu82OjOGVgF8m1VoXrxn66VJ8QLP
AFtqkmkxplGf07mqWrKY0UU7sHiCeX3VZrTg63oMyTSagSt1b7R1tM2uWy4yho1eP6vJFXrcNzFW
ossf51kv2ShXSSbSxPeDRkKKDUbx1yfgvrZGlJ7cxx2ndHlHi8UsYfepxWw0cEalPxDHhKZU6s+q
yl67gLMukcgmHpGjz8VqRKy95C4b5dvsov0nnonrdxcZkzHqq2zGRftmoCau3rS3zlaaibYGlQRc
E+Q6X6Gwl/6ppNm6wUURlmCdJyP7/sJa0uea67SL9vHBwPEJui2KsRybca27qrtsMyvOCBft6Smh
3kWc4m0jlnvQX1qoBUmlxkmJgBMB2jPyQpjZjnZgPh9nshP9ifPsAHRfDXX8swWwH3qSBF72dYGv
2EXxuJuVcW5aO+oFS3kLRTjPPJnDAKiAlJYlI9MwDHdgaR3WBx7L9l9nSjXib0b20bht0M0uai5O
5Ui3NEfu9GiSTzxSN4eAgxpjDDHOM9Z9xiWJJhUHE0c7zHjZDqz6pynHXmTWz3MkV4ufiYKzzE3r
/M9bVvoNEEL7hgJz+Oku8NSnDgpguI/7/mV0+tjOPsPLgC/BC2yrHVQTiZZ1R5m6scwOs5TA+zv0
Msp9oj1GPkvlXYqELukUV6Z/c5Jg/klBmR242j0Hn4S+0OpCgJxDhtN4MA27624t03F1xCuA7MzD
edF1yaTqIf73eLrmc3B6tpgB/YuemAB9NpZpt+kRrPS634pb7c9OEO+H8Qx+/AUAAP//AwBIw/g6
VhwAAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:00 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,95 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/data_point/weightedavebasicdilutedsharesos/number?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHA7fWYAAzI0NTY2MbAwMjAw0DMAAAAA//8DAB00zBcNAAAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:08 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/data_point/public_float/number?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHA7fWYAAzIytTQ0NDM1AAM9AwAAAAD//wMAWSojCg8AAAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:08 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/AAPL/data_point/adjweightedavebasicdilutedsharesos/number?api_key=MOCK_API_KEY
response:
body:
string: !!binary |
H4sIAHA7fWYAAzI0NTY2MbAwMjAw0DMAAAAA//8DAB00zBcNAAAA
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:14:08 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,362 +0,0 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/news?api_key=MOCK_API_KEY&end_date=2024-01-03&page_size=50&specific_source=yahoo&start_date=2024-01-02
response:
body:
string: !!binary |
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
AAA=
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:48 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/news?api_key=MOCK_API_KEY&end_date=2024-01-03&next_page=MjAyNC0wMS0wMlQyMzowMDoyMC4wMDAwMDArMDAwMHw4NzMzMjUw&page_size=50&specific_source=yahoo&start_date=2024-01-02
response:
body:
string: !!binary |
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
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 27 Jun 2024 10:13:49 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -1,547 +0,0 @@
"""Test Intrinio fetchers."""
from datetime import date
from unittest import mock
import pytest
from openbb_core.app.service.user_service import UserService
from openbb_intrinio.models.balance_sheet import IntrinioBalanceSheetFetcher
from openbb_intrinio.models.calendar_ipo import IntrinioCalendarIpoFetcher
from openbb_intrinio.models.cash_flow import IntrinioCashFlowStatementFetcher
from openbb_intrinio.models.company_filings import IntrinioCompanyFilingsFetcher
from openbb_intrinio.models.company_news import IntrinioCompanyNewsFetcher
from openbb_intrinio.models.currency_pairs import IntrinioCurrencyPairsFetcher
from openbb_intrinio.models.equity_historical import IntrinioEquityHistoricalFetcher
from openbb_intrinio.models.equity_info import IntrinioEquityInfoFetcher
from openbb_intrinio.models.equity_quote import IntrinioEquityQuoteFetcher
from openbb_intrinio.models.equity_search import IntrinioEquitySearchFetcher
from openbb_intrinio.models.etf_holdings import IntrinioEtfHoldingsFetcher
from openbb_intrinio.models.etf_info import IntrinioEtfInfoFetcher
from openbb_intrinio.models.etf_price_performance import (
IntrinioEtfPricePerformanceFetcher,
)
from openbb_intrinio.models.etf_search import IntrinioEtfSearchFetcher
from openbb_intrinio.models.financial_ratios import IntrinioFinancialRatiosFetcher
from openbb_intrinio.models.forward_ebitda_estimates import (
IntrinioForwardEbitdaEstimatesFetcher,
)
from openbb_intrinio.models.forward_eps_estimates import (
IntrinioForwardEpsEstimatesFetcher,
)
from openbb_intrinio.models.forward_pe_estimates import (
IntrinioForwardPeEstimatesFetcher,
)
from openbb_intrinio.models.forward_sales_estimates import (
IntrinioForwardSalesEstimatesFetcher,
)
from openbb_intrinio.models.fred_series import IntrinioFredSeriesFetcher
from openbb_intrinio.models.historical_attributes import (
IntrinioHistoricalAttributesFetcher,
)
from openbb_intrinio.models.historical_dividends import (
IntrinioHistoricalDividendsFetcher,
)
from openbb_intrinio.models.historical_market_cap import (
IntrinioHistoricalMarketCapFetcher,
)
from openbb_intrinio.models.income_statement import IntrinioIncomeStatementFetcher
from openbb_intrinio.models.index_historical import IntrinioIndexHistoricalFetcher
from openbb_intrinio.models.insider_trading import IntrinioInsiderTradingFetcher
# from openbb_intrinio.models.institutional_ownership import (
# IntrinioInstitutionalOwnershipFetcher,
# )
from openbb_intrinio.models.key_metrics import IntrinioKeyMetricsFetcher
from openbb_intrinio.models.latest_attributes import IntrinioLatestAttributesFetcher
from openbb_intrinio.models.market_snapshots import IntrinioMarketSnapshotsFetcher
from openbb_intrinio.models.options_chains import IntrinioOptionsChainsFetcher
from openbb_intrinio.models.options_snapshots import IntrinioOptionsSnapshotsFetcher
from openbb_intrinio.models.options_unusual import IntrinioOptionsUnusualFetcher
from openbb_intrinio.models.price_target_consensus import (
IntrinioPriceTargetConsensusFetcher,
)
from openbb_intrinio.models.reported_financials import IntrinioReportedFinancialsFetcher
from openbb_intrinio.models.search_attributes import (
IntrinioSearchAttributesFetcher,
)
from openbb_intrinio.models.share_statistics import IntrinioShareStatisticsFetcher
from openbb_intrinio.models.world_news import IntrinioWorldNewsFetcher
test_credentials = UserService().default_user_settings.credentials.model_dump(
mode="json"
)
@pytest.fixture(scope="module")
def vcr_config():
"""VCR configuration."""
return {
"filter_headers": [("User-Agent", None)],
"filter_query_parameters": [
("api_key", "MOCK_API_KEY"),
("X-Amz-Algorithm", "MOCK_X-Amz-Algorithm"),
("X-Amz-Credential", "MOCK_X-Amz-Credential"),
("X-Amz-Date", "MOCK_X-Amz-Date"),
("X-Amz-Expires", "MOCK_X-Amz-Expires"),
("X-Amz-SignedHeaders", "MOCK_X-Amz-SignedHeaders"),
("X-Amz-Signature", "MOCK_X-Amz-Signature"),
],
}
@pytest.fixture(autouse=True, scope="module")
def mock_cpu_count():
"""Mock the cpu_count function so recording works."""
with mock.patch(
"os.cpu_count"
) as mock_cpu_count: # pylint: disable=redefined-outer-name
mock_cpu_count.return_value = -3
yield
@pytest.mark.record_http
def test_intrinio_equity_historical_fetcher(credentials=test_credentials):
"""Test equity historical fetcher."""
params = {
"symbol": "AAPL",
"start_date": date(2023, 1, 1),
"end_date": date(2023, 1, 10),
"interval": "1d",
}
fetcher = IntrinioEquityHistoricalFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_currency_pairs_fetcher(credentials=test_credentials):
"""Test currency pairs fetcher."""
params = {}
fetcher = IntrinioCurrencyPairsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_company_news_fetcher(credentials=test_credentials):
"""Test company news fetcher."""
params = {
"symbol": "AAPL",
"limit": 50,
"source": "yahoo",
"start_date": date(2024, 1, 2),
"end_date": date(2024, 1, 3),
}
fetcher = IntrinioCompanyNewsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_world_news_fetcher(credentials=test_credentials):
"""Test world news fetcher."""
params = {
"limit": 50,
"source": "yahoo",
"start_date": date(2024, 1, 2),
"end_date": date(2024, 1, 3),
}
fetcher = IntrinioWorldNewsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_equity_quote_fetcher(credentials=test_credentials):
"""Test equity quote fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioEquityQuoteFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_options_chains_fetcher(credentials=test_credentials):
"""Test options chains fetcher."""
params = {"symbol": "AAPL", "date": date(2023, 9, 15), "delay": "eod"}
fetcher = IntrinioOptionsChainsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_options_unusual_fetcher(credentials=test_credentials):
"""Test options unusual fetcher."""
params = {
"source": "delayed",
"trade_type": "block",
"sentiment": "neutral",
"start_date": date(2023, 11, 20),
"min_value": 10000000,
}
fetcher = IntrinioOptionsUnusualFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_balance_sheet_fetcher(credentials=test_credentials):
"""Test balance sheet fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioBalanceSheetFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_cash_flow_statement_fetcher(credentials=test_credentials):
"""Test cash flow statement fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioCashFlowStatementFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_income_statement_fetcher(credentials=test_credentials):
"""Test income statement fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioIncomeStatementFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_fred_series_fetcher(credentials=test_credentials):
"""Test fred series fetcher."""
params = {
"symbol": "$GDP",
"start_date": date(2022, 9, 20),
"end_date": date(2023, 9, 20),
}
fetcher = IntrinioFredSeriesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_calendar_ipo_fetcher(credentials=test_credentials):
"""Test calendar IPO fetcher."""
params = {"status": "upcoming"}
fetcher = IntrinioCalendarIpoFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_search_attributes(credentials=test_credentials):
"""Test search attributes fetcher."""
params = {"query": "ebit"}
fetcher = IntrinioSearchAttributesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_historical_attributes(credentials=test_credentials):
"""Test historical attributes fetcher."""
params = {
"provider": "intrinio",
"symbol": "AAPL,MSFT",
"tag": "ebit,marketcap",
"frequency": "yearly",
"limit": 1000,
"tag_type": None,
"start_date": date(2013, 1, 1),
"end_date": date(2023, 1, 1),
"sort": "desc",
}
fetcher = IntrinioHistoricalAttributesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_latest_attributes(credentials=test_credentials):
"""Test latest attributes fetcher."""
params = {
"provider": "intrinio",
"symbol": "AAPL,MSFT",
"tag": "ceo,marketcap",
}
fetcher = IntrinioLatestAttributesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_equity_info_fetcher(credentials=test_credentials):
"""Test equity info fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioEquityInfoFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_index_historical_fetcher(credentials=test_credentials):
"""Test index historical fetcher."""
params = {
"symbol": "DJI",
"start_date": date(2024, 1, 1),
"end_date": date(2024, 2, 5),
}
fetcher = IntrinioIndexHistoricalFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_historical_dividends_fetcher(credentials=test_credentials):
"""Test historical dividends fetcher."""
params = {
"symbol": "AAPL",
"start_date": date(2023, 1, 1),
"end_date": date(2023, 6, 6),
}
fetcher = IntrinioHistoricalDividendsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_company_filings_fetcher(credentials=test_credentials):
"""Test company filings fetcher."""
params = {
"symbol": "AAPL",
"form_type": None,
"limit": 100,
"start_date": date(2023, 1, 1),
"end_date": date(2023, 6, 6),
}
fetcher = IntrinioCompanyFilingsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_insider_trading_fetcher(credentials=test_credentials):
"""Test insider trading fetcher."""
params = {
"symbol": "AAPL",
"start_date": date(2023, 1, 1),
"end_date": date(2023, 6, 6),
}
fetcher = IntrinioInsiderTradingFetcher()
result = fetcher.test(params, credentials)
assert result is None
# Disabled due to unreliable Intrinio endpoint
# @pytest.mark.record_http
# def test_intrinio_institutional_ownership_fetcher(credentials=test_credentials):
# params = {"symbol": "AAPL"}
# fetcher = IntrinioInstitutionalOwnershipFetcher()
# result = fetcher.test(params, credentials)
# assert result is None
@pytest.mark.record_http
def test_intrinio_key_metrics_fetcher(credentials=test_credentials):
"""Test key metrics fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioKeyMetricsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_share_statistics_fetcher(credentials=test_credentials):
"""Test share statistics fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioShareStatisticsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_equity_search_fetcher(credentials=test_credentials):
"""Test equity search fetcher."""
params = {"query": "gold", "limit": 100}
fetcher = IntrinioEquitySearchFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_financial_ratios_fetcher(credentials=test_credentials):
"""Test financial ratios fetcher."""
params = {"symbol": "AAPL", "period": "annual", "limit": 2, "use_cache": False}
fetcher = IntrinioFinancialRatiosFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_reported_financials_fetcher(credentials=test_credentials):
"""Test reported financials fetcher."""
params = {
"symbol": "AAPL",
"statement_type": "cash",
"period": "quarter",
"limit": 1,
}
fetcher = IntrinioReportedFinancialsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_etf_search_fetcher(credentials=test_credentials):
"""Test etf search fetcher."""
params = {"query": "factor", "exchange": "bats"}
fetcher = IntrinioEtfSearchFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_etf_info_fetcher(credentials=test_credentials):
"""Test etf info fetcher."""
params = {"symbol": "DJIA,SPY,GOVT"}
fetcher = IntrinioEtfInfoFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_etf_holdings_fetcher(credentials=test_credentials):
"""Test etf holdings fetcher."""
params = {"symbol": "DJIA"}
fetcher = IntrinioEtfHoldingsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_etf_price_performance_fetcher(credentials=test_credentials):
"""Test etf price performance fetcher."""
params = {"symbol": "SPY:US"}
fetcher = IntrinioEtfPricePerformanceFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_market_snapshots_fetcher(credentials=test_credentials):
"""Test market snapshots fetcher."""
params = {"date": date(2022, 6, 30)}
fetcher = IntrinioMarketSnapshotsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_forward_eps_estimates_fetcher(credentials=test_credentials):
"""Test forward EPS estimates fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioForwardEpsEstimatesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_forward_sales_estimates_fetcher(credentials=test_credentials):
"""Test forward sales estimates fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioForwardSalesEstimatesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_price_target_consensus_fetcher(credentials=test_credentials):
"""Test price target consensus fetcher."""
params = {"symbol": "AAPL"}
fetcher = IntrinioPriceTargetConsensusFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_forward_pe_fetcher(credentials=test_credentials):
"""Test forward pe fetcher."""
params = {"symbol": "AAPL,MSFT"}
fetcher = IntrinioForwardPeEstimatesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_forward_ebitda_fetcher(credentials=test_credentials):
"""Test forward ebitda fetcher."""
params = {"symbol": "AAPL,MSFT"}
fetcher = IntrinioForwardEbitdaEstimatesFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.skip(reason="HTTP request is too large and unreasonable to store.")
def test_intrinio_options_snapshots(credentials=test_credentials):
"""Test options snapshots fetcher."""
params = {"date": "2024-06-11"}
fetcher = IntrinioOptionsSnapshotsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_historical_market_cap(credentials=test_credentials):
"""Test options snapshots fetcher."""
params = {
"symbol": "AAPL,MSFT",
"start_date": date(2020, 1, 1),
"end_date": date(2020, 12, 31),
"interval": "week",
}
fetcher = IntrinioHistoricalMarketCapFetcher()
result = fetcher.test(params, credentials)
assert result is None