FEAT: EPS and Revenue Estimations from Seeking Alpha (#3402)

* FEAT: EPS and Revenue Estimations from Seeking Alpha

* initial pytest for seekingalpha model and view

* added fa_controller tests for seekingalpha views

* integration tests for epsfc and revfc

* FIX: handling of "no data found"

* merge

* number format fix

* format change according to black linter

* fixed unit tests because prev. recordings didn't match anymore

* change to match linter rules

* fixes

* delete website files"

* update codespell

* Flake

Co-authored-by: kajdo <juergen.kajdocsy@gmail.com>
Co-authored-by: James Maslek <jmaslek11@gmail.com>
Co-authored-by: Colin Delahunty <72827203+colin99d@users.noreply.github.com>
This commit is contained in:
kajdo
2022-12-12 23:55:20 +01:00
committed by GitHub
parent 0e79f3fbc8
commit fedeeaad18
24 changed files with 1372 additions and 8 deletions

View File

@@ -32,7 +32,7 @@ jobs:
- run: pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools types-six
- run: bandit -x ./tests -r . || true
- run: black --diff --check .
- run: codespell --ignore-words-list=commun,statics,ro,zar,zlot,jewl,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,vie,hel,ket,toke,certi,buidl,ot --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,./build/pyinstaller,./website/config.toml
- run: codespell --ignore-words-list=commun,statics,ro,zar,zlot,jewl,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,vie,hel,ket,toke,certi,buidl,ot,te --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,./build/pyinstaller,./website/config.toml
- run: flake8 . --count --ignore=E203,W503 --max-line-length=122 --show-source --statistics --exclude ./build/pyinstaller,./website/content
- run: mypy --ignore-missing-imports openbb_terminal
- run: shopt -s globstar && pyupgrade --py38-plus **/*.py

View File

@@ -25,7 +25,7 @@ repos:
entry: codespell
args:
[
"--ignore-words-list=commun,ro,zar,vie,hel,jewl,zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,statics,ket,toke,certi,buidl",
"--ignore-words-list=te,commun,ro,zar,vie,hel,jewl,zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,statics,ket,toke,certi,buidl",
"--quiet-level=2",
"--skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,build/pyinstaller/*,./website/config.toml",
]

View File

@@ -238,6 +238,8 @@
"metrics": ["FinancialModelingPrep"],
"ratios": ["FinancialModelingPrep"],
"growth": ["FinancialModelingPrep"],
"revfc": ["SeekingAlpha"],
"epsfc": ["SeekingAlpha"],
"warnings": ["MarketWatch"],
"dcf": ["StockAnalysis"],
"dcfc": ["FinancialModelingPrep"],

View File

@@ -354,6 +354,8 @@ en:
stocks/fa/metrics: key metrics over time
stocks/fa/ratios: in-depth ratios over time
stocks/fa/growth: growth of financial statement items and ratios
stocks/fa/epsfc: Earning Estimate by Analysts - EPS
stocks/fa/revfc: Earning Estimate by Analysts - Revenue
stocks/fa/dcfc: determine the (historical) discounted cash flow
stocks/res/_ticker: Ticker
stocks/res/macroaxis: www.macroaxis.com
@@ -497,10 +499,8 @@ en:
crypto/ov/categories: crypto categories
crypto/ov/hold: ethereum, bitcoin holdings overview statistics
crypto/ov/hm: crypto heatmap
crypto/ov/global: global crypto market info
crypto/ov/info: basic info about all coins available
crypto/ov/markets: market related info about all coins available
crypto/ov/exchanges: list all exchanges
crypto/ov/exmarkets: all available markets on given exchange
crypto/ov/platforms: list blockchain platforms eg. ethereum, solana, kusama, terra
crypto/ov/contracts: all smart contracts for given platform

View File

@@ -42,3 +42,6 @@ earnings --source YahooFinance
earnings --source AlphaVantage
fraud
dupont
epsfc
revfc
exit

View File

@@ -0,0 +1,5 @@
stocks
load aapl
fa
epsfc
exit

View File

@@ -0,0 +1,5 @@
stocks
load aapl
fa
revfc
exit

View File

@@ -1,6 +1,5 @@
"""Fundamental Analysis Controller."""
__docformat__ = "numpy"
import argparse
import logging
from datetime import datetime, timedelta
@@ -32,6 +31,7 @@ from openbb_terminal.stocks.fundamental_analysis import (
polygon_view,
fmp_view,
eodhd_view,
seeking_alpha_view,
)
# pylint: disable=inconsistent-return-statements,C0302,R0904
@@ -53,6 +53,8 @@ class FundamentalAnalysisController(StockBaseController):
"metrics",
"ratios",
"growth",
"revfc",
"epsfc",
"warnings",
"data",
"income",
@@ -107,7 +109,6 @@ class FundamentalAnalysisController(StockBaseController):
if session and obbff.USE_PROMPT_TOOLKIT:
choices: dict = self.choices_default
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):
@@ -130,6 +131,8 @@ class FundamentalAnalysisController(StockBaseController):
mt.add_cmd("metrics")
mt.add_cmd("ratios")
mt.add_cmd("growth")
mt.add_cmd("revfc")
mt.add_cmd("epsfc")
mt.add_cmd("warnings")
mt.add_cmd("dcf")
mt.add_cmd("dcfc")
@@ -543,6 +546,34 @@ class FundamentalAnalysisController(StockBaseController):
self.ticker, start_date=ns_parser.start, export=ns_parser.export
)
@log_start_end(log=logger)
def call_epsfc(self, other_args: List[str]):
"""Process eps forecast command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="epsfc",
description="""Estimated EPS [Source: Seeking Alpha]""",
)
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
seeking_alpha_view.display_eps_estimates(self.ticker)
@log_start_end(log=logger)
def call_revfc(self, other_args: List[str]):
"""Process revenue forecast command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="revfc",
description="""Estimated revenue [Source: Seeking Alpha]""",
)
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
seeking_alpha_view.display_rev_estimates(self.ticker)
@log_start_end(log=logger)
def call_splits(self, other_args: List[str]):
"""Process splits command."""

View File

@@ -0,0 +1,334 @@
""" Seeking Alpha Model """
__docformat__ = "numpy"
import logging
import requests
import pandas as pd
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import lambda_long_number_format
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def get_estimates_eps(ticker: str) -> pd.DataFrame:
"""Takes the ticker, asks for seekingalphaID and gets eps estimates
Parameters
----------
ticker: str
ticker of company
Returns
-------
pd.DataFrame
eps estimates for the next 10yrs
"""
url = "https://seekingalpha.com/api/v3/symbol_data/estimates"
querystring = {
"estimates_data_items": "eps_normalized_actual,eps_normalized_consensus_low,eps_normalized_consensus_mean,"
"eps_normalized_consensus_high,eps_normalized_num_of_estimates",
"period_type": "annual",
"relative_periods": "-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11",
}
# add ticker_ids for the ticker
seek_id = get_seekingalpha_id(ticker)
querystring["ticker_ids"] = seek_id
payload = ""
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0",
"Accept": "*/*",
"Accept-Language": "de,en-US;q=0.7,en;q=0.3",
"Accept-Encoding": "gzip, deflate, br",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"Connection": "keep-alive",
}
# semi random user agent -- disabled and static user agent because it might be the reason for 403
# headers["User-Agent"] = get_user_agent()
response = requests.request(
"GET", url, data=payload, headers=headers, params=querystring
)
# init
output = pd.DataFrame(
columns=[
"fiscalyear",
"consensus_mean",
"change %",
"analysts",
"actual",
"consensus_low",
"consensus_high",
]
)
# if no estimations exist, response is empty "reviews" and "reviews"
# {"revisions":{},"estimates":{}}
try:
seek_object = response.json()["estimates"][str(seek_id)]
items = len(seek_object["eps_normalized_num_of_estimates"].keys())
for i in range(0, items - 3):
# python_dict
eps_estimates = {}
eps_estimates["fiscalyear"] = seek_object[
"eps_normalized_num_of_estimates"
][str(i)][0]["period"]["fiscalyear"]
eps_estimates["analysts"] = seek_object["eps_normalized_num_of_estimates"][
str(i)
][0]["dataitemvalue"]
try:
eps_estimates["actual"] = seek_object["eps_normalized_actual"][str(i)][
0
]["dataitemvalue"]
except Exception:
eps_estimates["actual"] = 0
eps_estimates["consensus_low"] = seek_object[
"eps_normalized_consensus_low"
][str(i)][0]["dataitemvalue"]
eps_estimates["consensus_high"] = seek_object[
"eps_normalized_consensus_high"
][str(i)][0]["dataitemvalue"]
eps_estimates["consensus_mean"] = seek_object[
"eps_normalized_consensus_mean"
][str(i)][0]["dataitemvalue"]
try:
this = float(eps_estimates["consensus_mean"])
try:
prev = float(
seek_object["eps_normalized_actual"][str(i - 1)][0][
"dataitemvalue"
]
)
except Exception:
prev = float(
seek_object["eps_normalized_consensus_mean"][str(i - 1)][0][
"dataitemvalue"
]
)
percent = ((this / prev) - 1) * 100
except Exception:
percent = 0
eps_estimates["change %"] = percent
# format correction (before return, so calculation still works)
eps_estimates["consensus_mean"] = lambda_long_number_format(
float(eps_estimates["consensus_mean"])
)
eps_estimates["consensus_low"] = lambda_long_number_format(
float(eps_estimates["consensus_low"])
)
eps_estimates["consensus_high"] = lambda_long_number_format(
float(eps_estimates["consensus_high"])
)
eps_estimates["actual"] = lambda_long_number_format(
float(eps_estimates["actual"])
)
# df append replacement
new_row = pd.DataFrame(eps_estimates, index=[0])
output = pd.concat([output, new_row])
except Exception:
return pd.DataFrame()
return output
@log_start_end(log=logger)
def get_estimates_rev(ticker: str) -> pd.DataFrame:
"""Takes the ticker, asks for seekingalphaID and gets rev estimates
Parameters
----------
ticker: str
ticker of company
Returns
-------
pd.DataFrame
rev estimates for the next 10yrs
"""
url = "https://seekingalpha.com/api/v3/symbol_data/estimates"
querystring = {
"estimates_data_items": "revenue_actual,revenue_consensus_low,revenue_consensus_mean,"
"revenue_consensus_high,revenue_num_of_estimates",
"period_type": "annual",
"relative_periods": "-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11",
}
# add ticker_ids for the ticker
seek_id = get_seekingalpha_id(ticker)
querystring["ticker_ids"] = seek_id
payload = ""
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0",
"Accept": "*/*",
"Accept-Language": "de,en-US;q=0.7,en;q=0.3",
"Accept-Encoding": "gzip, deflate, br",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"Connection": "keep-alive",
"TE": "trailers",
}
# semi random user agent -- disabled and static user agent because it might be the reason for 403
# headers["User-Agent"] = get_user_agent()
response = requests.request(
"GET", url, data=payload, headers=headers, params=querystring
)
# init
# pd.empty should deliver true if no data-rows are added
output = pd.DataFrame(
columns=[
"fiscalyear",
"consensus_mean",
"change %",
"analysts",
"actual",
"consensus_low",
"consensus_high",
]
)
# if no estimations exist, response is empty "reviews" and "reviews"
# {"revisions":{},"estimates":{}}
try:
seek_object = response.json()["estimates"][seek_id]
items = len(seek_object["revenue_num_of_estimates"].keys())
for i in range(0, items - 3):
# python_dict
revenue_estimates = {}
revenue_estimates["fiscalyear"] = seek_object["revenue_num_of_estimates"][
str(i)
][0]["period"]["fiscalyear"]
revenue_estimates["consensus_mean"] = seek_object["revenue_consensus_mean"][
str(i)
][0]["dataitemvalue"]
revenue_estimates["analysts"] = seek_object["revenue_num_of_estimates"][
str(i)
][0]["dataitemvalue"]
if i < 1:
revenue_estimates["actual"] = seek_object["revenue_actual"][str(i)][0][
"dataitemvalue"
]
else:
revenue_estimates["actual"] = 0
revenue_estimates["consensus_low"] = seek_object["revenue_consensus_low"][
str(i)
][0]["dataitemvalue"]
revenue_estimates["consensus_high"] = seek_object["revenue_consensus_high"][
str(i)
][0]["dataitemvalue"]
try:
this = float(revenue_estimates["consensus_mean"])
# if actual revenue is available, take it for the calc
try:
prev = float(
seek_object["revenue_actual"][str(i - 1)][0]["dataitemvalue"]
)
except Exception:
prev = float(
seek_object["revenue_consensus_mean"][str(i - 1)][0][
"dataitemvalue"
]
)
percent = ((this / prev) - 1) * 100
except Exception:
percent = float(0)
revenue_estimates["change %"] = percent
# format correction (before return, so calculation still works)
revenue_estimates["consensus_mean"] = lambda_long_number_format(
float(revenue_estimates["consensus_mean"])
)
revenue_estimates["consensus_low"] = lambda_long_number_format(
float(revenue_estimates["consensus_low"])
)
revenue_estimates["consensus_high"] = lambda_long_number_format(
float(revenue_estimates["consensus_high"])
)
revenue_estimates["actual"] = lambda_long_number_format(
float(revenue_estimates["actual"])
)
# df append replacement
new_row = pd.DataFrame(revenue_estimates, index=[0])
output = pd.concat([output, new_row])
except Exception:
return pd.DataFrame()
return output
@log_start_end(log=logger)
def get_seekingalpha_id(ticker: str) -> str:
"""Takes the ticker, asks for seekingalphaID and returns it
Parameters
----------
ticker: str
ticker of company
Returns
-------
str:
seekingalphaID - to be used for further API calls
"""
url = "https://seekingalpha.com/api/v3/searches"
querystring = {
"filter[type]": "symbols",
"filter[list]": "all",
"page[size]": "1",
}
querystring["filter[query]"] = ticker
payload = ""
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0",
"Accept": "*/*",
"Accept-Language": "de,en-US;q=0.7,en;q=0.3",
"Accept-Encoding": "gzip, deflate, br",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"Referer": "https://seekingalpha.com/",
"Connection": "keep-alive",
# "TE": "trailers",
}
response = requests.request(
"GET", url, data=payload, headers=headers, params=querystring
)
try:
seekingalphaID = str(response.json()["symbols"][0]["id"])
except Exception:
# for some reason no mapping possible
seekingalphaID = "0"
return seekingalphaID

