From 0fe94cbfc7629b65109e8a729ad2313e714aa687 Mon Sep 17 00:00:00 2001 From: Diogo Sousa Date: Wed, 2 Aug 2023 01:09:39 +0100 Subject: [PATCH] refactor income statement --- .../fmp/openbb_fmp/models/income_statement.py | 97 ++++------- .../openbb_polygon/models/income_statement.py | 137 +++++++--------- .../polygon/openbb_polygon/utils/types.py | 36 ++-- .../app/static/package/stocks_fa.py | 114 ++++++------- .../models/income_statement.py | 155 +++++++----------- 5 files changed, 221 insertions(+), 318 deletions(-) diff --git a/openbb_sdk/providers/fmp/openbb_fmp/models/income_statement.py b/openbb_sdk/providers/fmp/openbb_fmp/models/income_statement.py index d8bbad249b9..e968dd7f282 100644 --- a/openbb_sdk/providers/fmp/openbb_fmp/models/income_statement.py +++ b/openbb_sdk/providers/fmp/openbb_fmp/models/income_statement.py @@ -1,15 +1,9 @@ """FMP Income Statement Fetcher.""" -from datetime import ( - date as dateType, - datetime, -) from typing import Any, Dict, List, Literal, Optional -from openbb_provider.abstract.data import Data from openbb_provider.abstract.fetcher import Fetcher -from openbb_provider.abstract.query_params import QueryParams from openbb_provider.models.income_statement import ( IncomeStatementData, IncomeStatementQueryParams, @@ -21,27 +15,18 @@ from openbb_fmp.utils.helpers import create_url, get_data_many PeriodType = Literal["annual", "quarter"] -class FMPIncomeStatementQueryParams(QueryParams): +class FMPIncomeStatementQueryParams(IncomeStatementQueryParams): """FMP Income Statement QueryParams. Source: https://financialmodelingprep.com/developer/docs/#Income-Statement - - Parameter - --------- - symbol : Optional[str] - The symbol of the company if no CIK is provided. - cik : Optional[str] - The CIK of the company if no symbol is provided. - period : Literal["annual", "quarter"] - The period of the income statement. Default is "annual". - limit : Optional[NonNegativeInt] - The limit of the income statement. """ - symbol: Optional[str] - cik: Optional[str] - period: PeriodType = Field(default="annual") - limit: Optional[NonNegativeInt] + cik: Optional[str] = Field( + description="The CIK of the company if no symbol is provided." + ) + limit: Optional[NonNegativeInt] = Field( + default=1, description="The limit of the income statement." + ) @root_validator() def check_symbol_or_cik(cls, values): # pylint: disable=no-self-argument @@ -50,47 +35,39 @@ class FMPIncomeStatementQueryParams(QueryParams): return values -class FMPIncomeStatementData(Data): - date: dateType - symbol: str - reportedCurrency: str = Field(alias="currency") - cik: Optional[int] - fillingDate: Optional[dateType] = Field(alias="filing_date") - acceptedDate: Optional[datetime] +class FMPIncomeStatementData(IncomeStatementData): + class Config: + fields = { + "currency": "reportedCurrency", + "filing_date": "fillingDate", + "accepted_date": "acceptedDate", + "cost_of_revenue": "costOfRevenue", + "gross_profit": "grossProfit", + "research_and_development_expenses": "researchAndDevelopmentExpenses", + "general_and_administrative_expenses": "generalAndAdministrativeExpenses", + "selling_and_marketing_expenses": "sellingAndMarketingExpenses", + "selling_general_and_administrative_expenses": "sellingGeneralAndAdministrativeExpenses", + "other_expenses": "otherExpenses", + "operating_expenses": "operatingExpenses", + "depreciation_and_amortization": "depreciationAndAmortization", + "operating_income": "operatingIncome", + "interest_income": "interestIncome", + "interest_expense": "interestExpense", + "total_other_income_expenses_net": "totalOtherIncomeExpensesNet", + "income_before_tax": "incomeBeforeTax", + "income_tax_expense": "incomeTaxExpense", + "net_income": "netIncome", + "eps_diluted": "epsdiluted", + "weighted_average_shares_outstanding": "weightedAverageShsOut", + "weighted_average_shares_outstanding_dil": "weightedAverageShsOutDil", + } + calendarYear: Optional[int] - period: Optional[str] - revenue: Optional[int] - costOfRevenue: Optional[int] - grossProfit: Optional[int] grossProfitRatio: Optional[float] - researchAndDevelopmentExpenses: Optional[int] - generalAndAdministrativeExpenses: Optional[int] - sellingAndMarketingExpenses: Optional[int] - sellingGeneralAndAdministrativeExpenses: Optional[int] - otherExpenses: Optional[int] - operatingExpenses: Optional[int] - costAndExpenses: Optional[int] - interestIncome: Optional[int] - interestExpense: Optional[int] - depreciationAndAmortization: Optional[int] - ebitda: Optional[int] ebitdaratio: Optional[float] - operatingIncome: Optional[int] operatingIncomeRatio: Optional[float] - totalOtherIncomeExpensesNet: Optional[int] - incomeBeforeTax: Optional[int] incomeBeforeTaxRatio: Optional[float] - incomeTaxExpense: Optional[int] - netIncome: Optional[int] netIncomeRatio: Optional[float] - eps: Optional[float] - epsdiluted: Optional[float] = Field(alias="eps_diluted") - weightedAverageShsOut: Optional[int] = Field( - alias="weighted_average_shares_outstanding" - ) - weightedAverageShsOutDil: Optional[int] = Field( - alias="weighted_average_shares_outstanding_dil" - ) link: Optional[str] finalLink: Optional[str] @@ -105,11 +82,7 @@ class FMPIncomeStatementFetcher( ): @staticmethod def transform_query(params: Dict[str, Any]) -> FMPIncomeStatementQueryParams: - transformed_params = params - transformed_params["period"] = ( - "annual" if params.get("period", "") == "annually" else "quarter" - ) - return FMPIncomeStatementQueryParams(**transformed_params) + return FMPIncomeStatementQueryParams(**params) @staticmethod def extract_data( diff --git a/openbb_sdk/providers/polygon/openbb_polygon/models/income_statement.py b/openbb_sdk/providers/polygon/openbb_polygon/models/income_statement.py index c007bf596f7..f5dd8a43b6d 100644 --- a/openbb_sdk/providers/polygon/openbb_polygon/models/income_statement.py +++ b/openbb_sdk/providers/polygon/openbb_polygon/models/income_statement.py @@ -1,56 +1,63 @@ from datetime import ( date as dateType, - datetime, ) -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional -from openbb_provider.abstract.data import Data from openbb_provider.abstract.fetcher import Fetcher -from openbb_provider.helpers import data_transformer, get_querystring +from openbb_provider.helpers import get_querystring from openbb_provider.models.income_statement import ( IncomeStatementData, IncomeStatementQueryParams, ) -from pydantic import Field +from pydantic import validator from openbb_polygon.utils.helpers import get_data from openbb_polygon.utils.types import PolygonFundamentalQueryParams class PolygonIncomeStatementQueryParams(PolygonFundamentalQueryParams): - __doc__ = PolygonFundamentalQueryParams.__doc__ + """Polygon Income Statement Query Parameters""" -class PolygonIncomeStatementData(Data): - start_date: dateType = Field(alias="date") - tickers: Optional[List[str]] +class PolygonIncomeStatementData(IncomeStatementData): + class Config: + fields = { + "date": "start_date", + "accepted_date": "acceptance_datetime", + "period": "fiscal_period", + "revenue": "revenues", + "operating_income": "operating_income_loss", + "income_before_tax": "income_loss_from_continuing_operations_before_tax", + "income_tax_expense": "income_tax_expense_benefit", + "net_income": "net_income_loss", + "eps": "basic_earnings_per_share", + "eps_diluted": "diluted_earnings_per_share", + "interest_expense": "interest_expense_operating", + "symbol": "tickers", + } + + # tickers: Optional[List[str]] cik: Optional[str] filing_date: Optional[dateType] - acceptance_datetime: Optional[datetime] = Field(alias="accepted_date") - fiscal_period: Optional[str] = Field(alias="period") - revenues: Optional[float] = Field(alias="revenue") cost_of_revenue: Optional[float] gross_profit: Optional[float] operating_expenses: Optional[float] - income_loss_from_continuing_operations_before_tax: Optional[float] = Field( - alias="income_before_tax" - ) income_loss_from_continuing_operations_after_tax: Optional[float] - income_tax_expense_benefit: Optional[float] = Field(alias="income_tax_expense") - net_income_loss: Optional[float] = Field(alias="net_income") - basic_earnings_per_share: Optional[float] = Field(alias="eps") - diluted_earnings_per_share: Optional[float] = Field(alias="eps_diluted") benefits_costs_expenses: Optional[float] - interest_expense_operating: Optional[float] = Field(alias="interest_expense") net_income_loss_attributable_to_noncontrolling_interest: Optional[int] net_income_loss_attributable_to_parent: Optional[float] net_income_loss_available_to_common_stockholders_basic: Optional[float] - operating_income_loss: Optional[float] participating_securities_distributed_and_undistributed_earnings_loss_basic: Optional[ float ] preferred_stock_dividends_and_other_adjustments: Optional[float] + @validator("symbol", pre=True, check_fields=False) + def symbol_from_tickers(cls, v): + if isinstance(v, list): + return ",".join(v) + return v + class PolygonIncomeStatementFetcher( Fetcher[ @@ -61,13 +68,8 @@ class PolygonIncomeStatementFetcher( ] ): @staticmethod - def transform_query( - query: IncomeStatementQueryParams, extra_params: Optional[Dict] = None - ) -> PolygonIncomeStatementQueryParams: - period = "annual" if query.period == "annually" else "quarterly" - return PolygonIncomeStatementQueryParams( - symbol=query.symbol, period=period, **extra_params if extra_params else {} # type: ignore - ) + def transform_query(params: Dict[str, Any]) -> PolygonIncomeStatementQueryParams: + return PolygonIncomeStatementQueryParams(**params) @staticmethod def extract_data( @@ -75,6 +77,8 @@ class PolygonIncomeStatementFetcher( ) -> List[PolygonIncomeStatementData]: api_key = credentials.get("polygon_api_key") if credentials else "" + query.period = "annual" if query.period == "annually" else "quarter" + base_url = "https://api.polygon.io/vX/reference/financials" query_string = get_querystring(query.dict(by_alias=True), []) request_url = f"{base_url}?{query_string}&apiKey={api_key}" @@ -91,53 +95,33 @@ class PolygonIncomeStatementFetcher( new["fiscal_period"] = item["fiscal_period"] new["tickers"] = item["tickers"] new["cik"] = item["cik"] - incs = item["financials"]["income_statement"] - new["revenues"] = incs["revenues"].get("value") - new["cost_of_revenue"] = incs.get("cost_of_revenue", {}).get("value", 0) - new["gross_profit"] = incs.get("gross_profit", {}).get("value", 0) - new["operating_expenses"] = incs["operating_expenses"].get("value") - new["income_loss_from_continuing_operations_before_tax"] = incs[ - "income_loss_from_continuing_operations_before_tax" - ].get("value") - new["income_tax_expense_benefit"] = incs["income_tax_expense_benefit"].get( - "value" - ) - new["net_income_loss"] = incs["net_income_loss"].get("value") - new["basic_earnings_per_share"] = incs.get( - "basic_earnings_per_share", {} - ).get("value") - new["diluted_earnings_per_share"] = incs.get( - "diluted_earnings_per_share", {} - ).get("value") - new["net_income_loss_attributable_to_noncontrolling_interest"] = incs[ - "net_income_loss_attributable_to_noncontrolling_interest" - ].get("value") - new["net_income_loss_attributable_to_parent"] = incs[ - "net_income_loss_attributable_to_parent" - ].get("value") - new["net_income_loss_available_to_common_stockholders_basic"] = incs[ - "net_income_loss_available_to_common_stockholders_basic" - ].get("value") - new["operating_income_loss"] = incs["operating_income_loss"].get("value") - new[ - "participating_securities_distributed_and_undistributed_earnings_loss_basic" - ] = incs[ - "participating_securities_distributed_and_undistributed_earnings_loss_basic" - ].get( - "value" - ) - new["preferred_stock_dividends_and_other_adjustments"] = incs[ - "preferred_stock_dividends_and_other_adjustments" - ].get("value") - new["income_loss_from_continuing_operations_after_tax"] = incs[ - "income_loss_from_continuing_operations_after_tax" - ].get("value") - new["benefits_costs_expenses"] = incs["benefits_costs_expenses"].get( - "value" - ) - new["interest_expense_operating"] = incs.get( - "interest_expense_operating", {} - ).get("value", 0) + incs = item["financials"].get("income_statement", {}) + + FIELDS = [ + "revenues", + "cost_of_revenue", + "gross_profit", + "operating_expenses" + "income_loss_from_continuing_operations_before_tax", + "income_tax_expense_benefit", + "net_income_loss", + "basic_earnings_per_share", + "diluted_earnings_per_share", + "net_income_loss_attributable_to_noncontrolling_interest", + "net_income_loss_attributable_to_parent", + "net_income_loss_available_to_common_stockholders_basic", + "operating_income_loss", + "participating_securities_distributed_and_undistributed_earnings_loss_basic", + "preferred_stock_dividends_and_other_adjustments", + "income_loss_from_continuing_operations_after_tax", + "benefits_costs_expenses", + "interest_expense_operating", + ] + + if incs: + for field in FIELDS: + new[field] = incs.get(field, {}).get("value", 0) + to_return.append(PolygonIncomeStatementData(**new)) return to_return @@ -145,5 +129,4 @@ class PolygonIncomeStatementFetcher( def transform_data( data: List[PolygonIncomeStatementData], ) -> List[IncomeStatementData]: - processors = {"tickers": lambda x: "" if not x else ",".join(x)} - return data_transformer(data, IncomeStatementData, processors) + return data diff --git a/openbb_sdk/providers/polygon/openbb_polygon/utils/types.py b/openbb_sdk/providers/polygon/openbb_polygon/utils/types.py index ed73f8ab08d..875f12019fe 100644 --- a/openbb_sdk/providers/polygon/openbb_polygon/utils/types.py +++ b/openbb_sdk/providers/polygon/openbb_polygon/utils/types.py @@ -7,7 +7,8 @@ from typing import Literal, Optional, Union from openbb_provider.abstract.data import Data from openbb_provider.abstract.query_params import QueryParams -from pydantic import Field, PositiveFloat, PositiveInt, validator +from openbb_provider.models.income_statement import IncomeStatementQueryParams +from pydantic import Field, NonNegativeInt, PositiveFloat, PositiveInt, validator class Timespan(str, Enum): @@ -20,21 +21,25 @@ class Timespan(str, Enum): year = "year" -class PolygonFundamentalQueryParams(QueryParams): +class PolygonFundamentalQueryParams(IncomeStatementQueryParams): """Polygon Fundamental QueryParams. Source: https://polygon.io/docs/stocks#!/get_vx_reference_financials """ - ticker: Optional[str] = Field( - alias="symbol", description="The symbol of the company if no CIK is provided." - ) - cik: Optional[str] = Field( - description="The CIK of the company if no symbol is provided." + class Config: + fields = { + "symbol": "ticker", + "period": "timeframe", + } + + limit: Optional[NonNegativeInt] = Field( + default=1, description="The limit of the income statement." ) + company_name: Optional[str] = Field(description="The name of the company.") company_name_search: Optional[str] = Field( - alias="company_name.search", description="The name of the company to search." + description="The name of the company to search." ) sic: Optional[str] = Field( description="The Standard Industrial Classification (SIC) of the company." @@ -43,51 +48,38 @@ class PolygonFundamentalQueryParams(QueryParams): description="The filing date of the financial statement." ) filing_date_lt: Optional[date] = Field( - alias="filing_date.lt", description="The filing date less than the given date." + description="The filing date less than the given date." ) filing_date_lte: Optional[date] = Field( - alias="filing_date.lte", description="The filing date less than or equal to the given date.", ) filing_date_gt: Optional[date] = Field( - alias="filing_date.gt", description="The filing date greater than the given date.", ) filing_date_gte: Optional[date] = Field( - alias="filing_date.gte", description="The filing date greater than or equal to the given date.", ) period_of_report_date: Optional[date] = Field( description="The period of report date of the financial statement." ) period_of_report_date_lt: Optional[date] = Field( - alias="period_of_report_date.lt", description="The period of report date less than the given date.", ) period_of_report_date_lte: Optional[date] = Field( - alias="period_of_report_date.lte", description="The period of report date less than or equal to the given date.", ) period_of_report_date_gt: Optional[date] = Field( - alias="period_of_report_date.gt", description="The period of report date greater than the given date.", ) period_of_report_date_gte: Optional[date] = Field( - alias="period_of_report_date.gte", description="The period of report date greater than or equal to the given date.", ) - timeframe: Optional[Literal["annual", "quarterly", "ttm"]] = Field( - alias="period", description="The timeframe of the financial statement." - ) include_sources: Optional[bool] = Field( description="Whether to include the sources of the financial statement." ) order: Optional[Literal["asc", "desc"]] = Field( description="The order of the financial statement." ) - limit: Optional[PositiveInt] = Field( - default=100, description="The limit of the financial statement." - ) sort: Optional[Literal["filing_date", "period_of_report_date"]] = Field( description="The sort of the financial statement." ) diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py index f15d9b90034..2d741b55fb7 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py @@ -1603,8 +1603,8 @@ class CLASS_stocks_fa(Container): @validate_arguments def income( self, - symbol: Optional[str] = None, - period: Literal["annual", "quarter"] = "annual", + symbol: str, + period: Literal["annually", "quarterly"] = "annually", chart: bool = False, provider: Optional[Literal["fmp", "polygon"]] = None, **kwargs @@ -1619,10 +1619,10 @@ class CLASS_stocks_fa(Container): ---------- provider: Literal[fmp, polygon] The provider to use for the query. - symbol : Optional[str] - None - period : Literal['annual', 'quarter'] - None + symbol : ConstrainedStrValue + Symbol to get data for. + period : Literal['annually', 'quarterly'] + Period of the data to return (quarterly or annually). Returns ------- @@ -1642,15 +1642,59 @@ class CLASS_stocks_fa(Container): IncomeStatement --------------- date : date - None + Date of the income statement. + currency : Optional[str] + Reporting currency. + filing_date : Optional[date] + Filling date. + accepted_date : Optional[date] + Accepted date. period : Optional[str] - None + Period of the income statement. revenue : Optional[int] - None + Revenue. + cost_of_revenue : Optional[int] + Cost of revenue. + gross_profit : Optional[int] + Gross profit. + research_and_development_expenses : Optional[int] + Research and development expenses. + general_and_administrative_expenses : Optional[int] + General and administrative expenses. + selling_and_marketing_expenses : Optional[float] + Selling and marketing expenses. + selling_general_and_administrative_expenses : Optional[int] + Selling, general and administrative expenses. + other_expenses : Optional[int] + Other expenses. + operating_expenses : Optional[int] + Operating expenses. + depreciation_and_amortization : Optional[int] + Depreciation and amortization. ebitda : Optional[int] - None + Earnings before interest, taxes, depreciation and amortization. + operating_income : Optional[int] + Operating income. + interest_income : Optional[int] + Interest income. + interest_expense : Optional[int] + Interest expense. + total_other_income_expenses_net : Optional[int] + Total other income expenses net. + income_before_tax : Optional[int] + Income before tax. + income_tax_expense : Optional[int] + Income tax expense. + net_income : Optional[int] + Net income. eps : Optional[float] - None + Earnings per share. + eps_diluted : Optional[float] + Earnings per share diluted. + weighted_average_shares_outstanding : Optional[int] + Weighted average shares outstanding. + weighted_average_shares_outstanding_dil : Optional[int] + Weighted average shares outstanding diluted. fmp === @@ -1658,75 +1702,31 @@ class CLASS_stocks_fa(Container): Parameters ---------- cik : Optional[str] - None + The CIK of the company if no symbol is provided. limit : Optional[NonNegativeInt] - None + The limit of the income statement. IncomeStatement --------------- symbol : str None - reportedCurrency : str - None cik : Optional[int] None - fillingDate : Optional[date] - None - acceptedDate : Optional[datetime] - None calendarYear : Optional[int] None - costOfRevenue : Optional[int] - None - grossProfit : Optional[int] - None grossProfitRatio : Optional[float] None - researchAndDevelopmentExpenses : Optional[int] - None - generalAndAdministrativeExpenses : Optional[int] - None - sellingAndMarketingExpenses : Optional[int] - None - sellingGeneralAndAdministrativeExpenses : Optional[int] - None - otherExpenses : Optional[int] - None - operatingExpenses : Optional[int] - None costAndExpenses : Optional[int] None - interestIncome : Optional[int] - None - interestExpense : Optional[int] - None - depreciationAndAmortization : Optional[int] - None ebitdaratio : Optional[float] None - operatingIncome : Optional[int] - None operatingIncomeRatio : Optional[float] None - totalOtherIncomeExpensesNet : Optional[int] - None - incomeBeforeTax : Optional[int] - None incomeBeforeTaxRatio : Optional[float] None - incomeTaxExpense : Optional[int] - None - netIncome : Optional[int] - None netIncomeRatio : Optional[float] None - epsdiluted : Optional[float] - None - weightedAverageShsOut : Optional[int] - None - weightedAverageShsOutDil : Optional[int] - None link : Optional[str] None finalLink : Optional[str] diff --git a/openbb_sdk/sdk/provider/openbb_provider/models/income_statement.py b/openbb_sdk/sdk/provider/openbb_provider/models/income_statement.py index 3ea229a635a..346eb464dd7 100644 --- a/openbb_sdk/sdk/provider/openbb_provider/models/income_statement.py +++ b/openbb_sdk/sdk/provider/openbb_provider/models/income_statement.py @@ -1,119 +1,74 @@ """Income Statement Data Model.""" -from datetime import date as dateType +from datetime import ( + date as dateType, + datetime, +) from typing import Optional +from pydantic import Field + from openbb_provider.abstract.data import Data from openbb_provider.models.base import FinancialStatementQueryParams class IncomeStatementQueryParams(FinancialStatementQueryParams): - """Income statement query. - - Parameter - --------- - symbol : str - The symbol of the company. - period : Literal["annually", "quarterly"] - The period of the income statement. - """ + """Income statement query.""" class IncomeStatementData(Data): - """Income Statement Data. + """Income Statement Data.""" - Returns - ------- - date : date - The date of the income statement. - symbol : str - The symbol of the company. - currency : Optional[str] - The currency of the income statement. - cik : Optional[int] - The Central Index Key (CIK) of the company. - filing_date : date - The filing date of the income statement. - accepted_date : Optional[date] - The accepted date of the income statement. - period : Optional[str] - The period of the income statement. - revenue : Optional[int] - The revenue of the income statement. - cost_of_revenue : Optional[int] - The cost of revenue of the income statement. - gross_profit : Optional[int] - The gross profit of the income statement. - research_and_development_expenses : Optional[int] - The research and development expenses of the income statement. - general_and_administrative_expenses : Optional[int] - The general and administrative expenses of the income statement. - selling_and_marketing_expenses : Optional[float] - The selling and marketing expenses of the income statement. - selling_general_and_administrative_expenses : Optional[int] - The selling, general and administrative expenses of the income statement. - other_expenses : Optional[int] - The other expenses of the income statement. - operating_expenses : Optional[int] - The operating expenses of the income statement. - depreciation_and_amortization : Optional[int] - The depreciation and amortization of the income statement. - ebitda : Optional[int] - The earnings before interest, taxes, depreciation and amortization of the income statement. - operating_income : Optional[int] - The operating income of the income statement. - interest_income : Optional[int] - The interest income of the income statement. - interest_expense : Optional[int] - The interest expense of the income statement. - total_other_income_expenses_net : Optional[int] - The total other income expenses net of the income statement. - income_before_tax : Optional[int] - The income before tax of the income statement. - income_tax_expense : Optional[int] - The income tax expense of the income statement. - net_income : Optional[int] - The net income of the income statement. - eps : Optional[float] - The earnings per share of the income statement. - eps_diluted : Optional[float] - The diluted earnings per share of the income statement. - weighted_average_shares_outstanding : Optional[int] - The weighted average shares outstanding of the income statement. - weighted_average_shares_outstanding_dil : Optional[int] - The weighted average shares outstanding diluted of the income statement. - """ + date: dateType = Field(description="Date of the income statement.") + symbol: str = Field(description="Symbol of the company.") + cik: Optional[int] = Field(description="Central Index Key.") + currency: Optional[str] = Field(description="Reporting currency.") + filing_date: Optional[dateType] = Field(description="Filling date.") + accepted_date: Optional[datetime] = Field(description="Accepted date.") + period: Optional[str] = Field(description="Period of the income statement.") - date: dateType - currency: Optional[str] = None - filing_date: Optional[dateType] = None - accepted_date: Optional[dateType] = None - period: Optional[str] + revenue: Optional[int] = Field(description="Revenue.") + cost_of_revenue: Optional[int] = Field(description="Cost of revenue.") + gross_profit: Optional[int] = Field(description="Gross profit.") - revenue: Optional[int] - cost_of_revenue: Optional[int] - gross_profit: Optional[int] + research_and_development_expenses: Optional[int] = Field( + description="Research and development expenses." + ) + general_and_administrative_expenses: Optional[int] = Field( + description="General and administrative expenses." + ) + selling_and_marketing_expenses: Optional[float] = Field( + description="Selling and marketing expenses." + ) + selling_general_and_administrative_expenses: Optional[int] = Field( + description="Selling, general and administrative expenses." + ) + other_expenses: Optional[int] = Field(description="Other expenses.") + operating_expenses: Optional[int] = Field(description="Operating expenses.") - research_and_development_expenses: Optional[int] = None - general_and_administrative_expenses: Optional[int] = None - selling_and_marketing_expenses: Optional[float] = None - selling_general_and_administrative_expenses: Optional[int] = None - other_expenses: Optional[int] = None - operating_expenses: Optional[int] + depreciation_and_amortization: Optional[int] = Field( + description="Depreciation and amortization." + ) + ebitda: Optional[int] = Field( + description="Earnings before interest, taxes, depreciation and amortization." + ) + operating_income: Optional[int] = Field(description="Operating income.") - depreciation_and_amortization: Optional[int] = None - ebitda: Optional[int] = None - operating_income: Optional[int] = None + interest_income: Optional[int] = Field(description="Interest income.") + interest_expense: Optional[int] = Field(description="Interest expense.") + total_other_income_expenses_net: Optional[int] = Field( + description="Total other income expenses net." + ) + income_before_tax: Optional[int] = Field(description="Income before tax.") + income_tax_expense: Optional[int] = Field(description="Income tax expense.") - interest_income: Optional[int] = None - interest_expense: Optional[int] = None - total_other_income_expenses_net: Optional[int] = None - income_before_tax: Optional[int] - income_tax_expense: Optional[int] - - net_income: Optional[int] - eps: Optional[float] - eps_diluted: Optional[float] - weighted_average_shares_outstanding: Optional[int] = None - weighted_average_shares_outstanding_dil: Optional[int] = None + net_income: Optional[int] = Field(description="Net income.") + eps: Optional[float] = Field(description="Earnings per share.") + eps_diluted: Optional[float] = Field(description="Earnings per share diluted.") + weighted_average_shares_outstanding: Optional[int] = Field( + description="Weighted average shares outstanding." + ) + weighted_average_shares_outstanding_dil: Optional[int] = Field( + description="Weighted average shares outstanding diluted." + )