Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seprate Intrinio financials data tags into a different command #5723

Merged
merged 11 commits into from
Nov 14, 2023
48 changes: 47 additions & 1 deletion openbb_platform/extensions/equity/integration/test_equity_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ def test_equity_news(params, headers):

@pytest.mark.parametrize(
"params",
[({"symbol": "AAPL", "limit": 100})],
[({"symbol": "AAPL", "limit": 100, "provider": "fmp"})],
)
@pytest.mark.integration
def test_equity_fundamental_multiples(params, headers):
Expand All @@ -977,6 +977,52 @@ def test_equity_fundamental_multiples(params, headers):
assert result.status_code == 200


@pytest.mark.parametrize(
"params",
[
({"query": "ebit", "limit": 100, "provider": "intrinio"}),
],
)
@pytest.mark.integration
def test_equity_fundamental_search_financial_attributes(params, obb):
params = {p: v for p, v in params.items() if v}

query_str = get_querystring(params, [])
url = f"http://0.0.0.0:8000/api/v1/equity/fundamental/search_financial_attributes?{query_str}"
result = requests.get(url, headers=headers, timeout=10)
assert isinstance(result, requests.Response)
assert result.status_code == 200


@pytest.mark.parametrize(
"params",
[
(
{
"provider": "intrinio",
"symbol": "AAPL",
"tag": "ebit",
"period": "annual",
"limit": 1000,
"type": None,
"start_date": "2013-01-01",
"end_date": "2023-01-01",
"sort": "desc",
}
),
],
)
@pytest.mark.integration
def test_equity_fundamental_financial_attributes(params, obb):
params = {p: v for p, v in params.items() if v}

query_str = get_querystring(params, [])
url = f"http://0.0.0.0:8000/api/v1/equity/fundamental/financial_attributes?{query_str}"
result = requests.get(url, headers=headers, timeout=10)
assert isinstance(result, requests.Response)
assert result.status_code == 200