View File

@@ -0,0 +1,61 @@
""" Seeking Alpha View """
__docformat__ = "numpy"
import logging
from openbb_terminal.decorators import log_start_end
from openbb_terminal.rich_config import console
from openbb_terminal.stocks.fundamental_analysis import seeking_alpha_model
from openbb_terminal.helper_funcs import (
print_rich_table,
)
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def display_eps_estimates(symbol: str):
"""Display eps Estimates
Parameters
----------
symbol: str
ticker of company
"""
eps_estimates = seeking_alpha_model.get_estimates_eps(symbol)
if not eps_estimates.empty:
print_rich_table(
eps_estimates,
headers=list(eps_estimates.columns),
show_index=False,
title=f"{symbol.upper()} EPS History and Estimations",
)
else:
console.print("No data found.")
return
@log_start_end(log=logger)
def display_rev_estimates(symbol: str):
"""Display rev Estimates
Parameters
----------
symbol: str
ticker of company
"""
rev_estimates = seeking_alpha_model.get_estimates_rev(symbol)
if not rev_estimates.empty:
print_rich_table(
rev_estimates,
headers=list(rev_estimates.columns),
show_index=False,
title=f"{symbol.upper()} Revenue History and Estimations",
)
else:
console.print("No data found.")
return

View File

