mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-03 16:02:04 +00:00
financial ratios
This commit is contained in:
@@ -328,18 +328,23 @@ def pta(
|
||||
return CommandOutput(results=Query(**locals()).execute())
|
||||
|
||||
|
||||
@router.command(model="FinancialRatios")
|
||||
def ratios(
|
||||
cc: CommandContext,
|
||||
provider_choices: ProviderChoices,
|
||||
standard_params: StandardParams,
|
||||
extra_params: ExtraParams,
|
||||
) -> CommandOutput[BaseModel]:
|
||||
"""Extensive set of ratios over time."""
|
||||
return CommandOutput(results=Query(**locals()).execute())
|
||||
|
||||
|
||||
@router.command
|
||||
def rating() -> CommandOutput[Empty]: # type: ignore
|
||||
"""Analyst prices and ratings over time of the company."""
|
||||
return CommandOutput(results=Empty())
|
||||
|
||||
|
||||
@router.command
|
||||
def ratios() -> CommandOutput[Empty]: # type: ignore
|
||||
"""Extensive set of ratios over time."""
|
||||
return CommandOutput(results=Empty())
|
||||
|
||||
|
||||
@router.command
|
||||
def revfc() -> CommandOutput[Empty]: # type: ignore
|
||||
"""Earning Estimate by Analysts - Revenue."""
|
||||
|
||||
@@ -16,6 +16,7 @@ from openbb_fmp.models.esg_risk_rating import FMPESGRiskRatingFetcher
|
||||
from openbb_fmp.models.esg_score import FMPESGScoreFetcher
|
||||
from openbb_fmp.models.esg_sector import FMPESGSectorFetcher
|
||||
from openbb_fmp.models.executive_compensation import FMPExecutiveCompensationFetcher
|
||||
from openbb_fmp.models.financial_ratios import FMPFinancialRatiosFetcher
|
||||
from openbb_fmp.models.forex_eod import FMPForexEODFetcher
|
||||
from openbb_fmp.models.forex_pairs import FMPForexPairsFetcher
|
||||
from openbb_fmp.models.global_news import FMPGlobalNewsFetcher
|
||||
@@ -101,5 +102,6 @@ fmp_provider = Provider(
|
||||
"MajorIndicesConstituents": FMPMajorIndicesConstituentsFetcher,
|
||||
"DividendCalendar": FMPDividendCalendarFetcher,
|
||||
"StockQuote": FMPStockQuoteFetcher,
|
||||
"FinancialRatios": FMPFinancialRatiosFetcher,
|
||||
},
|
||||
)
|
||||
|
||||
118
openbb_sdk/providers/fmp/openbb_fmp/models/financial_ratios.py
Normal file
118
openbb_sdk/providers/fmp/openbb_fmp/models/financial_ratios.py
Normal file
@@ -0,0 +1,118 @@
|
||||
"""FMP Income Statement Fetcher."""
|
||||
|
||||
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.base import FinancialStatementQueryParams
|
||||
from openbb_provider.standard_models.financial_ratios import FinancialRatiosData
|
||||
|
||||
from openbb_fmp.utils.helpers import get_data_many
|
||||
|
||||
PeriodType = Literal["annual", "quarter"]
|
||||
|
||||
|
||||
class FMPFinancialRatiosQueryParams(FinancialStatementQueryParams):
|
||||
"""FMP Financial Ratios QueryParams.
|
||||
|
||||
Source: https://financialmodelingprep.com/developer/docs/#Company-Financial-Ratios
|
||||
|
||||
Symbol must be provided.
|
||||
"""
|
||||
|
||||
|
||||
class FMPFinancialRatiosData(FinancialRatiosData):
|
||||
"""FMP Financial Ratios Data."""
|
||||
|
||||
class Config:
|
||||
fields = {
|
||||
"current_ratio": "currentRatio",
|
||||
"quick_ratio": "quickRatio",
|
||||
"cash_ratio": "cashRatio",
|
||||
"days_of_sales_outstanding": "daysOfSalesOutstanding",
|
||||
"days_of_inventory_outstanding": "daysOfInventoryOutstanding",
|
||||
"operating_cycle": "operatingCycle",
|
||||
"days_of_payables_outstanding": "daysOfPayablesOutstanding",
|
||||
"cash_conversion_cycle": "cashConversionCycle",
|
||||
"gross_profit_margin": "grossProfitMargin",
|
||||
"operating_profit_margin": "operatingProfitMargin",
|
||||
"pretax_profit_margin": "pretaxProfitMargin",
|
||||
"net_profit_margin": "netProfitMargin",
|
||||
"effective_tax_rate": "effectiveTaxRate",
|
||||
"return_on_assets": "returnOnAssets",
|
||||
"return_on_equity": "returnOnEquity",
|
||||
"return_on_capital_employed": "returnOnCapitalEmployed",
|
||||
"net_income_per_ebt": "netIncomePerEBT",
|
||||
"ebt_per_ebit": "ebtPerEbit",
|
||||
"ebit_per_revenue": "ebitPerRevenue",
|
||||
"debt_ratio": "debtRatio",
|
||||
"debt_equity_ratio": "debtEquityRatio",
|
||||
"long_term_debt_to_capitalization": "longTermDebtToCapitalization",
|
||||
"total_debt_to_capitalization": "totalDebtToCapitalization",
|
||||
"interest_coverage": "interestCoverage",
|
||||
"cash_flow_to_debt_ratio": "cashFlowToDebtRatio",
|
||||
"company_equity_multiplier": "companyEquityMultiplier",
|
||||
"receivables_turnover": "receivablesTurnover",
|
||||
"payables_turnover": "payablesTurnover",
|
||||
"inventory_turnover": "inventoryTurnover",
|
||||
"fixed_asset_turnover": "fixedAssetTurnover",
|
||||
"asset_turnover": "assetTurnover",
|
||||
"operating_cash_flow_per_share": "operatingCashFlowPerShare",
|
||||
"free_cash_flow_per_share": "freeCashFlowPerShare",
|
||||
"cash_per_share": "cashPerShare",
|
||||
"payout_ratio": "payoutRatio",
|
||||
"operating_cash_flow_sales_ratio": "operatingCashFlowSalesRatio",
|
||||
"free_cash_flow_operating_cash_flow_ratio": "freeCashFlowOperatingCashFlowRatio",
|
||||
"cash_flow_coverage_ratios": "cashFlowCoverageRatios",
|
||||
"short_term_coverage_ratios": "shortTermCoverageRatios",
|
||||
"capital_expenditure_coverage_ratio": "capitalExpenditureCoverageRatio",
|
||||
"dividend_paid_and_capex_coverage_ratio": "dividendPaidAndCapexCoverageRatio",
|
||||
"dividend_payout_ratio": "dividendPayoutRatio",
|
||||
"price_book_value_ratio": "priceBookValueRatio",
|
||||
"price_to_book_ratio": "priceToBookRatio",
|
||||
"price_to_sales_ratio": "priceToSalesRatio",
|
||||
"price_earnings_ratio": "priceEarningsRatio",
|
||||
"price_to_free_cash_flows_ratio": "priceToFreeCashFlowsRatio",
|
||||
"price_to_operating_cash_flows_ratio": "priceToOperatingCashFlowsRatio",
|
||||
"price_cash_flow_ratio": "priceCashFlowRatio",
|
||||
"price_earnings_to_growth_ratio": "priceEarningsToGrowthRatio",
|
||||
"price_sales_ratio": "priceSalesRatio",
|
||||
"dividend_yield": "dividendYield",
|
||||
"enterprise_value_multiple": "enterpriseValueMultiple",
|
||||
"price_fair_value": "priceFairValue",
|
||||
}
|
||||
|
||||
|
||||
class FMPFinancialRatiosFetcher(
|
||||
Fetcher[
|
||||
FMPFinancialRatiosQueryParams,
|
||||
List[FMPFinancialRatiosData],
|
||||
]
|
||||
):
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> FMPFinancialRatiosQueryParams:
|
||||
return FMPFinancialRatiosQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: FMPFinancialRatiosQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> List[FMPFinancialRatiosData]:
|
||||
api_key = credentials.get("fmp_api_key") if credentials else ""
|
||||
|
||||
query.period = "annual" if query.period == "annually" else "quarter"
|
||||
base_url = "https://financialmodelingprep.com/api/v3"
|
||||
|
||||
url = (
|
||||
f"{base_url}/ratios/{query.symbol}?"
|
||||
f"period={query.period}&limit={query.limit}&apikey={api_key}"
|
||||
)
|
||||
|
||||
return get_data_many(url, FMPFinancialRatiosData, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: List[FMPFinancialRatiosData],
|
||||
) -> List[FinancialRatiosData]:
|
||||
return [FinancialRatiosData.parse_obj(d.dict()) for d in data]
|
||||
@@ -1,6 +1,5 @@
|
||||
"""FMP Historical Dividends fetcher."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
@@ -8,7 +7,6 @@ from openbb_provider.standard_models.historical_dividends import (
|
||||
HistoricalDividendsData,
|
||||
HistoricalDividendsQueryParams,
|
||||
)
|
||||
from pydantic import validator
|
||||
|
||||
from openbb_fmp.utils.helpers import create_url, get_data_many
|
||||
|
||||
@@ -31,18 +29,6 @@ class FMPHistoricalDividendsData(HistoricalDividendsData):
|
||||
"declaration_date": "declarationDate",
|
||||
}
|
||||
|
||||
@validator("declarationDate", pre=True, check_fields=False)
|
||||
def declaration_date_validate(cls, v: str): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d") if v else None
|
||||
|
||||
@validator("recordDate", pre=True, check_fields=False)
|
||||
def record_date_validate(cls, v: str): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d") if v else None
|
||||
|
||||
@validator("paymentDate", pre=True, check_fields=False)
|
||||
def payment_date_validate(cls, v: str): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d") if v else None
|
||||
|
||||
|
||||
class FMPHistoricalDividendsFetcher(
|
||||
Fetcher[
|
||||
@@ -70,5 +56,5 @@ class FMPHistoricalDividendsFetcher(
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: List[FMPHistoricalDividendsData],
|
||||
) -> List[FMPHistoricalDividendsData]:
|
||||
return data
|
||||
) -> List[HistoricalDividendsData]:
|
||||
return [HistoricalDividendsData.parse_obj(d.dict()) for d in data]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""FMP Historical Employees fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
@@ -9,7 +8,6 @@ from openbb_provider.standard_models.historical_employees import (
|
||||
HistoricalEmployeesData,
|
||||
HistoricalEmployeesQueryParams,
|
||||
)
|
||||
from pydantic import validator
|
||||
|
||||
from openbb_fmp.utils.helpers import create_url, get_data_many
|
||||
|
||||
@@ -34,18 +32,6 @@ class FMPHistoricalEmployeesData(HistoricalEmployeesData):
|
||||
"employee_count": "employeeCount",
|
||||
}
|
||||
|
||||
@validator("acceptanceTime", pre=True, check_fields=False)
|
||||
def acceptance_time_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
@validator("periodOfReport", pre=True, check_fields=False)
|
||||
def period_of_report_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
@validator("filingDate", pre=True, check_fields=False)
|
||||
def filing_date_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
|
||||
class FMPHistoricalEmployeesFetcher(
|
||||
Fetcher[
|
||||
|
||||
@@ -50,5 +50,5 @@ class FMPStockPeersFetcher(
|
||||
return get_data_one(url, FMPStockPeersData, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: FMPStockPeersData) -> FMPStockPeersData:
|
||||
return data
|
||||
def transform_data(data: FMPStockPeersData) -> StockPeersData:
|
||||
return StockPeersData.parse_obj(data.dict())
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
"""Financial ratios data model."""
|
||||
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
|
||||
|
||||
class FinancialRatiosData(Data):
|
||||
symbol: str = Field(description="The symbol of the company.")
|
||||
date: str = Field(description="The date of the financial ratios.")
|
||||
period: str = Field(description="The period of the financial ratios.")
|
||||
current_ratio: Optional[float] = Field(description="The current ratio.")
|
||||
quick_ratio: Optional[float] = Field(description="The quick ratio.")
|
||||
cash_ratio: Optional[float] = Field(description="The cash ratio.")
|
||||
days_of_sales_outstanding: Optional[float] = Field(
|
||||
description="Days of sales outstanding."
|
||||
)
|
||||
days_of_inventory_outstanding: Optional[float] = Field(
|
||||
description="Days of inventory outstanding."
|
||||
)
|
||||
operating_cycle: Optional[float] = Field(description="Operating cycle.")
|
||||
days_of_payables_outstanding: Optional[float] = Field(
|
||||
description="Days of payables outstanding."
|
||||
)
|
||||
cash_conversion_cycle: Optional[float] = Field(description="Cash conversion cycle.")
|
||||
gross_profit_margin: Optional[float] = Field(description="Gross profit margin.")
|
||||
operating_profit_margin: Optional[float] = Field(
|
||||
description="Operating profit margin."
|
||||
)
|
||||
pretax_profit_margin: Optional[float] = Field(description="Pretax profit margin.")
|
||||
net_profit_margin: Optional[float] = Field(description="Net profit margin.")
|
||||
effective_tax_rate: Optional[float] = Field(description="Effective tax rate.")
|
||||
return_on_assets: Optional[float] = Field(description="Return on assets.")
|
||||
return_on_equity: Optional[float] = Field(description="Return on equity.")
|
||||
return_on_capital_employed: Optional[float] = Field(
|
||||
description="Return on capital employed."
|
||||
)
|
||||
net_income_per_ebt: Optional[float] = Field(description="Net income per EBT.")
|
||||
ebt_per_ebit: Optional[float] = Field(description="EBT per EBIT.")
|
||||
ebit_per_revenue: Optional[float] = Field(description="EBIT per revenue.")
|
||||
debt_ratio: Optional[float] = Field(description="Debt ratio.")
|
||||
debt_equity_ratio: Optional[float] = Field(description="Debt equity ratio.")
|
||||
long_term_debt_to_capitalization: Optional[float] = Field(
|
||||
description="Long term debt to capitalization."
|
||||
)
|
||||
total_debt_to_capitalization: Optional[float] = Field(
|
||||
description="Total debt to capitalization."
|
||||
)
|
||||
interest_coverage: Optional[float] = Field(description="Interest coverage.")
|
||||
cash_flow_to_debt_ratio: Optional[float] = Field(
|
||||
description="Cash flow to debt ratio."
|
||||
)
|
||||
company_equity_multiplier: Optional[float] = Field(
|
||||
description="Company equity multiplier."
|
||||
)
|
||||
receivables_turnover: Optional[float] = Field(description="Receivables turnover.")
|
||||
payables_turnover: Optional[float] = Field(description="Payables turnover.")
|
||||
inventory_turnover: Optional[float] = Field(description="Inventory turnover.")
|
||||
fixed_asset_turnover: Optional[float] = Field(description="Fixed asset turnover.")
|
||||
asset_turnover: Optional[float] = Field(description="Asset turnover.")
|
||||
operating_cash_flow_per_share: Optional[float] = Field(
|
||||
description="Operating cash flow per share."
|
||||
)
|
||||
free_cash_flow_per_share: Optional[float] = Field(
|
||||
description="Free cash flow per share."
|
||||
)
|
||||
cash_per_share: Optional[float] = Field(description="Cash per share.")
|
||||
payout_ratio: Optional[float] = Field(description="Payout ratio.")
|
||||
operating_cash_flow_sales_ratio: Optional[float] = Field(
|
||||
description="Operating cash flow sales ratio."
|
||||
)
|
||||
free_cash_flow_operating_cash_flow_ratio: Optional[float] = Field(
|
||||
description="Free cash flow operating cash flow ratio."
|
||||
)
|
||||
cash_flow_coverage_ratios: Optional[float] = Field(
|
||||
description="Cash flow coverage ratios."
|
||||
)
|
||||
short_term_coverage_ratios: Optional[float] = Field(
|
||||
description="Short term coverage ratios."
|
||||
)
|
||||
capital_expenditure_coverage_ratio: Optional[float] = Field(
|
||||
description="Capital expenditure coverage ratio."
|
||||
)
|
||||
dividend_paid_and_capex_coverage_ratio: Optional[float] = Field(
|
||||
description="Dividend paid and capex coverage ratio."
|
||||
)
|
||||
dividend_payout_ratio: Optional[float] = Field(description="Dividend payout ratio.")
|
||||
price_book_value_ratio: Optional[float] = Field(
|
||||
description="Price book value ratio."
|
||||
)
|
||||
price_to_book_ratio: Optional[float] = Field(description="Price to book ratio.")
|
||||
price_to_sales_ratio: Optional[float] = Field(description="Price to sales ratio.")
|
||||
price_earnings_ratio: Optional[float] = Field(description="Price earnings ratio.")
|
||||
price_to_free_cash_flows_ratio: Optional[float] = Field(
|
||||
description="Price to free cash flows ratio."
|
||||
)
|
||||
price_to_operating_cash_flows_ratio: Optional[float] = Field(
|
||||
description="Price to operating cash flows ratio."
|
||||
)
|
||||
price_cash_flow_ratio: Optional[float] = Field(description="Price cash flow ratio.")
|
||||
price_earnings_to_growth_ratio: Optional[float] = Field(
|
||||
description="Price earnings to growth ratio."
|
||||
)
|
||||
price_sales_ratio: Optional[float] = Field(description="Price sales ratio.")
|
||||
dividend_yield: Optional[float] = Field(description="Dividend yield.")
|
||||
enterprise_value_multiple: Optional[float] = Field(
|
||||
description="Enterprise value multiple."
|
||||
)
|
||||
price_fair_value: Optional[float] = Field(description="Price fair value.")
|
||||
@@ -4,7 +4,7 @@
|
||||
from datetime import date as dateType
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic import Field, validator
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
from openbb_provider.abstract.query_params import QueryParams
|
||||
@@ -25,11 +25,23 @@ class HistoricalDividendsData(Data):
|
||||
)
|
||||
dividend: float = Field(description="The dividend of the historical dividends.")
|
||||
record_date: Optional[dateType] = Field(
|
||||
description="The record date of the historical dividends."
|
||||
description="The record date of the historical dividends.", default=None
|
||||
)
|
||||
payment_date: Optional[dateType] = Field(
|
||||
description="The payment date of the historical dividends."
|
||||
description="The payment date of the historical dividends.", default=None
|
||||
)
|
||||
declaration_date: Optional[dateType] = Field(
|
||||
description="The declaration date of the historical dividends."
|
||||
description="The declaration date of the historical dividends.", default=None
|
||||
)
|
||||
|
||||
@validator("declaration_date", pre=True, check_fields=False)
|
||||
def declaration_date_validate(cls, v: str): # pylint: disable=E0213
|
||||
return dateType.fromisoformat(v) if v else None
|
||||
|
||||
@validator("record_date", pre=True, check_fields=False)
|
||||
def record_date_validate(cls, v: str): # pylint: disable=E0213
|
||||
return dateType.fromisoformat(v) if v else None
|
||||
|
||||
@validator("payment_date", pre=True, check_fields=False)
|
||||
def payment_date_validate(cls, v: str): # pylint: disable=E0213
|
||||
return dateType.fromisoformat(v) if v else None
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
from datetime import date, datetime
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic import Field, validator
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
from openbb_provider.abstract.query_params import QueryParams
|
||||
@@ -35,3 +35,15 @@ class HistoricalEmployeesData(Data, BaseSymbol):
|
||||
source: str = Field(
|
||||
description="The source URL which retrieves this data for the company."
|
||||
)
|
||||
|
||||
@validator("acceptance_time", pre=True, check_fields=False)
|
||||
def acceptance_time_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
@validator("period_of_report", pre=True, check_fields=False)
|
||||
def period_of_report_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
@validator("filing_date", pre=True, check_fields=False)
|
||||
def filing_date_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
Reference in New Issue
Block a user