Address Gemini round 4: register get_technicals, fix curr_date, clean up naming

HIGH: Add get_technicals to TOOLS_CATEGORIES (was unregistered)
HIGH: Use curr_date param in get_indicators for historical range calculation
HIGH: Remove misleading get_insider_transactions alias — keep separate:
  - get_insider_transactions: yfinance/AV (actual insider trades, Form 4)
  - get_sec_filings: Polaris (earnings filings, 8-K/10-Q/10-K)
MEDIUM: Simplify _extract_briefs helper
This commit is contained in:
John Weston 2026-03-23 18:16:21 -04:00
parent 7e3516e400
commit 435854e5a6
2 changed files with 25 additions and 13 deletions

View File

@ -30,7 +30,7 @@ from .polaris import (
get_balance_sheet as get_polaris_balance_sheet,
get_cashflow as get_polaris_cashflow,
get_income_statement as get_polaris_income_statement,
get_insider_transactions as get_polaris_insider_transactions,
get_sec_filings as get_polaris_sec_filings,
get_news as get_polaris_news,
get_global_news as get_polaris_global_news,
get_sentiment_score as get_polaris_sentiment_score,
@ -53,7 +53,8 @@ TOOLS_CATEGORIES = {
"technical_indicators": {
"description": "Technical analysis indicators",
"tools": [
"get_indicators"
"get_indicators",
"get_technicals"
]
},
"fundamental_data": {
@ -71,6 +72,7 @@ TOOLS_CATEGORIES = {
"get_news",
"get_global_news",
"get_insider_transactions",
"get_sec_filings",
]
},
"sentiment_analysis": {
@ -138,7 +140,9 @@ VENDOR_METHODS = {
"get_insider_transactions": {
"alpha_vantage": get_alpha_vantage_insider_transactions,
"yfinance": get_yfinance_insider_transactions,
"polaris": get_polaris_insider_transactions,
},
"get_sec_filings": {
"polaris": get_polaris_sec_filings,
},
# sentiment_analysis (Polaris-exclusive)
"get_sentiment_score": {

View File

@ -102,11 +102,9 @@ def _days_to_range(days: int) -> str:
def _extract_briefs(data) -> list:
"""Extract briefs list from API response (handles both dict and typed objects)."""
if hasattr(data, '__dict__') and not isinstance(data, dict):
data = data.__dict__ if hasattr(data, '__dict__') else {}
if isinstance(data, dict):
return data.get("briefs", [])
return getattr(data, 'briefs', [])
if not isinstance(data, dict):
data = vars(data) if hasattr(data, '__dict__') else {}
return data.get("briefs", [])
# ---------------------------------------------------------------------------
@ -170,7 +168,10 @@ def get_indicators(
curr_date: Annotated[str, "Current trading date, YYYY-mm-dd"],
look_back_days: Annotated[int, "how many days to look back"],
) -> str:
"""Fetch technical indicators from Polaris (20 indicators + signal summary)."""
"""Fetch technical indicators from Polaris (20 indicators + signal summary).
Uses curr_date and look_back_days to determine the data range.
"""
cache_key = f"indicators:{symbol}:{indicator}:{curr_date}:{look_back_days}"
cached = _cached(cache_key)
if cached:
@ -178,6 +179,10 @@ def get_indicators(
client = _get_client()
# Use curr_date to determine if we need historical vs current data
today = datetime.now().strftime("%Y-%m-%d")
is_historical = curr_date < today if curr_date else False
# Map common indicator names to Polaris types
indicator_map = {
"close_50_sma": "sma", "close_20_sma": "sma", "close_200_sma": "sma",
@ -192,7 +197,13 @@ def get_indicators(
}
polaris_type = indicator_map.get(indicator.lower(), indicator.lower())
range_param = _days_to_range(look_back_days)
# If historical, we need enough range to cover curr_date - look_back_days
if is_historical:
days_from_now = (datetime.strptime(today, "%Y-%m-%d") - datetime.strptime(curr_date, "%Y-%m-%d")).days
range_param = _days_to_range(days_from_now + look_back_days)
else:
range_param = _days_to_range(look_back_days)
known_types = {
"sma", "ema", "rsi", "macd", "bollinger", "atr",
@ -538,9 +549,6 @@ def get_sec_filings(
return result
# Keep old name as alias for backward compatibility
get_insider_transactions = get_sec_filings
# ---------------------------------------------------------------------------
# Polaris-Exclusive: Sentiment & Trading Signals