feat: OpenBB Investment Analysis API
REST API wrapping OpenBB SDK for stock data, sentiment analysis, technical indicators, macro data, and rule-based portfolio analysis. - Stock data via yfinance (quote, profile, metrics, financials, historical, news) - News sentiment via Alpha Vantage (per-article, per-ticker scores) - Analyst data via Finnhub (recommendations, insider trades, upgrades) - Macro data via FRED (Fed rate, CPI, GDP, unemployment, treasury yields) - Technical indicators via openbb-technical (RSI, MACD, SMA, EMA, Bollinger) - Rule-based portfolio analysis engine (BUY_MORE/HOLD/SELL) - Stock discovery (gainers, losers, active, undervalued, growth) - 102 tests, all passing
This commit is contained in:
68
tests/test_mappers.py
Normal file
68
tests/test_mappers.py
Normal file
@@ -0,0 +1,68 @@
|
||||
from mappers import (
|
||||
discover_items_from_list,
|
||||
metrics_from_dict,
|
||||
profile_from_dict,
|
||||
quote_from_dict,
|
||||
)
|
||||
|
||||
|
||||
class TestQuoteFromDict:
|
||||
def test_basic(self):
|
||||
q = quote_from_dict("AAPL", {"name": "Apple", "last_price": 180.0})
|
||||
assert q.symbol == "AAPL"
|
||||
assert q.price == 180.0
|
||||
|
||||
def test_fallback_to_close(self):
|
||||
q = quote_from_dict("AAPL", {"close": 175.0})
|
||||
assert q.price == 175.0
|
||||
|
||||
def test_empty_dict(self):
|
||||
q = quote_from_dict("AAPL", {})
|
||||
assert q.price is None
|
||||
|
||||
|
||||
class TestProfileFromDict:
|
||||
def test_basic(self):
|
||||
p = profile_from_dict("AAPL", {"name": "Apple", "sector": "Tech"})
|
||||
assert p.sector == "Tech"
|
||||
|
||||
def test_description_fallback(self):
|
||||
p = profile_from_dict("AAPL", {"long_description": "A company"})
|
||||
assert p.description == "A company"
|
||||
|
||||
def test_employees_fallback(self):
|
||||
p = profile_from_dict("AAPL", {"full_time_employees": 150000})
|
||||
assert p.employees == 150000
|
||||
|
||||
|
||||
class TestMetricsFromDict:
|
||||
def test_basic(self):
|
||||
m = metrics_from_dict("AAPL", {"pe_ratio": 28.0, "roe": 0.15})
|
||||
assert m.pe_ratio == 28.0
|
||||
assert m.roe == 0.15
|
||||
|
||||
def test_roe_fallback(self):
|
||||
m = metrics_from_dict("AAPL", {"return_on_equity": 0.20})
|
||||
assert m.roe == 0.20
|
||||
|
||||
def test_eps_fallback(self):
|
||||
m = metrics_from_dict("AAPL", {"eps_ttm": 6.5})
|
||||
assert m.eps == 6.5
|
||||
|
||||
def test_empty_dict(self):
|
||||
m = metrics_from_dict("AAPL", {})
|
||||
assert m.pe_ratio is None
|
||||
|
||||
|
||||
class TestDiscoverItemsFromList:
|
||||
def test_basic(self):
|
||||
items = discover_items_from_list([
|
||||
{"symbol": "TSLA", "price": 250.0},
|
||||
{"symbol": "AAPL", "last_price": 180.0},
|
||||
])
|
||||
assert len(items) == 2
|
||||
assert items[0]["symbol"] == "TSLA"
|
||||
assert items[1]["price"] == 180.0
|
||||
|
||||
def test_empty_list(self):
|
||||
assert discover_items_from_list([]) == []
|
||||
Reference in New Issue
Block a user