summaryrefslogtreecommitdiffstats
path: root/openbb_platform/providers/yfinance/openbb_yfinance/models/price_target_consensus.py
diff options
context:
space:
mode:
Diffstat (limited to 'openbb_platform/providers/yfinance/openbb_yfinance/models/price_target_consensus.py')
-rw-r--r--openbb_platform/providers/yfinance/openbb_yfinance/models/price_target_consensus.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/openbb_platform/providers/yfinance/openbb_yfinance/models/price_target_consensus.py b/openbb_platform/providers/yfinance/openbb_yfinance/models/price_target_consensus.py
new file mode 100644
index 00000000000..5f065c56f62
--- /dev/null
+++ b/openbb_platform/providers/yfinance/openbb_yfinance/models/price_target_consensus.py
@@ -0,0 +1,114 @@
+"""YFinance Price Target Consensus Model"""
+# pylint: disable=unused-argument
+import asyncio
+import warnings
+from typing import Any, Dict, List, Optional
+
+from openbb_core.provider.abstract.fetcher import Fetcher
+from openbb_core.provider.standard_models.price_target_consensus import (
+ PriceTargetConsensusData,
+ PriceTargetConsensusQueryParams,
+)
+from pydantic import Field
+from yfinance import Ticker
+
+_warn = warnings.warn
+
+
+class YFinancePriceTargetConsensusQueryParams(PriceTargetConsensusQueryParams):
+ """YFinance Price Target Consensus query params."""
+
+
+class YFinancePriceTargetConsensusData(PriceTargetConsensusData):
+ """YFinance Price Target Consensus Data."""
+
+ __alias_dict__ = {
+ "target_high": "targetHighPrice",
+ "target_low": "targetLowPrice",
+ "target_consensus": "targetMeanPrice",
+ "target_median": "targetMedianPrice",
+ "recommendation": "recommendationKey",
+ "recommendation_mean": "recommendationMean",
+ "number_of_analysts": "numberOfAnalystOpinions",
+ "current_price": "currentPrice",
+ }
+
+ recommendation: Optional[str] = Field(
+ default=None,
+ description="Recommendation - buy, sell, etc.",
+ )
+ recommendation_mean: Optional[float] = Field(
+ default=None,
+ description="Mean recommendation score where 1 is strong buy and 5 is strong sell.",
+ )
+ current_price: Optional[float] = Field(
+ default=None,
+ description="Current price of the stock.",
+ )
+
+
+class YFinancePriceTargetConsensusFetcher(
+ Fetcher[
+ YFinancePriceTargetConsensusQueryParams, List[YFinancePriceTargetConsensusData]
+ ]
+):
+ """YFinance Price Target Consensus fetcher."""
+
+ @staticmethod
+ def transform_query(
+ params: Dict[str, Any]
+ ) -> YFinancePriceTargetConsensusQueryParams:
+ """Transform the query."""
+ return YFinancePriceTargetConsensusQueryParams(**params)
+
+ @staticmethod
+ async def aextract_data(
+ query: YFinancePriceTargetConsensusQueryParams,
+ credentials: Optional[Dict[str, str]],
+ **kwargs: Any,
+ ) -> List[Dict]:
+ """Extract the raw data from YFinance"""
+
+ symbols = query.symbol.split(",")
+ results = []
+ fields = [
+ "symbol",
+ "currentPrice",
+ "targetHighPrice",
+ "targetLowPrice",
+ "targetMeanPrice",
+ "targetMedianPrice",
+ "recommendationMean",
+ "recommendationKey",
+ "numberOfAnalystOpinions",
+ ]
+
+ async def get_one(symbol):
+ """Get the data for one ticker symbol."""
+ result = {}
+ ticker = {}
+ try:
+ ticker = Ticker(symbol).get_info()
+ except Exception as e:
+ _warn(f"Error getting data for {symbol}: {e}")
+ if ticker:
+ for field in fields:
+ if field in ticker:
+ result[field] = ticker.get(field, None)
+ if result:
+ results.append(result)
+
+ tasks = [get_one(symbol) for symbol in symbols]
+
+ await asyncio.gather(*tasks)
+
+ return results
+
+ @staticmethod
+ def transform_data(
+ query: YFinancePriceTargetConsensusQueryParams,
+ data: List[Dict],
+ **kwargs: Any,
+ ) -> List[YFinancePriceTargetConsensusData]:
+ """Transform the data."""
+ return [YFinancePriceTargetConsensusData.model_validate(d) for d in data]