diff options
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.py | 114 |
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] |