Skip to content

Commit

Permalink
Seprate Intrinio financials data tags into a different command (#5723)
Browse files Browse the repository at this point in the history
* add `ebit` field in income statement standard model

* only add required data tags

* remove calculations data

* use `name` key instead of `tag` key

* set `period` as required in data

* remove `period` and `cik` from provider models

* add `equity/fundamental/search_financial_attributes` with tests

* clean descriptions file

* add `equity/fundamental/financial_attributes` with tests

* set `value` as `Optional`
  • Loading branch information
the-praxs authored and piiq committed Nov 17, 2023
1 parent 6aff23b commit 0a9ebfb
Show file tree
Hide file tree
Showing 18 changed files with 505 additions and 43 deletions.
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

0 comments on commit 0a9ebfb

Please sign in to comment.