@pytest.mark.parametrize(
"params",
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ def test_equity_news(params, obb):
@pytest.mark.parametrize(
"params",
[
({"symbol": "AAPL", "limit": 100}),
({"symbol": "AAPL", "limit": 100, "provider": "fmp"}),
],
)
@pytest.mark.integration
Expand All @@ -905,6 +905,46 @@ def test_equity_fundamental_multiples(params, obb):
assert len(result.results) > 0


@pytest.mark.parametrize(
"params",
[
({"query": "ebit", "limit": 100, "provider": "intrinio"}),
],
)
@pytest.mark.integration
def test_equity_fundamental_search_financial_attributes(params, obb):
result = obb.equity.fundamental.search_financial_attributes(**params)
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0


@pytest.mark.parametrize(
"params",
[
(
{
"provider": "intrinio",
"symbol": "AAPL",
"tag": "ebit",
"period": "annual",
"limit": 1000,
"type": None,
"start_date": "2013-01-01",
"end_date": "2023-01-01",
"sort": "desc",
}
),
],
)
@pytest.mark.integration
def test_equity_fundamental_financial_attributes(params, obb):
result = obb.equity.fundamental.financial_attributes(**params)
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0


@pytest.mark.parametrize(
"params",
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,28 @@ def employee_count(
return OBBject(results=Query(**locals()).execute())


@router.command(model="SearchFinancialAttributes")
def search_financial_attributes(
cc: CommandContext,
provider_choices: ProviderChoices,
standard_params: StandardParams,
extra_params: ExtraParams,
) -> OBBject[BaseModel]:
"""Search financial attributes for financial statements."""
return OBBject(results=Query(**locals()).execute())


@router.command(model="FinancialAttributes")
def financial_attributes(
cc: CommandContext,
provider_choices: ProviderChoices,
standard_params: StandardParams,
extra_params: ExtraParams,
) -> OBBject[BaseModel]:
"""Fetch the value of financial attributes for a selected company and fiscal period."""
return OBBject(results=Query(**locals()).execute())


@router.command(model="IncomeStatement")
def income(
cc: CommandContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ class BalanceSheetData(Data):
accepted_date: Optional[datetime] = Field(
default=None, description="Accepted date."
)
period: Optional[str] = Field(
default=None, description="Reporting period of the statement."
)
period: str = Field(default=None, description="Reporting period of the statement.")

cash_and_cash_equivalents: Optional[StrictFloat] = Field(
default=None, description="Cash and cash equivalents"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ class CashFlowStatementData(Data):
default=None, description=DATA_DESCRIPTIONS.get("symbol", "")
)
date: dateType = Field(description=DATA_DESCRIPTIONS.get("date" ""))
period: Optional[str] = Field(
default=None, description="Reporting period of the statement."
)
period: str = Field(default=None, description="Reporting period of the statement.")
cik: Optional[str] = Field(
default=None, description="Central Index Key (CIK) of the company."
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Financial Attributes standard model."""

from datetime import date as dateType
from typing import Literal, Optional

from pydantic import Field

from openbb_provider.abstract.data import Data
from openbb_provider.abstract.query_params import QueryParams
from openbb_provider.utils.descriptions import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS


class FinancialAttributesQueryParams(QueryParams):
"""Financial Attributes Query."""

symbol: str = Field(description=QUERY_DESCRIPTIONS.get("symbol"))
tag: str = Field(description=QUERY_DESCRIPTIONS.get("tag"))
period: Optional[Literal["annual", "quarter"]] = Field(
default="annual", description=QUERY_DESCRIPTIONS.get("period")
)
limit: Optional[int] = Field(
default=1000, description=QUERY_DESCRIPTIONS.get("limit")
)
type: Optional[str] = Field(
default=None, description="Filter by type, when applicable."
)
start_date: Optional[dateType] = Field(
default=None, description=QUERY_DESCRIPTIONS.get("start_date")
)
end_date: Optional[dateType] = Field(
default=None, description=QUERY_DESCRIPTIONS.get("end_date")
)
sort: Optional[Literal["asc", "desc"]] = Field(
default="desc", description="Sort order."
)


class FinancialAttributesData(Data):
"""Financial Attributes Data."""

date: dateType = Field(description=DATA_DESCRIPTIONS.get("date"))
value: Optional[float] = Field(default=None, description="The value of the data.")
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ class IncomeStatementData(Data):
description=DATA_DESCRIPTIONS.get("date", "")
+ " In this case, the date of the income statement."
)
period: Optional[str] = Field(
default=None, description="Period of the income statement."
)
period: str = Field(default=None, description="Period of the income statement.")
cik: Optional[str] = Field(default=None, description="Central Index Key.")

revenue: Optional[StrictFloat] = Field(default=None, description="Revenue.")
Expand Down Expand Up @@ -95,6 +93,10 @@ class IncomeStatementData(Data):
depreciation_and_amortization: Optional[StrictFloat] = Field(
default=None, description="Depreciation and amortization."
)
ebit: Optional[StrictFloat] = Field(
default=None,
description="Earnings before interest, and taxes.",
)
ebitda: Optional[StrictFloat] = Field(
default=None,
description="Earnings before interest, taxes, depreciation and amortization.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""Search Financial Attributes standard model."""

from typing import Optional

from pydantic import Field

from openbb_provider.abstract.data import Data
from openbb_provider.abstract.query_params import QueryParams
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS


class SearchFinancialAttributesQueryParams(QueryParams):
"""Search Financial Attributes Query."""

query: str = Field(description="Query to search for.")
limit: Optional[int] = Field(
default=1000, description=QUERY_DESCRIPTIONS.get("limit")
)


class SearchFinancialAttributesData(Data):
"""Search Financial Attributes Data."""

id: str = Field(description="ID of the financial attribute.")
name: str = Field(description="Name of the financial attribute.")
tag: str = Field(description="Tag of the financial attribute.")
statement_code: str = Field(description="Code of the financial statement.")
statement_type: Optional[str] = Field(
default=None, description="Type of the financial statement."
)
parent_name: Optional[str] = Field(
default=None, description="Parent's name of the financial attribute."
)
sequence: Optional[int] = Field(
default=None, description="Sequence of the financial statement."
)
factor: Optional[str] = Field(
default=None, description="Unit of the financial attribute."
)
transaction: Optional[str] = Field(
default=None,
description="Transaction type (credit/debit) of the financial attribute.",
)
type: Optional[str] = Field(
default=None, description="Type of the financial attribute."
)
unit: Optional[str] = Field(
default=None, description="Unit of the financial attribute."
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
"start_date": "Start date of the data, in YYYY-MM-DD format.",
"end_date": "End date of the data, in YYYY-MM-DD format.",
"interval": "Time interval of the data to return.",
# "weekly": "Whether to return weekly data.",
# "monthly": "Whether to return monthly data.",
"period": "Time period of the data to return.",
"date": "A specific date to get data for.",
"limit": "The number of data entries to return.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@
from openbb_intrinio.models.currency_pairs import IntrinioCurrencyPairsFetcher
from openbb_intrinio.models.equity_historical import IntrinioEquityHistoricalFetcher
from openbb_intrinio.models.equity_quote import IntrinioEquityQuoteFetcher
from openbb_intrinio.models.financial_attributes import (
IntrinioFinancialAttributesFetcher,
)
from openbb_intrinio.models.fred_indices import IntrinioFredIndicesFetcher
from openbb_intrinio.models.global_news import IntrinioGlobalNewsFetcher
from openbb_intrinio.models.income_statement import IntrinioIncomeStatementFetcher
from openbb_intrinio.models.options_chains import IntrinioOptionsChainsFetcher
from openbb_intrinio.models.options_unusual import IntrinioOptionsUnusualFetcher
from openbb_intrinio.models.search_financial_attributes import (
IntrinioSearchFinancialAttributesFetcher,
)
from openbb_provider.abstract.provider import Provider

intrinio_provider = Provider(
Expand All @@ -28,10 +34,12 @@
"CurrencyPairs": IntrinioCurrencyPairsFetcher,
"EquityHistorical": IntrinioEquityHistoricalFetcher,
"EquityQuote": IntrinioEquityQuoteFetcher,
"FinancialAttributes": IntrinioFinancialAttributesFetcher,
"FredIndices": IntrinioFredIndicesFetcher,
"GlobalNews": IntrinioGlobalNewsFetcher,
"IncomeStatement": IntrinioIncomeStatementFetcher,
"OptionsChains": IntrinioOptionsChainsFetcher,
"OptionsUnusual": IntrinioOptionsUnusualFetcher,
"SearchFinancialAttributes": IntrinioSearchFinancialAttributesFetcher,
},
)
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,16 @@ def extract_data(

def get_financial_statement_data(period: str, data: List[Dict]) -> None:
statement_data: Dict = {}
calculations_data: Dict = {}

intrinio_id = f"{query.symbol}-{statement_code}-{period}"
statement_url = f"{base_url}/fundamentals/{intrinio_id}/standardized_financials?api_key={api_key}"
statement_data = get_data_one(statement_url, **kwargs)

intrinio_id = f"{query.symbol}-calculations-{period}"
calculations_url = f"{base_url}/fundamentals/{intrinio_id}/standardized_financials?api_key={api_key}"
calculations_data = get_data_one(calculations_url, **kwargs)

data.append(
{
"date": statement_data["fundamental"]["end_date"],
"period": statement_data["fundamental"]["fiscal_period"],
"cik": statement_data["fundamental"]["company"]["cik"],
"symbol": statement_data["fundamental"]["company"]["ticker"],
"financials": statement_data["standardized_financials"]
+ calculations_data["standardized_financials"],
"financials": statement_data["standardized_financials"],
}
)

Expand All @@ -122,13 +114,11 @@ def transform_data(
sub_dict: Dict[str, Any] = {}

for sub_item in item["financials"]:
field_name = alias_generators.to_snake(sub_item["data_tag"]["tag"])
field_name = alias_generators.to_snake(sub_item["data_tag"]["name"])
sub_dict[field_name] = float(sub_item["value"])

sub_dict["date"] = item["date"]
sub_dict["period"] = item["period"]
sub_dict["cik"] = item["cik"]
sub_dict["symbol"] = item["symbol"]

# Intrinio does not return Q4 data but FY data instead
if query.period == "quarter" and item["period"] == "FY":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,16 @@ def extract_data(

def get_financial_statement_data(period: str, data: List[Dict]) -> None:
statement_data: Dict = {}
calculations_data: Dict = {}

intrinio_id = f"{query.symbol}-{statement_code}-{period}"
statement_url = f"{base_url}/fundamentals/{intrinio_id}/standardized_financials?api_key={api_key}"
statement_data = get_data_one(statement_url, **kwargs)

intrinio_id = f"{query.symbol}-calculations-{period}"
calculations_url = f"{base_url}/fundamentals/{intrinio_id}/standardized_financials?api_key={api_key}"
calculations_data = get_data_one(calculations_url, **kwargs)

data.append(
{
"date": statement_data["fundamental"]["end_date"],
"period": statement_data["fundamental"]["fiscal_period"],
"cik": statement_data["fundamental"]["company"]["cik"],
"symbol": statement_data["fundamental"]["company"]["ticker"],
"financials": statement_data["standardized_financials"]
+ calculations_data["standardized_financials"],
"financials": statement_data["standardized_financials"],
}
)

Expand All @@ -143,8 +135,6 @@ def transform_data(

sub_dict["date"] = item["date"]
sub_dict["period"] = item["period"]
sub_dict["cik"] = item["cik"]
sub_dict["symbol"] = item["symbol"]

# Intrinio does not return Q4 data but FY data instead
if query.period == "quarter" and item["period"] == "FY":
Expand Down
Loading
Loading