@@ -1,7 +1,7 @@
global global crypto market info [CoinGecko, CoinPaprika]
global crypto/ov/global [CoinGecko, CoinPaprika]
defi global DeFi market info [CoinGecko]
stables stablecoins [CoinGecko]
exchanges list all exchanges [CoinGecko, CoinPaprika]
exchanges crypto/ov/exchanges [CoinGecko, CoinPaprika]
exrates coin exchange rates [CoinGecko]
indexes crypto indexes [CoinGecko]
derivatives crypto derivatives [CoinGecko]

View File

@@ -0,0 +1,185 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Referer:
- https://seekingalpha.com/
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
TE:
- trailers
method: GET
uri: https://seekingalpha.com/api/v3/searches?filter%5Btype%5D=symbols&filter%5Blist%5D=all&page%5Bsize%5D=1&filter%5Bquery%5D=JNJ
response:
body:
string: !!binary |
H4sIAAAAAAAAA6tWKq7MTcrPKVayiq5WykxRsjI0NDbVUcpLzE1VslLy8vNS0lEqzilNB3Ky8rKA
nOT8vJLUvBKQZH5GXnF+noKaApQFlE2tSM5IzEsH6fWLDHYFqS8tKkrNS64EioQGuwAFMovjC0sT
80riixJLUkEW1sbWAgDS1n6yhwAAAA==
headers:
Accept-Ranges:
- bytes
Age:
- '85'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=3600, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '136'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:12:41 GMT
ETag:
- W/"cc200d9e38b2d26b2fffbef87ce15226"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- 56yPeC8_nt_3HfZ8
X-Runtime:
- '0.006611'
X-Served-By:
- cache-bfi-krnt7300038-BFI, cache-vie6365-VIE
X-Timer:
- S1668366761.419626,VS0,VE1
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=9737974274275; expires=Sat, 13 Nov 2027 19:12:41 GMT; path=/;
- machine_cookie_ts=1668366761; expires=Sat, 13 Nov 2027 19:12:41 GMT; path=/;
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
method: GET
uri: https://seekingalpha.com/api/v3/symbol_data/estimates?estimates_data_items=eps_normalized_actual%2Ceps_normalized_consensus_low%2Ceps_normalized_consensus_mean%2Ceps_normalized_consensus_high%2Ceps_normalized_num_of_estimates&period_type=annual&relative_periods=-3%2C-2%2C-1%2C0%2C1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11&ticker_ids=1135
response:
body:
string: !!binary |
H4sIAAAAAAAAA+2a4W6bMBCA34XfwfLZYLCfg3/TFKHEWZEI6QLJ1FV5951Lu7WNkxrpVtUoUqUW
dCrcx3H3xfFjsrfHpm92XZ+Yx9Misf3QbOvBusMEQObut73vl91uv63b5rddL7vDdrnbLN+EqsR8
w8DNxq6G5mjX+C8SkwguRAqQcqhAmkwYmTHOecozw3mySDCsbga7PdbtwcUDc2fv7b7Zrd2Fx7+G
h3vb4HFSd92hbjFi0/Sruv15qPeD3ScmeznzYGs8xKsWiwQDbLeu96+jXs69jhuvgaH/7rlIQaQS
Ks7xNvFnvOd8vOd6fay71XOG3aFtT6fvi6T4WvmXgfljnCf/cnr+WCcfPH9l8sJkxdXnr6ievwrM
H+M8+avp+cvr+YuKa8MLA/pq/iCoAOArEfQCYJwHQDYdQHYdADaATy2APDB/jPPkn0/PXwTkD7kR
8noBYH3QdEAZCADjPADkdADwxQCIQAAY5wGAY2vqCOCXAXBIRVYBNwDvx8nZCMQOSVMBEAgA4zwA
IBjAOOVdinmF+Qk3J19NzKfxmF6sDicHqeAVL41EPs/z4XnWnsEpqeDwQDgY54HDJ8EZU1QODiqQ
B87F3oGmhHCwd2qD/vRORP4bHNBhcFzcORzQk+CMKQoHB5+/B86lyYrXQThQVjhW0dIEuqMzy0uV
Q9VYIVCtXJwHTrha4Ws1piie4GTncJyuvzXzFXq87fpDv2x3v5xAE2k5ZyXQNKVYxRyYLGgIBNaP
8NaPCK+fvx9NaNQcOJOahkCkcq6ZzmgARCrnWAIgaQhEqueaZUTvQKx6jmYnaEogUj/XTBGVwAz9
vGAqp6mOGfp5yRTNqzNHPy9xtJQ5jWRGouh3zY+7m6MTLp7fHB2Xj0ua/hupowMwmh4rYnV0YErR
lECkjo4lQDNGRLyOTgQgWkUviZrADBUdV9CJ+sMsFb2g+fwyU0WnkYtI/Hxr6+7m5zc/dwSI1tCB
5SAl0RpqrIrOWaFVTjSE4tV0IHKUWDUdv09SqiAy1XhVnWdZSTNWRbS6XpS6pPEuMUNjL5guJNX3
77OUdqU00LxDM/V2RbR54Uube70a3O5w3PXywU487za1883omtHUVFQ9ybtL7ZwNriIQWWxMDcm7
S80HR9FUTkzdyL9LzQeHqlUHbqT6jI14p9PpD2wJzVtKMwAA
headers:
Accept-Ranges:
- bytes
Age:
- '0'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=60, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '891'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:12:42 GMT
ETag:
- W/"fa3611a593042edf6a005a94c3df2e84"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, MISS
X-Cache-Hits:
- 0, 0
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- DHRGVFfYyLSA9Aph
X-Runtime:
- '0.563933'
X-Served-By:
- cache-bfi-krnt7300119-BFI, cache-vie6330-VIE
X-Timer:
- S1668366761.491722,VS0,VE793
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=5477104746998; expires=Sat, 13 Nov 2027 19:12:42 GMT; path=/;
- machine_cookie_ts=1668366762; expires=Sat, 13 Nov 2027 19:12:42 GMT; path=/;
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,185 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Referer:
- https://seekingalpha.com/
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
TE:
- trailers
method: GET
uri: https://seekingalpha.com/api/v3/searches?filter%5Btype%5D=symbols&filter%5Blist%5D=all&page%5Bsize%5D=1&filter%5Bquery%5D=JNJ
response:
body:
string: !!binary |
H4sIAAAAAAAAA6tWKq7MTcrPKVayiq5WykxRsjI0NDbVUcpLzE1VslLy8vNS0lEqzilNB3Ky8rKA
nOT8vJLUvBKQZH5GXnF+noKaApQFlE2tSM5IzEsH6fWLDHYFqS8tKkrNS64EioQGuwAFMovjC0sT
80riixJLUkEW1sbWAgDS1n6yhwAAAA==
headers:
Accept-Ranges:
- bytes
Age:
- '465'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=3600, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '136'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:19:01 GMT
ETag:
- W/"cc200d9e38b2d26b2fffbef87ce15226"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- 56yPeC8_nt_3HfZ8
X-Runtime:
- '0.006611'
X-Served-By:
- cache-bfi-krnt7300038-BFI, cache-vie6331-VIE
X-Timer:
- S1668367141.204535,VS0,VE1
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=9924157037916; expires=Sat, 13 Nov 2027 19:19:01 GMT; path=/;
- machine_cookie_ts=1668367141; expires=Sat, 13 Nov 2027 19:19:01 GMT; path=/;
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
method: GET
uri: https://seekingalpha.com/api/v3/symbol_data/estimates?estimates_data_items=eps_normalized_actual%2Ceps_normalized_consensus_low%2Ceps_normalized_consensus_mean%2Ceps_normalized_consensus_high%2Ceps_normalized_num_of_estimates&period_type=annual&relative_periods=-3%2C-2%2C-1%2C0%2C1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11&ticker_ids=1135
response:
body:
string: !!binary |
H4sIAAAAAAAAA+2a4W6bMBCA34XfwfLZYLCfg3/TFKHEWZEI6QLJ1FV5951Lu7WNkxrpVtUoUqUW
dCrcx3H3xfFjsrfHpm92XZ+Yx9Misf3QbOvBusMEQObut73vl91uv63b5rddL7vDdrnbLN+EqsR8
w8DNxq6G5mjX+C8SkwguRAqQcqhAmkwYmTHOecozw3mySDCsbga7PdbtwcUDc2fv7b7Zrd2Fx7+G
h3vb4HFSd92hbjFi0/Sruv15qPeD3ScmeznzYGs8xKsWiwQDbLeu96+jXs69jhuvgaH/7rlIQaQS
Ks7xNvFnvOd8vOd6fay71XOG3aFtT6fvi6T4WvmXgfljnCf/cnr+WCcfPH9l8sJkxdXnr6ievwrM
H+M8+avp+cvr+YuKa8MLA/pq/iCoAOArEfQCYJwHQDYdQHYdADaATy2APDB/jPPkn0/PXwTkD7kR
8noBYH3QdEAZCADjPADkdADwxQCIQAAY5wGAY2vqCOCXAXBIRVYBNwDvx8nZCMQOSVMBEAgA4zwA
IBjAOOVdinmF+Qk3J19NzKfxmF6sDicHqeAVL41EPs/z4XnWnsEpqeDwQDgY54HDJ8EZU1QODiqQ
B87F3oGmhHCwd2qD/vRORP4bHNBhcFzcORzQk+CMKQoHB5+/B86lyYrXQThQVjhW0dIEuqMzy0uV
Q9VYIVCtXJwHTrha4Ws1piie4GTncJyuvzXzFXq87fpDv2x3v5xAE2k5ZyXQNKVYxRyYLGgIBNaP
8NaPCK+fvx9NaNQcOJOahkCkcq6ZzmgARCrnWAIgaQhEqueaZUTvQKx6jmYnaEogUj/XTBGVwAz9
vGAqp6mOGfp5yRTNqzNHPy9xtJQ5jWRGouh3zY+7m6MTLp7fHB2Xj0ua/hupowMwmh4rYnV0YErR
lECkjo4lQDNGRLyOTgQgWkUviZrADBUdV9CJ+sMsFb2g+fwyU0WnkYtI/Hxr6+7m5zc/dwSI1tCB
5SAl0RpqrIrOWaFVTjSE4tV0IHKUWDUdv09SqiAy1XhVnWdZSTNWRbS6XpS6pPEuMUNjL5guJNX3
77OUdqU00LxDM/V2RbR54Uube70a3O5w3PXywU487za1883omtHUVFQ9ybtL7ZwNriIQWWxMDcm7
S80HR9FUTkzdyL9LzQeHqlUHbqT6jI14p9PpD2wJzVtKMwAA
headers:
Accept-Ranges:
- bytes
Age:
- '379'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=60, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '891'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:19:01 GMT
ETag:
- W/"fa3611a593042edf6a005a94c3df2e84"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- DHRGVFfYyLSA9Aph
X-Runtime:
- '0.563933'
X-Served-By:
- cache-bfi-krnt7300119-BFI, cache-vie6321-VIE
X-Timer:
- S1668367141.269184,VS0,VE1
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=1882774375016; expires=Sat, 13 Nov 2027 19:19:01 GMT; path=/;
- machine_cookie_ts=1668367141; expires=Sat, 13 Nov 2027 19:19:01 GMT; path=/;
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,89 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Referer:
- https://seekingalpha.com/
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
TE:
- trailers
method: GET
uri: https://seekingalpha.com/api/v3/searches?filter%5Btype%5D=symbols&filter%5Blist%5D=all&page%5Bsize%5D=1&filter%5Bquery%5D=JNJ
response:
body:
string: !!binary |
H4sIAAAAAAAAA6tWKq7MTcrPKVayiq5WykxRsjI0NDbVUcpLzE1VslLy8vNS0lEqzilNB3Ky8rKA
nOT8vJLUvBKQZH5GXnF+noKaApQFlE2tSM5IzEsH6fWLDHYFqS8tKkrNS64EioQGuwAFMovjC0sT
80riixJLUkEW1sbWAgDS1n6yhwAAAA==
headers:
Accept-Ranges:
- bytes
Age:
- '0'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=3600, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '136'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:11:16 GMT
ETag:
- W/"cc200d9e38b2d26b2fffbef87ce15226"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- 56yPeC8_nt_3HfZ8
X-Runtime:
- '0.006611'
X-Served-By:
- cache-bfi-krnt7300038-BFI, cache-vie6371-VIE
X-Timer:
- S1668366676.346920,VS0,VE228
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=2621104791757; expires=Sat, 13 Nov 2027 19:11:16 GMT; path=/;
- machine_cookie_ts=1668366676; expires=Sat, 13 Nov 2027 19:11:16 GMT; path=/;
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,189 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Referer:
- https://seekingalpha.com/
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
TE:
- trailers
User-Agent:
- Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0
method: GET
uri: https://seekingalpha.com/api/v3/searches?filter%5Btype%5D=symbols&filter%5Blist%5D=all&page%5Bsize%5D=1&filter%5Bquery%5D=JNJ
response:
body:
string: !!binary |
H4sIAAAAAAAAA6tWKq7MTcrPKVayiq5WykxRsjI0NDbVUcpLzE1VslLy8vNS0lEqzilNB3Ky8rKA
nOT8vJLUvBKQZH5GXnF+noKaApQFlE2tSM5IzEsH6fWLDHYFqS8tKkrNS64EioQGuwAFMovjC0sT
80riixJLUkEW1sbWAgDS1n6yhwAAAA==
headers:
Accept-Ranges:
- bytes
Age:
- '2042'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=3600, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '136'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:45:18 GMT
ETag:
- W/"cc200d9e38b2d26b2fffbef87ce15226"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- 56yPeC8_nt_3HfZ8
X-Runtime:
- '0.006611'
X-Served-By:
- cache-bfi-krnt7300038-BFI, cache-vie6328-VIE
X-Timer:
- S1668368719.580650,VS0,VE1
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=9030003503847; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
- machine_cookie_ts=1668368718; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
User-Agent:
- Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0
method: GET
uri: https://seekingalpha.com/api/v3/symbol_data/estimates?estimates_data_items=eps_normalized_actual%2Ceps_normalized_consensus_low%2Ceps_normalized_consensus_mean%2Ceps_normalized_consensus_high%2Ceps_normalized_num_of_estimates&period_type=annual&relative_periods=-3%2C-2%2C-1%2C0%2C1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11&ticker_ids=1135
response:
body:
string: !!binary |
H4sIAAAAAAAAA+2a4W6bMBCA34XfwfLZYLCfg3/TFKHEWZEI6QLJ1FV5951Lu7WNkxrpVtUoUqUW
dCrcx3H3xfFjsrfHpm92XZ+Yx9Misf3QbOvBusMEQObut73vl91uv63b5rddL7vDdrnbLN+EqsR8
w8DNxq6G5mjX+C8SkwguRAqQcqhAmkwYmTHOecozw3mySDCsbga7PdbtwcUDc2fv7b7Zrd2Fx7+G
h3vb4HFSd92hbjFi0/Sruv15qPeD3ScmeznzYGs8xKsWiwQDbLeu96+jXs69jhuvgaH/7rlIQaQS
Ks7xNvFnvOd8vOd6fay71XOG3aFtT6fvi6T4WvmXgfljnCf/cnr+WCcfPH9l8sJkxdXnr6ievwrM
H+M8+avp+cvr+YuKa8MLA/pq/iCoAOArEfQCYJwHQDYdQHYdADaATy2APDB/jPPkn0/PXwTkD7kR
8noBYH3QdEAZCADjPADkdADwxQCIQAAY5wGAY2vqCOCXAXBIRVYBNwDvx8nZCMQOSVMBEAgA4zwA
IBjAOOVdinmF+Qk3J19NzKfxmF6sDicHqeAVL41EPs/z4XnWnsEpqeDwQDgY54HDJ8EZU1QODiqQ
B87F3oGmhHCwd2qD/vRORP4bHNBhcFzcORzQk+CMKQoHB5+/B86lyYrXQThQVjhW0dIEuqMzy0uV
Q9VYIVCtXJwHTrha4Ws1piie4GTncJyuvzXzFXq87fpDv2x3v5xAE2k5ZyXQNKVYxRyYLGgIBNaP
8NaPCK+fvx9NaNQcOJOahkCkcq6ZzmgARCrnWAIgaQhEqueaZUTvQKx6jmYnaEogUj/XTBGVwAz9
vGAqp6mOGfp5yRTNqzNHPy9xtJQ5jWRGouh3zY+7m6MTLp7fHB2Xj0ua/hupowMwmh4rYnV0YErR
lECkjo4lQDNGRLyOTgQgWkUviZrADBUdV9CJ+sMsFb2g+fwyU0WnkYtI/Hxr6+7m5zc/dwSI1tCB
5SAl0RpqrIrOWaFVTjSE4tV0IHKUWDUdv09SqiAy1XhVnWdZSTNWRbS6XpS6pPEuMUNjL5guJNX3
77OUdqU00LxDM/V2RbR54Uube70a3O5w3PXywU487za1883omtHUVFQ9ybtL7ZwNriIQWWxMDcm7
S80HR9FUTkzdyL9LzQeHqlUHbqT6jI14p9PpD2wJzVtKMwAA
headers:
Accept-Ranges:
- bytes
Age:
- '1956'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=60, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '891'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:45:18 GMT
ETag:
- W/"fa3611a593042edf6a005a94c3df2e84"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- DHRGVFfYyLSA9Aph
X-Runtime:
- '0.563933'
X-Served-By:
- cache-bfi-krnt7300119-BFI, cache-vie6383-VIE
X-Timer:
- S1668368719.647015,VS0,VE1
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=2152441849684; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
- machine_cookie_ts=1668368718; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,192 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Referer:
- https://seekingalpha.com/
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
TE:
- trailers
User-Agent:
- Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0
method: GET
uri: https://seekingalpha.com/api/v3/searches?filter%5Btype%5D=symbols&filter%5Blist%5D=all&page%5Bsize%5D=1&filter%5Bquery%5D=JNJ
response:
body:
string: !!binary |
H4sIAAAAAAAAA6tWKq7MTcrPKVayiq5WykxRsjI0NDbVUcpLzE1VslLy8vNS0lEqzilNB3Ky8rKA
nOT8vJLUvBKQZH5GXnF+noKaApQFlE2tSM5IzEsH6fWLDHYFqS8tKkrNS64EioQGuwAFMovjC0sT
80riixJLUkEW1sbWAgDS1n6yhwAAAA==
headers:
Accept-Ranges:
- bytes
Age:
- '2042'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=3600, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '136'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:45:18 GMT
ETag:
- W/"cc200d9e38b2d26b2fffbef87ce15226"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- 56yPeC8_nt_3HfZ8
X-Runtime:
- '0.006611'
X-Served-By:
- cache-bfi-krnt7300038-BFI, cache-vie6369-VIE
X-Timer:
- S1668368719.768704,VS0,VE1
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=2620385759373; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
- machine_cookie_ts=1668368718; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Accept-Language:
- de,en-US;q=0.7,en;q=0.3
Connection:
- keep-alive
Sec-Fetch-Dest:
- empty
Sec-Fetch-Mode:
- cors
Sec-Fetch-Site:
- same-origin
TE:
- trailers
User-Agent:
- Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0
method: GET
uri: https://seekingalpha.com/api/v3/symbol_data/estimates?estimates_data_items=revenue_actual%2Crevenue_consensus_low%2Crevenue_consensus_mean%2Crevenue_consensus_high%2Crevenue_num_of_estimates&period_type=annual&relative_periods=-3%2C-2%2C-1%2C0%2C1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11&ticker_ids=1135
response:
body:
string: !!binary |
H4sIAAAAAAAAA+2abW/aMBCA/0s+k+rOL7Gd38G3aUIRmDUShA4CU1Xx33duoGuHWRPpNOGUCqmF
Hkruydn3JPZLtvWHeldvml1Wvhwnmd+19bpqfXibIUodflOMb/Z+1uzXs81y9iGmyMpvL5lfLv28
rQ9+Qd/NykyAEDliDjhFWSpRSvUAADmoEiCbZBRW1a1fH6rVPsTjQ/j0yW/rzSIcsfurfX7yNb3P
qqbZVyuKWNa7ebX6ua+2rd9mpTp/8uwrektHNZOMAnyzqLbvo86fvY/rjkGhf87Z5ChyiVMAOk16
deesu3OuFoeqmZ8ybPar1fH4fZKZ28rf9syf4iL52+H5U4F8cv2LUptSmX9e/4Lr+hc986e4SP7F
8PzVbeWve+ZPcZH89fD85b/zl1N0JZpSn8bStfGvuQqApoReEwDFRQCo4QAEDwDHBUD2BEBxEQBy
OAC8MQCiJwCKiwCgtjW0BcB1AIC5UFOEEvHvdnLRAi1XBWBPABQXAYC9AXRdPqSop5SfCH3yXcd8
bY/51eoIcpALmIItJfE59YdTr72AQ//mEQToCYfiInBgEJwuxSLAIQWKwLk6d5ApERySJ5o85aeV
wwUHXT84Ie4SDrpBcLoURYBD1z8C51pnoeMQHLTB0iSWWn6wtIvK4eos2FOtQlwETn+1omHVpShe
4ahLOOTpZyWfk7n7ZrffzVabX8GcmXwcNEoS9vDDNfJSVXNwEF6cKHqWkoiWkuhfSm93KTyWjoDa
CF4UiQq7c0IjL4lE1d0ZsIaXRKIO7zQ6UyjOiSJRmXdSWewmTa7ukajVO+mQeXSMUO8tnuZSPtsY
oedblIZXRMYo/FRL+nUOZqulWzf/x/rH4139w7oD91P5u/q/LdCAKWzBOqxEouqPoKQ63Rxz2U2i
7o8gJDDfBqUq/864QltHUwZXUaQq/9pSWbgwWXCRSFX+NQg0yElijPIvwOhCaMZ6GaP8y/PzWK5R
NU75L76Y/K991dzl/y7/8d1JXM/9lTUmTNB8LT1Z+RfSAi+KROXf0RoIWV6oCy7PS9X9jdaIoqAW
zUUiWfcHaYUwNEK4SKTq/vSIQClFY4SNxBjdH2k9WRutFBulMbq/QCes1Wi5KI3T/RXdalu0fJR6
7tP4v1t+qnkbNsPTXp9PNh5Gd+Vd7r138ux2XNUlUpqpotvzLilZoS3vspJIaaaK7tOLUQL9dZco
4xv2IpRQ0/YIztupW1qiPB6PvwFwj6HQVzQAAA==
headers:
Accept-Ranges:
- bytes
Age:
- '45'
Allow:
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
Cache-Control:
- max-age=60, public
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Length:
- '940'
Content-Security-Policy:
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
https://seekingalpha.com/report/csp'
Content-Type:
- application/json; charset=utf-8
Date:
- Sun, 13 Nov 2022 19:45:18 GMT
ETag:
- W/"cf0af100271bfcd8c54302c681602ea9"
Referrer-Policy:
- strict-origin-when-cross-origin
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Vary:
- User-Agent, Accept-Encoding
X-Cache:
- MISS, HIT
X-Cache-Hits:
- 0, 1
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Request-Id:
- WD7Kw0ltfAdqpIZG
X-Runtime:
- '0.625983'
X-Served-By:
- cache-bfi-kbfi7400089-BFI, cache-vie6380-VIE
X-Timer:
- S1668368719.841743,VS0,VE1
X-XSS-Protection:
- 1; mode=block
set-cookie:
- machine_cookie=5570966595206; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
- machine_cookie_ts=1668368718; expires=Sat, 13 Nov 2027 19:45:18 GMT; path=/;
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,9 @@
,fiscalyear,consensus_mean,change %,analysts,actual,consensus_low,consensus_high
0,2021,9.790,21.915940224159414,17.0,9.800,9.690,9.820
0,2022,10.045,2.4987755102040765,19.0,0,10.020,10.100
0,2023,10.367,3.2039208034341904,19.0,0,9.490,11.100
0,2024,10.797,4.14644569009841,12.0,0,9.940,11.200
0,2025,11.120,2.9957690227257583,6.0,0,10.130,11.660
0,2026,11.513,3.537140287769791,6.0,0,10.390,12.080
0,2027,10.810,-6.108832110258278,1.0,0,10.810,10.810
0,2028,11.370,5.180388529139668,1.0,0,11.370,11.370
1 fiscalyear consensus_mean change % analysts actual consensus_low consensus_high
2 0 2021 9.790 21.915940224159414 17.0 9.800 9.690 9.820
3 0 2022 10.045 2.4987755102040765 19.0 0 10.020 10.100
4 0 2023 10.367 3.2039208034341904 19.0 0 9.490 11.100
5 0 2024 10.797 4.14644569009841 12.0 0 9.940 11.200
6 0 2025 11.120 2.9957690227257583 6.0 0 10.130 11.660
7 0 2026 11.513 3.537140287769791 6.0 0 10.390 12.080
8 0 2027 10.810 -6.108832110258278 1.0 0 10.810 10.810
9 0 2028 11.370 5.180388529139668 1.0 0 11.370 11.370

