summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanglewood <85772166+deeleeramone@users.noreply.github.com>2024-01-20 16:26:16 -0800
committerDanglewood <85772166+deeleeramone@users.noreply.github.com>2024-01-20 16:26:16 -0800
commit60171359ba47f92b54366f6873d67e3cc2756c3d (patch)
tree781c203278cced1b80ceb2abde57044813e39aad
parentf965e5b23cd6055700c19bdc3a071fb2f7028514 (diff)
price target consensusfeature/add-yfinance-functions
-rw-r--r--openbb_platform/extensions/equity/integration/test_equity_api.py5
-rw-r--r--openbb_platform/extensions/equity/integration/test_equity_python.py5
-rw-r--r--openbb_platform/providers/yfinance/openbb_yfinance/__init__.py4
-rw-r--r--openbb_platform/providers/yfinance/openbb_yfinance/models/equity_quote.py8
-rw-r--r--openbb_platform/providers/yfinance/openbb_yfinance/models/price_target_consensus.py114
-rw-r--r--openbb_platform/providers/yfinance/tests/record/http/test_yfinance_fetchers/test_y_finance_price_target_consensus_fetcher.yaml108
-rw-r--r--openbb_platform/providers/yfinance/tests/test_yfinance_fetchers.py12
7 files changed, 250 insertions, 6 deletions
diff --git a/openbb_platform/extensions/equity/integration/test_equity_api.py b/openbb_platform/extensions/equity/integration/test_equity_api.py
index cef2762a0d7..595bb047616 100644
--- a/openbb_platform/extensions/equity/integration/test_equity_api.py
+++ b/openbb_platform/extensions/equity/integration/test_equity_api.py
@@ -640,7 +640,10 @@ def test_equity_estimates_price_target(params, headers):
@parametrize(
"params",
- [({"symbol": "AAPL"})],
+ [
+ ({"symbol": "AAPL", "provider": "fmp"}),
+ ({"symbol": "AAPL,AMZN,RELIANCE.NS", "provider": "yfinance"}),
+ ],
)
@pytest.mark.integration
def test_equity_estimates_consensus(params, headers):
diff --git a/openbb_platform/extensions/equity/integration/test_equity_python.py b/openbb_platform/extensions/equity/integration/test_equity_python.py
index dee4e7ffa69..68572f01fa8 100644
--- a/openbb_platform/extensions/equity/integration/test_equity_python.py
+++ b/openbb_platform/extensions/equity/integration/test_equity_python.py
@@ -598,7 +598,10 @@ def test_equity_estimates_price_target(params, obb):
@parametrize(
"params",
- [({"symbol": "AAPL"})],
+ [
+ ({"symbol": "AAPL", "provider": "fmp"}),
+ ({"symbol": "AAPL,AMZN,RELIANCE.NS", "provider": "yfinance"}),
+ ],
)
@pytest.mark.integration
def test_equity_estimates_consensus(params, obb):
diff --git a/openbb_platform/providers/yfinance/openbb_yfinance/__init__.py b/openbb_platform/providers/yfinance/openbb_yfinance/__init__.py
index 5c7853b1603..7a442117fe9 100644
--- a/openbb_platform/providers/yfinance/openbb_yfinance/__init__.py
+++ b/openbb_platform/providers/yfinance/openbb_yfinance/__init__.py
@@ -26,6 +26,9 @@ from openbb_yfinance.models.losers import YFLosersFetcher
from openbb_yfinance.models.market_indices import (
YFinanceMarketIndicesFetcher,
)
+from openbb_yfinance.models.price_target_consensus import (
+ YFinancePriceTargetConsensusFetcher,
+)
from openbb_yfinance.models.undervalued_growth_equities import (
YFUndervaluedGrowthEquitiesFetcher,
)
@@ -60,5 +63,6 @@ yfinance_provider = Provider(
"IncomeStatement": YFinanceIncomeStatementFetcher,
"IndexHistorical": YFinanceIndexHistoricalFetcher,
"MarketIndices": YFinanceMarketIndicesFetcher,
+ "PriceTargetConsensus": YFinancePriceTargetConsensusFetcher,
},
)
diff --git a/openbb_platform/providers/yfinance/openbb_yfinance/models/equity_quote.py b/openbb_platform/providers/yfinance/openbb_yfinance/models/equity_quote.py
index d9293520fe4..9632e24aea8 100644
--- a/openbb_platform/providers/yfinance/openbb_yfinance/models/equity_quote.py
+++ b/openbb_platform/providers/yfinance/openbb_yfinance/models/equity_quote.py
@@ -1,4 +1,4 @@
-"""YFinance Equity Quote fetcher"""
+"""YFinance Equity Quote Model"""
# pylint: disable=unused-argument
import asyncio
import warnings
@@ -16,11 +16,11 @@ _warn = warnings.warn
class YFinanceEquityQuoteQueryParams(EquityQuoteQueryParams):
- """YFinance Equity Profile query params."""
+ """YFinance Equity Quote query params."""
class YFinanceEquityQuoteData(EquityQuoteData):
- """YFinance Equity Profile Data."""
+ """YFinance Equity Quote Data."""
__alias_dict__ = {
"name": "longName",
@@ -62,7 +62,7 @@ class YFinanceEquityQuoteData(EquityQuoteData):
class YFinanceEquityQuoteFetcher(
Fetcher[YFinanceEquityQuoteQueryParams, List[YFinanceEquityQuoteData]]
):
- """YFinance Equity Profile fetcher."""
+ """YFinance Equity Quote fetcher."""
@staticmethod
def transform_query(params: Dict[str, Any]) -> YFinanceEquityQuoteQueryParams:
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]
diff --git a/openbb_platform/providers/yfinance/tests/record/http/test_yfinance_fetchers/test_y_finance_price_target_consensus_fetcher.yaml b/openbb_platform/providers/yfinance/tests/record/http/test_yfinance_fetchers/test_y_finance_price_target_consensus_fetcher.yaml
new file mode 100644
index 00000000000..86ba01594f2
--- /dev/null
+++ b/openbb_platform/providers/yfinance/tests/record/http/test_yfinance_fetchers/test_y_finance_price_target_consensus_fetcher.yaml
@@ -0,0 +1,108 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - '*/*'
+ Accept-Encoding:
+ - gzip, deflate, br
+ Connection:
+ - keep-alive
+ Cookie:
+ - MOCK_COOKIE
+ method: GET
+ uri: https://query2.finance.yahoo.com/v10/finance/quoteSummary/AAPL?corsDomain=finance.yahoo.com&crumb=MOCK_CRUMB&formatted=false&modules=financialData%2CquoteType%2CdefaultKeyStatistics%2CassetProfile%2CsummaryDetail&symbol=AAPL
+ response:
+ body:
+ string: !!binary |
+ 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
+ Al++/BuKRBv1sh4AAA==
+ headers:
+ Age:
+ - '1'
+ Connection:
+ - keep-alive
+ Expect-CT:
+ - max-age=31536000, report-uri="http://csp.yahoo.com/beacon/csp?src=yahoocom-expect-ct-report-only"
+ Referrer-Policy:
+ - no-referrer-when-downgrade
+ Strict-Transport-Security:
+ - max-age=31536000
+ X-Content-Type-Options:
+ - nosniff
+ X-XSS-Protection:
+ - 1; mode=block
+ cache-control:
+ - public, max-age=1, stale-while-revalidate=9
+ content-encoding:
+ - gzip
+ content-length:
+ - '3034'
+ content-type:
+ - application/json;charset=utf-8
+ date:
+ - Sun, 21 Jan 2024 00:25:54 GMT
+ server:
+ - ATS
+ vary:
+ - Origin,Accept-Encoding
+ x-envoy-decorator-operation:
+ - finance-company-fundamentals-api--mtls-production-gq1.finance-k8s.svc.yahoo.local:4080/*
+ x-envoy-upstream-service-time:
+ - '4'
+ status:
+ code: 200
+ message: OK
+version: 1
diff --git a/openbb_platform/providers/yfinance/tests/test_yfinance_fetchers.py b/openbb_platform/providers/yfinance/tests/test_yfinance_fetchers.py
index 80a809c99e1..0be7b538da6 100644
--- a/openbb_platform/providers/yfinance/tests/test_yfinance_fetchers.py
+++ b/openbb_platform/providers/yfinance/tests/test_yfinance_fetchers.py
@@ -26,6 +26,9 @@ from openbb_yfinance.models.losers import YFLosersFetcher
from openbb_yfinance.models.market_indices import (
YFinanceMarketIndicesFetcher,
)
+from openbb_yfinance.models.price_target_consensus import (
+ YFinancePriceTargetConsensusFetcher,
+)
from openbb_yfinance.models.undervalued_growth_equities import (
YFUndervaluedGrowthEquitiesFetcher,
)
@@ -273,3 +276,12 @@ def test_y_finance_equity_quote_fetcher(credentials=test_credentials):
fetcher = YFinanceEquityQuoteFetcher()
result = fetcher.test(params, credentials)
assert result is None
+
+
+@pytest.mark.record_http
+def test_y_finance_price_target_consensus_fetcher(credentials=test_credentials):
+ params = {"symbol": "AAPL"}
+
+ fetcher = YFinancePriceTargetConsensusFetcher()
+ result = fetcher.test(params, credentials)
+ assert result is None