mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-09-27 06:56:39 +03:00
style: normalise blank lines between definitions
- two between top-level definitions, one between methods, none doubled inside a body
This commit is contained in:
@@ -309,6 +309,7 @@ def select_deep_thinking_agent(provider, default=None) -> str:
|
|||||||
"""Select deep thinking llm engine using an interactive selection."""
|
"""Select deep thinking llm engine using an interactive selection."""
|
||||||
return _select_model(provider, "deep", default)
|
return _select_model(provider, "deep", default)
|
||||||
|
|
||||||
|
|
||||||
def _llm_provider_table() -> list[tuple[str, str, str | None]]:
|
def _llm_provider_table() -> list[tuple[str, str, str | None]]:
|
||||||
"""(display_name, provider_key, base_url) for every supported provider.
|
"""(display_name, provider_key, base_url) for every supported provider.
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,6 @@ def test_existing_key_file_is_tightened_before_writing(monkeypatch, prompts, tmp
|
|||||||
assert "OTHER=1" in env.read_text()
|
assert "OTHER=1" in env.read_text()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(os.name == "nt", reason="POSIX file modes")
|
@pytest.mark.skipif(os.name == "nt", reason="POSIX file modes")
|
||||||
def test_read_only_key_file_is_still_updated(monkeypatch, prompts, tmp_path):
|
def test_read_only_key_file_is_still_updated(monkeypatch, prompts, tmp_path):
|
||||||
env = tmp_path / ".env"
|
env = tmp_path / ".env"
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ def _bare_graph(tmpdir, *, enabled=True):
|
|||||||
return g
|
return g
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_disabled_is_a_noop():
|
def test_disabled_is_a_noop():
|
||||||
with tempfile.TemporaryDirectory() as tmp:
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ class TestCheckpointResume(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(result["count"], 11)
|
self.assertEqual(result["count"], 11)
|
||||||
|
|
||||||
|
|
||||||
def test_different_date_starts_fresh(self):
|
def test_different_date_starts_fresh(self):
|
||||||
"""A different date must NOT resume from an existing checkpoint."""
|
"""A different date must NOT resume from an existing checkpoint."""
|
||||||
global _should_crash
|
global _should_crash
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from tradingagents.llm_clients.factory import _coerce_max_retries, build_llm_kwa
|
|||||||
|
|
||||||
# --- coercion / validation -------------------------------------------------
|
# --- coercion / validation -------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
@pytest.mark.parametrize("value,expected", [(0, 0), (2, 2), (10, 10), ("6", 6)])
|
@pytest.mark.parametrize("value,expected", [(0, 0), (2, 2), (10, 10), ("6", 6)])
|
||||||
def test_coerce_accepts_non_negative_ints_and_numeric_strings(value, expected):
|
def test_coerce_accepts_non_negative_ints_and_numeric_strings(value, expected):
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from tradingagents.llm_clients.factory import _coerce_max_tokens, build_llm_kwar
|
|||||||
|
|
||||||
# --- coercion / validation -------------------------------------------------
|
# --- coercion / validation -------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
@pytest.mark.parametrize("value,expected", [(1, 1), (8192, 8192), ("4096", 4096)])
|
@pytest.mark.parametrize("value,expected", [(1, 1), (8192, 8192), ("4096", 4096)])
|
||||||
def test_coerce_accepts_positive_ints_and_numeric_strings(value, expected):
|
def test_coerce_accepts_positive_ints_and_numeric_strings(value, expected):
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ def test_global_news_empty_after_filter_is_informative(monkeypatch):
|
|||||||
assert "unavailable" in out and "not an absence" in out
|
assert "unavailable" in out and "not an absence" in out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _ticker_with(articles, monkeypatch):
|
def _ticker_with(articles, monkeypatch):
|
||||||
class FakeTicker:
|
class FakeTicker:
|
||||||
def __init__(self, *a, **k):
|
def __init__(self, *a, **k):
|
||||||
@@ -162,7 +161,6 @@ def test_coverage_gap_boundaries(dates, expect_gap):
|
|||||||
assert "unavailable for 2026-05-01..2026-05-08" in out and "not an absence" in out
|
assert "unavailable for 2026-05-01..2026-05-08" in out and "not an absence" in out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_ticker_news_empty_feed_for_a_past_window_is_unavailable(monkeypatch):
|
def test_ticker_news_empty_feed_for_a_past_window_is_unavailable(monkeypatch):
|
||||||
_ticker_with([], monkeypatch)
|
_ticker_with([], monkeypatch)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ def _stamp(path, ts):
|
|||||||
|
|
||||||
# --- date normalization -----------------------------------------------------
|
# --- date normalization -----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_normalize_dates_strips_tz_and_normalizes_to_midnight():
|
def test_normalize_dates_strips_tz_and_normalizes_to_midnight():
|
||||||
aware = pd.Series(pd.to_datetime(
|
aware = pd.Series(pd.to_datetime(
|
||||||
|
|||||||
@@ -251,7 +251,6 @@ def test_posts_from_an_unrequested_or_unnamed_subreddit_are_not_dropped():
|
|||||||
assert "NO LABEL" in out
|
assert "NO LABEL" in out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_each_subreddit_keeps_its_own_quota():
|
def test_each_subreddit_keeps_its_own_quota():
|
||||||
busy = [{"title": f"A{i}", "created_utc": None, "selftext": "", "subreddit": "a"} for i in range(9)]
|
busy = [{"title": f"A{i}", "created_utc": None, "selftext": "", "subreddit": "a"} for i in range(9)]
|
||||||
|
|||||||
@@ -172,7 +172,6 @@ def test_reddit_live_empty_feed_is_a_real_absence(monkeypatch):
|
|||||||
assert "unavailable" not in out
|
assert "unavailable" not in out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_stocktwits_empty_stream_for_a_past_window_is_unavailable(monkeypatch):
|
def test_stocktwits_empty_stream_for_a_past_window_is_unavailable(monkeypatch):
|
||||||
monkeypatch.setattr(stocktwits, "urlopen", lambda *a, **k: _JsonResp({"messages": []}))
|
monkeypatch.setattr(stocktwits, "urlopen", lambda *a, **k: _JsonResp({"messages": []}))
|
||||||
@@ -180,7 +179,6 @@ def test_stocktwits_empty_stream_for_a_past_window_is_unavailable(monkeypatch):
|
|||||||
assert "unavailable" in out and "not an absence" in out
|
assert "unavailable" in out and "not an absence" in out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_reddit_window_straddling_the_lookback_is_unavailable(monkeypatch):
|
def test_reddit_window_straddling_the_lookback_is_unavailable(monkeypatch):
|
||||||
# Ten days ago through five days ago: the week-long search never reaches the
|
# Ten days ago through five days ago: the week-long search never reaches the
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ VENDOR_METHODS = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_category_for_method(method: str) -> str:
|
def get_category_for_method(method: str) -> str:
|
||||||
"""Get the category that contains the specified method."""
|
"""Get the category that contains the specified method."""
|
||||||
for category, info in TOOLS_CATEGORIES.items():
|
for category, info in TOOLS_CATEGORIES.items():
|
||||||
@@ -163,6 +164,7 @@ def get_category_for_method(method: str) -> str:
|
|||||||
return category
|
return category
|
||||||
raise ValueError(f"Method '{method}' not found in any category")
|
raise ValueError(f"Method '{method}' not found in any category")
|
||||||
|
|
||||||
|
|
||||||
def get_vendor(category: str, method: str = None) -> str:
|
def get_vendor(category: str, method: str = None) -> str:
|
||||||
"""Get the configured vendor for a data category or specific tool method.
|
"""Get the configured vendor for a data category or specific tool method.
|
||||||
Tool-level configuration takes precedence over category-level.
|
Tool-level configuration takes precedence over category-level.
|
||||||
@@ -178,6 +180,7 @@ def get_vendor(category: str, method: str = None) -> str:
|
|||||||
# Fall back to category-level configuration
|
# Fall back to category-level configuration
|
||||||
return config.get("data_vendors", {}).get(category, "default")
|
return config.get("data_vendors", {}).get(category, "default")
|
||||||
|
|
||||||
|
|
||||||
def route_to_vendor(method: str, *args, **kwargs):
|
def route_to_vendor(method: str, *args, **kwargs):
|
||||||
"""Route method calls to appropriate vendor implementation with fallback support."""
|
"""Route method calls to appropriate vendor implementation with fallback support."""
|
||||||
category = get_category_for_method(method)
|
category = get_category_for_method(method)
|
||||||
|
|||||||
+3
-1
@@ -34,6 +34,7 @@ def get_api_key() -> str:
|
|||||||
)
|
)
|
||||||
return api_key
|
return api_key
|
||||||
|
|
||||||
|
|
||||||
def format_datetime_for_api(date_input, end_of_day: bool = False) -> str:
|
def format_datetime_for_api(date_input, end_of_day: bool = False) -> str:
|
||||||
"""Convert various date formats to the YYYYMMDDTHHMM Alpha Vantage expects.
|
"""Convert various date formats to the YYYYMMDDTHHMM Alpha Vantage expects.
|
||||||
|
|
||||||
@@ -60,10 +61,12 @@ def format_datetime_for_api(date_input, end_of_day: bool = False) -> str:
|
|||||||
else:
|
else:
|
||||||
raise ValueError(f"Date must be string or datetime object, got {type(date_input)}")
|
raise ValueError(f"Date must be string or datetime object, got {type(date_input)}")
|
||||||
|
|
||||||
|
|
||||||
class AlphaVantageRateLimitError(VendorRateLimitError):
|
class AlphaVantageRateLimitError(VendorRateLimitError):
|
||||||
"""Raised when the Alpha Vantage API rate limit is exceeded."""
|
"""Raised when the Alpha Vantage API rate limit is exceeded."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _make_api_request(function_name: str, params: dict) -> dict | str:
|
def _make_api_request(function_name: str, params: dict) -> dict | str:
|
||||||
"""Helper function to make API requests and handle responses.
|
"""Helper function to make API requests and handle responses.
|
||||||
|
|
||||||
@@ -119,7 +122,6 @@ def _make_api_request(function_name: str, params: dict) -> dict | str:
|
|||||||
return response_text
|
return response_text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _filter_csv_by_date_range(csv_data: str, start_date: str, end_date: str) -> str:
|
def _filter_csv_by_date_range(csv_data: str, start_date: str, end_date: str) -> str:
|
||||||
"""
|
"""
|
||||||
Filter CSV data to include only rows within the specified date range.
|
Filter CSV data to include only rows within the specified date range.
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ def get_news(ticker, start_date, end_date) -> dict[str, str] | str:
|
|||||||
|
|
||||||
return _make_api_request("NEWS_SENTIMENT", params)
|
return _make_api_request("NEWS_SENTIMENT", params)
|
||||||
|
|
||||||
|
|
||||||
def get_global_news(curr_date, look_back_days: int | None = None, limit: int | None = None) -> dict[str, str] | str:
|
def get_global_news(curr_date, look_back_days: int | None = None, limit: int | None = None) -> dict[str, str] | str:
|
||||||
"""Returns global market news & sentiment data without ticker-specific filtering.
|
"""Returns global market news & sentiment data without ticker-specific filtering.
|
||||||
|
|
||||||
|
|||||||
+1
@@ -64,6 +64,7 @@ def _coverage_dates(posts) -> list:
|
|||||||
dates.append(datetime.now(timezone.utc) - _SEARCH_LOOKBACK)
|
dates.append(datetime.now(timezone.utc) - _SEARCH_LOOKBACK)
|
||||||
return dates
|
return dates
|
||||||
|
|
||||||
|
|
||||||
_RSS = "https://www.reddit.com/r/{sub}/search.rss?{qs}"
|
_RSS = "https://www.reddit.com/r/{sub}/search.rss?{qs}"
|
||||||
# A descriptive, identified User-Agent (per Reddit's API etiquette). Reddit
|
# A descriptive, identified User-Agent (per Reddit's API etiquette). Reddit
|
||||||
# blocks generic/anonymous tokens like bare "Mozilla/5.0" or "curl/…" but
|
# blocks generic/anonymous tokens like bare "Mozilla/5.0" or "curl/…" but
|
||||||
|
|||||||
+1
-1
@@ -69,6 +69,7 @@ def get_YFin_data_online(
|
|||||||
|
|
||||||
return header + csv_string
|
return header + csv_string
|
||||||
|
|
||||||
|
|
||||||
def get_stock_stats_indicators_window(
|
def get_stock_stats_indicators_window(
|
||||||
symbol: Annotated[str, "ticker symbol of the company"],
|
symbol: Annotated[str, "ticker symbol of the company"],
|
||||||
indicator: Annotated[str, "technical indicator to get the analysis and report of"],
|
indicator: Annotated[str, "technical indicator to get the analysis and report of"],
|
||||||
@@ -269,7 +270,6 @@ def get_stockstats_indicator(
|
|||||||
return str(indicator_value)
|
return str(indicator_value)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_closes(symbol: str, start_date: str, end_date: str) -> pd.Series:
|
def get_closes(symbol: str, start_date: str, end_date: str) -> pd.Series:
|
||||||
"""Daily closes from ``start_date`` up to, not including, ``end_date``."""
|
"""Daily closes from ``start_date`` up to, not including, ``end_date``."""
|
||||||
canonical = normalize_symbol(symbol)
|
canonical = normalize_symbol(symbol)
|
||||||
|
|||||||
Reference in New Issue
Block a user