View File

@@ -0,0 +1,9 @@
,fiscalyear,consensus_mean,change %,analysts,actual,consensus_low,consensus_high
0,2021,9.790,21.915940224159414,17.0,9.800,9.690,9.820
0,2022,10.045,2.4987755102040765,19.0,0,10.020,10.100
0,2023,10.367,3.2039208034341904,19.0,0,9.490,11.100
0,2024,10.797,4.14644569009841,12.0,0,9.940,11.200
0,2025,11.120,2.9957690227257583,6.0,0,10.130,11.660
0,2026,11.513,3.537140287769791,6.0,0,10.390,12.080
0,2027,10.810,-6.108832110258278,1.0,0,10.810,10.810
0,2028,11.370,5.180388529139668,1.0,0,11.370,11.370
1 fiscalyear consensus_mean change % analysts actual consensus_low consensus_high
2 0 2021 9.790 21.915940224159414 17.0 9.800 9.690 9.820
3 0 2022 10.045 2.4987755102040765 19.0 0 10.020 10.100
4 0 2023 10.367 3.2039208034341904 19.0 0 9.490 11.100
5 0 2024 10.797 4.14644569009841 12.0 0 9.940 11.200
6 0 2025 11.120 2.9957690227257583 6.0 0 10.130 11.660
7 0 2026 11.513 3.537140287769791 6.0 0 10.390 12.080
8 0 2027 10.810 -6.108832110258278 1.0 0 10.810 10.810
9 0 2028 11.370 5.180388529139668 1.0 0 11.370 11.370

View File

@@ -270,6 +270,18 @@ def test_call_func_expect_queue(expected_queue, queue, func):
[],
{"TSLA"},
),
(
"call_epsfc",
"seeking_alpha_view.display_eps_estimates",
[],
{"TSLA"},
),
(
"call_revfc",
"seeking_alpha_view.display_rev_estimates",
[],
{"TSLA"},
),
(
"call_cal",
"yahoo_finance_view.display_calendar_earnings",

View File

@@ -0,0 +1,32 @@
# IMPORTATION THIRDPARTY
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.stocks.fundamental_analysis import seeking_alpha_model
@pytest.fixture(scope="module")
# might not be necessary
def vcr_config():
return {
"filter_headers": [("User-Agent", None)],
}
@pytest.mark.vcr
def test_get_seekingalpha_id(recorder):
seeking_id = seeking_alpha_model.get_seekingalpha_id(ticker="JNJ")
recorder.capture(seeking_id)
@pytest.mark.vcr
def test_check_get_estimates_eps(recorder):
df = seeking_alpha_model.get_estimates_eps(ticker="JNJ")
recorder.capture(df)
@pytest.mark.vcr
def test_check_get_estimates_rev(recorder):
df = seeking_alpha_model.get_estimates_eps(ticker="JNJ")
recorder.capture(df)

View File

@@ -0,0 +1,18 @@
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.stocks.fundamental_analysis import seeking_alpha_view
@pytest.mark.vcr
# @pytest.mark.record_stdout # deactivated, because assertion doesn't make sense if data changes
def test_display_eps_estimation():
seeking_alpha_view.display_eps_estimates(symbol="JNJ")
@pytest.mark.vcr
def test_display_rev_estimation():
seeking_alpha_view.display_rev_estimates(symbol="JNJ")

View File

@@ -15,6 +15,8 @@ Ticker: TSLA
metrics key metrics over time [FinancialModelingPrep]
ratios in-depth ratios over time [FinancialModelingPrep]
growth growth of financial statement items and ratios [FinancialModelingPrep]
revfc Earning Estimate by Analysts - Revenue [SeekingAlpha]
epsfc Earning Estimate by Analysts - EPS [SeekingAlpha]
warnings company warnings according to Sean Seah book [MarketWatch]
dcf advanced Excel customizable discounted cash flow [StockAnalysis]
dcfc determine the (historical) discounted cash flow [FinancialModelingPrep]